FFmpeg を使用した VP9 によるライブ エンコード

エンコード パラメータ

VP9 には、ライブ エンコードを最適化するためのさまざまなパラメータが用意されています。これらの大まかな原則については、ビットレート モードをご覧ください。

FFmpeg VP9 エンコードの例

次の表に、VP9 エンコードの ffmpeg 呼び出しのサンプル パラメータを示します。

パラメータ 説明
-quality realtime ライブ配信や 5 以上の速度には、realtime が必要です。
-speed 6 ライブ / リアルタイム エンコードには速度 58 を使用してください。数値が小さいほど(5 または 6)、品質が高くなりますが、より多くの CPU 電力が必要になります。数値が大きいほど(7 または 8)、品質が低いものの、低レイテンシのユースケースや管理が容易(モバイルなど)低い CPU デバイスの場合には管理しやすくなります。
-tile-columns 4 タイリングは、動画を長方形の領域に分割します。これにより、エンコードとデコードにマルチスレッドを使用できます。タイルの数は常に 2 の累乗です。0 = 1 タイル、1 = 2、2 = 4、3 = 8、4 = 16、5 = 32。
-frame-parallel 1 並行的なデコード機能を有効にします。
-threads 8 使用するスレッドの最大数。
-static-thresh 0 モーション検知のしきい値。
-max-intra-rate 300 最大 i-Frame ビットレート(pct)
-deadline realtime -quality realtime の代替(旧バージョン)バージョン
-lag-in-frames 0 遅延するフレームの最大数
-qmin 4 -qmax 48 量子化ツールの最小値と最大値。これらの値は、あくまで推奨値です。この値を調整することで、圧縮効率は低下しますが、動画の品質が向上します。
-row-mt 1 行マルチスレッディングを有効にする。最大 2 倍のスレッドをタイル列として使用できます。0 = オフ、1 = オン。
-error-resilient 1 エラー レジリエンス機能を有効にする。

エンコード パラメータの選択

ここでは、ライブ アダプティブ ビットレート ストリーミング(ABR)に定数ビットレート(CBR)エンコードを使用します。各ターゲット レートは、パッケージャのマニフェストで明示的に設定されています。これにより、クライアントの料金をより明確に「切り替え」できます。ビットレートに柔軟性がある場合やエンコードをチャンク化する場合は、可変ビットレート(VBR)エンコードと CQ モードも使用できます。Q モードでは、ライブ動画に必要なリアルタイム エンコードが難しくなります。詳しくは、ビットレート モードをご覧ください。

VP9 の操作方法について詳しくは、VOD の設定に関する関連記事をご覧ください。ただし、CBR には注意が必要です。

ヒントとアドバイス

ライブ ストリーミングを使用する場合、すべてが最小リアルタイム エンコード速度の 1 倍に制限されることに注意してください(FFmpeg は進行するエンコード速度を報告します)。エンコード速度が 1 倍を下回ると、エンコード処理でライブ動画の入力に対応できなくなり、ユーザーはバッファリングを経験します。また、送信が中断されると、ライブ配信中にストリームが使用できなくなります(アーカイブは通常は使用可能です)。

エンコード パラメータの使用例

以下は、Linux を実行しているクアッドコア i5 3.6 Ghz デスクトップで、さまざまなフレームサイズに対して 25 fps の CPU 使用率を示しています。

ターゲット解決 FFmpeg VP9 パラメータ CPU / 速度(例)
3840x2160(2160p) -r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7,800k ~ 88% 0.39 倍
2560x1440(1440p) -r 30 -g 90 -s 2560x1440 -quality realtime -speed 5 -threads 16 -row-mt 1 -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 6000k ~ 86% 0.68 倍
1920x1080(1080p) -r 30 -g 90 -s 1920x1080 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 4,500k ~ 82% 1.04 倍
1280x720(720p) -r 30 -g 90 -s 1280x720 -quality realtime -speed 5 -threads 8 -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 3,000k ~ 78% 1.77 倍
854x480(480p) -r 30 -g 90 -s 854x480 -quality realtime -speed 6 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 1,800k ~ 64% 3.51 倍
640×360(360p) -r 30 -g 90 -s 640x360 -quality realtime -speed 7 -threads 4 -row-mt 1 -tile-columns 1 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 730k ~ 62% 5.27 倍
426×240(240p) -r 30 -g 90 -s 426x240 -quality realtime -speed 8 -threads 2 -row-mt 1 -tile-columns 0 -frame-parallel 0 -qmin 4 -qmax 48 -b:v 365k ~ 66% 8.27 倍

FFmpeg の例:

ffmpeg -stream_loop 100 -i /home/id3as/Videos/120s_tears_of_steel_1080p.webm \
  -r 30 -g 90 -s 3840x2160 -quality realtime -speed 5 -threads 16 -row-mt 1 \
  -tile-columns 3 -frame-parallel 1 -qmin 4 -qmax 48 -b:v 7800k -c:v vp9 \
  -b:a 128k -c:a libopus -f webm pipe1

