これは開発版のドキュメントです。
正式版はこちら

帯域推定機能

概要

帯域推定機能は、Sora とクライアントの間で利用できるネットワーク帯域を推定する機能です。Sora 2025.1.0 以降では、この機能が有効です。

WebRTC では、ネットワークの帯域に合わせて映像や音声のビットレートを動的に変更します。 帯域推定機能では、映像や音声のパケット単位で受信状況をフィードバックすることで、従来よりも精度よく帯域を推定します。 これにより、帯域が不足した場合の追従と、帯域が回復した場合の復帰が改善します。

帯域推定は、次の 2 つの方向で動作します。

  • 配信側 (クライアントから Sora への方向)
    • Sora が、パケットの受信状況をクライアントにフィードバックします
    • クライアントの libwebrtc が、フィードバックをもとに帯域を推定し、映像エンコーダーのビットレートを制御します
  • 視聴側 (Sora からクライアントへの方向)
    • クライアントが、Sora から送信されたパケットの受信状況を Sora にフィードバックします
    • Sora が、フィードバックをもとに帯域を推定します

仕組み

Transport-wide Congestion Control (TWCC) は、パケット単位で受信状況をフィードバックする仕組みです。 送信側は、すべてのパケットに通し番号を付与します。 受信側は、どのパケットをいつ受信したか、どのパケットが失われたかを一定間隔でまとめて送信側に通知します。 送信側は、パケットの到着間隔の変化からネットワークの混雑状況を判断し、利用できる帯域を推定します。

配信側 (クライアントから Sora への方向)

  • Sora は、パケットの受信状況を TWCC でクライアントにフィードバックします
  • クライアントの libwebrtc は、TWCC のフィードバックをもとに送信側で帯域を推定します
  • クライアントは、推定結果に応じて映像エンコーダーに指示するビットレートを変更します
  • 映像の TWCC は Sora 2025.1.0 以降で、音声の TWCC は Sora 2025.2.0 以降で有効です
配信側クライアントSora配信側クライアントSoraパケット (通し番号付き)TWCC フィードバッククライアントの libwebrtc が帯域を推定しエンコーダーのビットレートを制御

視聴側 (Sora からクライアントへの方向)

  • クライアントは、Sora から送信されたパケットの受信状況を TWCC で Sora にフィードバックします
  • Sora は、パケットの到着間隔から求める遅延ベースの推定と、パケットロスから求めるロスベースの推定を組み合わせて帯域を推定します
  • 推定した帯域は、次の用途で利用します
    • シグナリング通知 network.status の estimated_bandwidth
    • サイマルキャスト受信時の RID 自動切り替え
Sora視聴側クライアントSora視聴側クライアントパケット (通し番号付き)TWCC フィードバックSora が帯域を推定し通知や RID 自動切り替えに利用

バージョンごとの変更

2026.1.0

  • ネットワークの状態をシグナリングで通知する機能が正式版になりました (推定結果の通知も含みます)

2025.2.0

  • 音声の TWCC を有効にしました
  • 実験的機能として、サイマルキャスト受信時の RID 自動切り替えを追加しました
  • 再送要求の頻度を利用した不安定レベルの通知機能を廃止しました

2025.1.0

  • 帯域推定機能を追加しました
  • 映像の TWCC を既定で有効にしました
  • Sora 自身の帯域推定を既定で有効にしました
  • 実験的機能として、シグナリング通知 network.status に estimated_bandwidth を追加しました

設定ビットレートと実ビットレートの関係

Sora に指定した映像のビットレートと、実際に配信される映像のビットレートは一致しません。 原因は、TWCC を利用する場合の libwebrtc のビットレート計算にあります。

ビットレートの指定方法

音声と映像のビットレートは、次のいずれかの方法で指定します。

  • クライアントがシグナリングの "type": "connect" で audio の bit_rate と video の bit_rate を指定する
  • 認証ウェブフックのレスポンスで audio_bit_rate と video_bit_rate を指定する
  • sora.conf の default_audio_bit_rate と default_video_bit_rate を指定する

指定した値は kbps 単位で扱われ、次のようにクライアントに通知されます。

  • 映像: RFC 3890 で定義されている SDP の b=TIAS
  • 音声: SDP の maxaveragebitrate (Opus のパラメーター)

また、配信する映像では x-google-start-bitrate も通知します。 x-google-start-bitrate は Google 固有の SDP パラメーターで、RFC では定義されていません。 libwebrtc はこの値をエンコーダーが最初に利用するビットレートとして使用しますが、libwebrtc を利用しないクライアントでは解釈されません。 WHIP と WHEP では、 x-google-start-bitrate に対応していません。

