LensLink
言語JA

遅延とパフォーマンス

カメラからOBSまでの遅延は、USBなら1080pでも4Kでも約60 msです。Wi-Fiではこれより大きく、ばらつきもあります。この値は推定ではなく常に測定されており、ステータス欄、ステータスバー、ログに表示されます。

遅延の発生源#

段階目安備考
キャプチャと露出1フレーム明るいシーンほど露出が短く、その差がここに表れます。
ハードウェアエンコード数msVideoToolbox。調整する項目はありません。
接続USB:小さく安定。Wi-Fi:変動あり快適な環境とストレスの多い環境を分ける段階です。
デコード数msデフォルトはGPU。ソフトウェアへの切り替えは自動です。
シーンへの取り込みGPUパイプラインでは1ミリ秒未満それ以外の場合は、GPUメモリから一度コピーして戻す処理が入ります。

遅延を下げる#

  1. USBを使う。最も安定していて、Wi-Fiの混雑の影響を受けず、スマートフォンの充電もできます。
  2. シーンを明るくする。暗い部屋では露出時間が長くなり、それがそのまま遅延に加わります。
  3. デフォルト設定をオンのままにする。低遅延モードとハードウェアデコードは、どちらも最初から有効になっています。
  4. 必要以上に高く設定しない。シーン内で幅1000 pxほどのトーク映像なら、1080pは妥協ではありません。
  5. 強いデジタルズームより望遠レンズを使う。ズームしたノイズの多い映像は圧縮効率が悪く、ビットレートと遅延の急上昇として表れます。

混雑時はキューに溜めずに破棄します。接続が詰まると、LensLinkはバックログを溜め込まずにフレームを破棄し、一時的に画質を下げます。そのため、配信が進むにつれて遅延がじわじわ増えることはなく、一定に保たれます。

数値を確認する#

この値は実測値です。NTP方式のクロックオフセット交換が毎秒実行されており、これが自動リップシンクを可能にしている仕組みでもあります。

GPUデコードパイプライン(ベータ)#

通常、デコードした各フレームはGPUからシステムメモリにダウンロードされてOBSに渡され、合成のためにすぐにGPUへアップロードし直されます。4K60では毎秒約2 GBのピクセルが、意味もなく往復することになります。ベータのパイプラインは、フレームをテクスチャとしてOBSに渡し、この往復を省きます。

ツール → LensLink設定で切り替えます。OBSの再起動後に、すべてのソースが一斉に切り替わります。

測定結果#

12の構成で、それぞれ約25秒のライブ映像を、同じPCとスマートフォンを使ってWi-Fi経由で測定しました。GPUパイプラインでは、すべての実行でピクセルコピーが0.00 MB/sでした。

構成1フレームあたりのコスト(ms)ピクセルコピー(MB/s)OBSのCPU使用率
720p 60 HEVC0.81 → 0.09163 → 02.2% → 1.4%
1080p 60 H.2642.11 → 0.10370 → 02.3% → 1.6%
1080p 60 HEVC1.42 → 0.09373 → 02.6% → 1.4%
4K 30 HEVC4.96 → 0.14721 → 02.9% → 1.5%
4K 60 H.2647.54 → 0.101221 → 04.1% → 1.8%
4K 60 HEVC4.75 → 0.101439 → 04.1% → 1.6%

1フレームあたりのコストは89〜99%減少し、その効果は解像度が高いほど大きくなります。4K60 HEVCでは、通常のパイプラインがシステムメモリに約1.4 GB/sのデータを流していましたが、これが完全になくなり、OBSプロセスのCPU使用率はおよそ半分になりました。遅延とフレームレートには系統的な差は見られませんでした。これらはネットワークとスマートフォンのエンコーダーで決まり、描画経路には左右されないためです。

プラットフォームごとの注意#

WindowsOBS 32が対応するすべてのシステム(Windows 10 1909以降)で、共有D3D11テクスチャを使用します。
macOSOBS 32が対応するすべてのシステム(macOS 13以降)で、IOSurfaceを使用します。例外は10ビットのストリームで、VideoToolboxが自ら8ビットに変換するため、HDRとApple Logはこの経路ではなく通常の経路で描画されます。
LinuxOBSがEGLで動作していること(Waylandと現在のX11ビルドではデフォルト)と、VAAPIドライバーが必要です。IntelとAMD用はMesaに組み込まれており、NVIDIAではnvidia-vaapi-driverが必要です。
マルチGPUデコードと描画が別々のGPUで行われる場合はテクスチャを共有できず、ソースは自動的に通常の方式に戻ります。

通常の方式への切り替えはソースごとに自動で行われます。最悪の場合でも通常のパイプラインとまったく同じで、その理由がログに1行出力されます。

GPUのメーカーは関係ありますか?#

OSほどは関係ありません。デコードは最近のすべてのGPUに搭載された専用回路で行われ、プラグインはメーカー固有のものではなく、プラットフォーム自身のAPIを通じてそれを使います。

Windowsメーカーを問いません。現行のGPUならD3D11VA、フォールバックはDXVA2です。
macOSVideoToolbox。Appleシリコン搭載MacでもIntel搭載Macでも同じです。
Linux(IntelまたはAMD)VAAPIはすでにMesaに含まれているため、インストールは不要です。
Linux(NVIDIA)nvidia-vaapi-driverが必要で、フォールバックはVDPAUです。GPUパイプラインが使えるかどうかがメーカーで決まるのは、ここだけです。
GPUを2基搭載したノートPCデコードが一方のGPUで、OBSの描画がもう一方で行われると、テクスチャを共有できないため、ソースは自動的に通常の方式に戻ります。
古いGPUHEVC Main10デコーダーのないGPUでは、10ビットのストリームはソフトウェアデコードになります。8ビットには影響ありません。

複数のスマートフォンを同時に使うときの負荷は、エンコードではなくデコードです。コンピュータ上では何もエンコードしないため、NVIDIAのNVENC同時セッション数の制限は関係ありません。制約になるのはデコードのスループットとメモリ帯域で、まさにGPUパイプラインが節約する部分です。

上記の測定結果は、NVIDIAのグラフィックカードを搭載した1台のWindowsマシンで得たものです。パイプラインがベータである理由の1つは、ほかの組み合わせ(macOSのIOSurface、MesaのVAAPI、nvidia-vaapi-driver、マルチGPU時のフォールバック)について、コードを増やすよりも実環境での報告が必要なことです。

自分で測定する#

ツール → LensLink設定 → パイプラインのベンチマークを記録をオンにすると、プラグインの設定フォルダ(パスはログに出力されます)に1秒ごとにCSVが1行書き込まれ、5秒ごとに概要も出力されます。構成ごとに10秒間配信し、2つを比較します。

python3 tools/bench-report.py BEFORE.csv AFTER.csv

LensLinkにパフォーマンスに関する変更を提案する場合は、この比較結果を示すことが求められます。