ヒントとアドバイス

  • ここでは、FIMP パイプ(&pipe1")に出力しています。これは、FFmpeg コマンドを実行する前に実行する必要があります。これを行うには、作業ディレクトリで mkfifo pipe1 コマンドを指定します。Shaka Packager を使用すると、特定のストリームの入力ソースとしてそのパイプをリッスンします。他のパッケージ モデルでは、別の方法が必要になる場合があります。

  • -row-mt コマンドが認識されるようにするには、https://www.ffmpeg.org/download.html に掲載されている FFmpeg の最新の安定版リリース(現在は 3.3.3)を使用してください。

アダプティブ ビットレート セットの例

FFmpeg エンコードしたマシンの処理能力によっては、以下のエンコードをすべて同時に配信できる場合とできない場合があります。そのため、使用可能なリソースとターゲット ユーザーに適したサブセットをリストから選択する必要があります。

FFmpeg フル ABR セット

理想的なシナリオでは、前のセクションで説明したエンコードの例を組み合わせて、すべてを同時に生成する単一のコマンドを作成します。

ffmpeg -stream_loop 100 -i lakes1080p.mp4 \
  -y -r 25 -g 75 -s 3840x2160 -quality realtime -speed 5 -threads 8 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 7800k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe1 \
  -y -r 25 -g 75 -s 2560x1440 -quality realtime -speed 5 -threads 8 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 6000k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe2 \
  -y -r 25 -g 75 -s 1920x1080 -quality realtime -speed 5 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 4500k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe3 \
  -y -r 25 -g 75 -s 1280x720 -quality realtime -speed 5 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 3000k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe4 \
  -y -r 25 -g 75 -s 854x480 -quality realtime -speed 6 -threads 4 \
  -tile-columns 2 -frame-parallel 1 \
  -b:v 2000k -c:v vp9 -b:a 196k -c:a libopus -f webm pipe5 \
  -y -r 25 -g 75 -s 640x360 -quality realtime -speed 7 -threads 2 \
  -tile-columns 1 -frame-parallel 0 \
  -b:v 730k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe6 \
  -y -r 25 -g 75 -s 426x240 -quality realtime -speed 8 -threads 2 \
  -tile-columns 1 -frame-parallel 0 \
  -b:v 365k -c:v vp9 -b:a 64k -c:a libopus -f webm pipe7

ただし、上記のフルセットには、非常に強力な CPU か、場合によっては一部のチップセットが提供するハードウェア GPU オフロードによるサポートが必要となります。Intel Kabylake 以降には、完全なハードウェア エンコード パイプラインが用意されています。(Kabylake GPU は 8 ビットの VP9 エンコードを行うことができますが、10 ビットはエンコードできません)。

Shaka Packager を使用した実用的なデスクトップの例

一般的なデスクトップ マシンのより実用的な例として、Shaka Packager を使用できます。Shaka をセットアップする簡単な方法は、Google の DockerHub イメージを使用して Docker コンテナ内に Shaka をインストールすることです。手順については、次のリンク先をご覧ください。

https://github.com/google/shaka-packager#using-docker-for-testing--development

この例では、次の構成のマシンを使用しました。

システム ホスト: obs カーネル: 4.4.0-91-lowlatency x86_64(64 ビット)
パソコン Xfce 4.12.3 ディストリビューション: OS: https://ubuntustudio.org/2016/10/ubuntu-studio-16-10-released/
CPU クアッドコア Intel Core i5-6500(-MCP-)
キャッシュ: 6144 KB
クロック速度: 最大: 3,600 MHz 1: 800 MHz 2: 800 MHz 3: 800 MHz 4: 800 MHz
グラフィック カード Intel Skylake 統合グラフィックス
メモリ 8 GB RAM

このマシンでは実際に、使用可能な使用可能な ABR エンコードの範囲が生成され、FFmpeg は一貫して 1 倍のエンコード速度を報告します。

ffmpeg -stream_loop 100 -i 120s_tears_of_steel_1080p.webm \
  -y -r 30 -g 90 -s 1920x1080 -quality realtime -speed 7 -threads 8 \
  -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 4500k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe1 \
  -y -r 30 -g 90 -s 1280x720 -quality realtime -speed 8 -threads 6 \
  -row-mt 1 -tile-columns 2 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 3000k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe2 \
  -y -r 30 -g 90 -s 640x360 -quality realtime -speed 8 -threads 2 \
  -row-mt 1 -tile-columns 1 -frame-parallel 1 -qmin 4 -qmax 48 \
  -b:v 730k -c:v vp9 -b:a 128k -c:a libopus -f webm pipe3

-speed の設定は非常に高いことに注意してください。これらの設定は試験運用版で、マシンごとに異なるものです。

Shaka Packager のオーバーヘッド

パッケージ化は、特に CPU 使用率の高いアクティビティではありません。Shamp Packager では、FFmpeg によってサブセットのみが配信されている場合でも、すべての出力をリッスンするように設定できます。上記のマシンでテストされた Packager の設定は次のとおりです。

packager \
  in=pipe1,stream=audio,init_segment=livehd-audio-1080.webm,segment_template=livehd-audio-1080-\$Number\$.webm \
  in=pipe1,stream=video,init_segment=livehd-video-1080.webm,template=livehd-video-1080-\$Number\$.webm \
  in=pipe2,stream=audio,init_segment=livehd-audio-720.webm,segment_template=livehd-audio-720-\$Number\$.webm \
  in=pipe2,stream=video,init_segment=livehd-video-720.webm,template=livehd-video-720-\$Number\$.webm \
  in=pipe3,stream=audio,init_segment=livehd-audio-360.webm,segment_template=livehd-audio-360-\$Number\$.webm \
  in=pipe3,stream=video,init_segment=livehd-video-360.webm,template=livehd-video-360-\$Number\$.webm \
  --mpd_output livehd.mpd --dump_stream_info --min_buffer_time=10 --time_shift_buffer_depth=300 \
  --segment_duration=3 --io_block_size 65536