libwebrtc のビットレート計算

  • TWCC を利用しない場合、libwebrtc は受信側が通知してくる利用可能な帯域をもとに、目標ビットレートを決定します
  • TWCC を利用する場合、libwebrtc はパケット単位のフィードバックから送信側で帯域を推定します
    • 目標ビットレートには、映像や音声のデータ本体だけではなく、パケットに付加される情報 (ヘッダー) や暗号化、UDP/IP などの通信に必要なオーバーヘッドも含まれます
    • エンコーダーには、目標ビットレートからオーバーヘッドと、データの欠落に備える保護分を差し引いたビットレートを指示します
  • この挙動は libwebrtc の Only include overhead if using send side bandwidth estimation で M81 (2020 年) 以降に意図的に導入されています

実際の挙動

  • ネットワークに余裕がある場合でも、映像の実ビットレートは b=TIAS の値より低くなります
    • 差の目安は 1 割弱です
    • 音声と映像を送信する場合、音声に割り当てるビットレートを差し引いた残りが映像に配分されます
    • 実際の差はパケットサイズ、フレームレート、コーデック、再送やデータ保護の利用状況により変わります
    • パケットサイズが小さいほど、オーバーヘッドの割合は大きくなります
  • この差は、libwebrtc がパケットのオーバーヘッドを目標ビットレートから差し引くために発生します。不具合ではありません
  • Sora 2024.2.x では TWCC が既定で無効だったため、同じビットレートを指定しても Sora 2025.1.0 以降の方が実ビットレートは低くなります
  • Sora 2025.2.0 以降は音声も TWCC の対象になるため、音声を含めた帯域の推定が行われます

オーバーヘッドの内訳と差し引き

ここでは、音声と映像を送信する想定で、ネットワークに余裕があり、映像のビットレートを指定した場合の例を説明します。

libwebrtc は、指定された映像のビットレートをそのままエンコーダーには指示しません。 libwebrtc は、パケットの送信に必要な次の情報を「オーバーヘッド」としてビットレートから差し引きます。

  • RTP (音声や映像のパケットを送信するコンテナー) のヘッダー: 12 バイト
  • RTP のヘッダー拡張 (TWCC の通し番号などの追加情報): 約 8 バイト
  • 再送用のヘッダー (RTX): 2 バイト
  • 暗号化: 10 バイト
  • UDP/IP (ネットワークでパケットを送るための基本的な仕組み) のヘッダー: 28 バイト
  • 合計: 約 60 バイト

libwebrtc は、最大パケットサイズ 1200 バイトにトランスポートのオーバーヘッド 38 バイト (暗号化と UDP/IP) を加えた 1238 バイトを 1 パケットとして、1 秒あたりのパケット数を計算します。 このパケット数に 1 パケットあたりのオーバーヘッド (約 60 バイト) を掛けた分が、映像のビットレートから差し引かれます。

また、指定した映像のビットレートは、音声と映像の合計の上限として扱われます。 音声 (Opus) の分が先に確保され、残りが映像に配分されます。 そのため、映像に配分されるビットレートは、指定した映像のビットレートから音声のビットレートを引いた値です。

この条件での計算例は、次のとおりです。

指定した映像のビットレート

音声

映像の配分

オーバーヘッド

映像エンコーダーへの指示

500 kbps

32 kbps

468 kbps

約 23 kbps

約 445 kbps

500 kbps

64 kbps

436 kbps

約 22 kbps

約 414 kbps

2.5 Mbps

32 kbps

2.47 Mbps

約 120 kbps

約 2.35 Mbps

2.5 Mbps

64 kbps

2.44 Mbps

約 118 kbps

約 2.32 Mbps

5 Mbps

32 kbps

4.97 Mbps

約 241 kbps

約 4.73 Mbps

5 Mbps

64 kbps

4.94 Mbps

約 240 kbps

約 4.70 Mbps

このように、音声への配分とオーバーヘッドの差し引きにより、映像のビットレートは指定した値より低くなります。 指定した映像のビットレートが小さいほど影響は大きく、500 kbps では差が 1 割を超えることもあります。

音声のビットレートを指定しない場合、libwebrtc のデフォルト値 (モノラルで 32 kbps、ステレオで 64 kbps) が使われます。 Sora のデフォルトではステレオが有効です。 そのため、音声のビットレートを指定しない場合、ステレオを無効にすると音声の分が減り、映像に配分されるビットレートが増えます。

実測値

Sora 2026.1.2 と Sora Python SDK (libwebrtc M150.7871) を利用して計測した値です。 映像コーデックには VP8 を使用し、通信には IPv4 と UDP を使用しています。 音声コーデックには Opus を使用し、音声のビットレートには 64 kbps を指定しています。 値はクライアントの getStats() の targetBitrate から取得しています。

指定した映像のビットレート

計算上の値

実測値

誤差

500 kbps

約 414 kbps

約 382 kbps

約 32 kbps 低い (約 8%)

2.5 Mbps

約 2.32 Mbps

約 2.31 Mbps

約 10 kbps 低い (1% 未満)

5 Mbps

約 4.70 Mbps

約 4.71 Mbps

ほぼ同じ

音声は、いずれの場合も 64 kbps が指示され、実際には約 55 kbps で送信されています。 指定した映像のビットレートが小さい場合、計算上の値よりも低くなることがあります。 音声のビットレートと音声パケットのオーバーヘッド分は、指定した映像のビットレートから確保されます。 映像も、1 フレームあたりに必要なパケット数をもとにオーバーヘッドが差し引かれます。 ビットレートが低いほど、これらのオーバーヘッドが相対的に大きな割合を占めます。

帯域が不安定だと判断したときの挙動

Sora とクライアントは、パケットの到着間隔とパケットロスから、帯域が不安定だと判断します。

  • パケットの到着間隔が送信間隔より長くなると、ネットワークのキューが詰まり始めていると判断します
  • パケットロスが増えると、帯域が不足していると判断します
  • 帯域が不安定だと判断した場合、目標ビットレートや推定帯域を大きく下げます
    • 遅延の増加を検出した場合は、実際に送受信できたビットレート (スループット) の 85% 程度まで下げます
    • パケットロスが 10% 以上の場合も下げます

配信側のビットレート制御

  • クライアントの libwebrtc が、映像エンコーダーに指示するビットレートを下げます
配信側クライアントSora配信側クライアントSoraパケットTWCC フィードバック到着間隔の広がりやパケットロスから帯域が不足していると判断しエンコーダーのビットレートを下げる

視聴側の RID 自動切り替え

  • 現在実験的機能として提供している RID 自動切り替え を有効にしている場合、Sora はビットレートが低い映像に切り替えます
  • 現時点の RID 自動切り替えは、ビットレートを下げる方向にのみ対応しています。帯域が回復しても、自動では高画質の映像に戻りません
  • Sora は、RID 自動切り替え以外に、転送する映像のビットレートを直接制限しません
Sora視聴側クライアントSora視聴側クライアントパケットTWCC フィードバック到着間隔の広がりやパケットロスから帯域が不足していると判断しビットレートが低い映像の RID に切り替える

帯域が回復したときの挙動

  • 配信側クライアントの libwebrtc は、パケットロスが 2% 以下の状態になると、目標ビットレートを少しずつ上げます
  • 帯域が回復した場合も、libwebrtc は一度に大きく戻さずに段階的にビットレートを上げます
  • libwebrtc は、利用できる帯域を調べるために、一時的に多めのデータを送信することがあります
  • 推定した帯域は、実際に利用できる帯域を保証するものではありません

確認方法

  • 視聴側では、シグナリング通知 network.status の estimated_bandwidth で Sora が推定した帯域を確認できます。詳細は ネットワークのシグナリング通知 をご確認ください
  • サーバー側の 統計 API では、次の項目で TWCC が動作しているかを確認できます
    • total_received_rtp_hdrext_transport_wide_cc
      • 配信側から受信した、TWCC の通し番号が付いたパケットの数
    • total_sent_rtcp_rtpfb_transport_wide
      • 配信側に送信した TWCC のフィードバックの数
    • total_sent_rtp_hdrext_transport_wide_cc
      • 視聴側に送信した、TWCC の通し番号が付いたパケットの数
    • total_received_rtcp_rtpfb_transport_wide
      • 視聴側から受信した TWCC のフィードバックの数
  • 配信側では、クライアントの getStats() で取得できる送信映像の targetBitrate (目標ビットレート) と bytesSent (送信済みバイト数) を比較することで、目標ビットレートと実ビットレートの差を確認できます

よくある質問

設定したビットレートまで映像の実ビットレートが上がらないことはありますか?

はい。TWCC を利用する場合、libwebrtc はオーバーヘッドを目標ビットレートに含めて計算し、エンコーダーにはオーバーヘッド分を差し引いたビットレートを指示します。そのため、ネットワークに余裕があっても実ビットレートは設定値を下回ります。目安は 1 割弱です。

Sora のバージョンアップで実ビットレートが低くなることはありますか?

はい。Sora 2025.1.0 で映像の TWCC を有効にし、Sora 2025.2.0 では音声も TWCC の対象にしました。Sora 2024.2.x 以前と比べて、同じビットレートを指定した場合の実ビットレートが低くなることがあります。