帯域推定機能

概要

Sora では Sora とクライアントの間で利用できるネットワーク帯域を推定する帯域推定機能を搭載しています。

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

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

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

仕組み

Transport-Wide Congestion Control (TWCC) という仕組みを利用して、帯域を推定します。 TWCC は、パケット単位で受信状況をフィードバックする仕組みです。

  • 送信側は、すべての RTP パケットに通し番号を付与します
  • 受信側は、どのパケットをいつ受信したか、どのパケットが失われたかを一定間隔でまとめて送信側に通知します
  • 送信側は、パケットの到着間隔の変化からネットワークの混雑状況を判断し、利用できる帯域を推定します

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

  • クライアントは、通し番号を付けたパケットを 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 単位で扱われ、次のようにクライアントに通知されます。

  • 映像: video の bit_rate で指定した値を、SDP の b=TIAS で通知
  • 音声: SDP の maxaveragebitrate (Opus のパラメーター)

b=TIAS は、映像のビットレートの上限を伝えるための SDP の項目で、RFC 3890 で定義されています。 video の bit_rate はこの上限を指定する値であり、指定したビットレートでの送信を保証するものではありません。

libwebrtc のビットレート計算

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

実際の挙動

  • ネットワークに余裕がある場合でも、映像の実ビットレートは video の bit_rate で指定した値より低くなることがあります
    • 差は一定の割合ではなく、指定したビットレートが低いほど、音声への配分やオーバーヘッドの影響が大きくなります
    • 音声と映像を送信する場合、映像には音声のビットレートと音声のオーバーヘッドを差し引いたビットレートが割り当てられます
    • 実際の差は映像の内容、パケットサイズ、フレームレート、コーデック、再送 (RTX) やデータ保護 (FEC) の利用状況により変わります
    • パケットサイズが小さいほど、オーバーヘッドの割合は大きくなります
  • この差には、音声への配分やオーバーヘッドの差し引き、エンコーダーによる調整が影響します。設定値を下回ることだけでは、不具合とは判断できません
  • Sora 2024.2.x 以前では TWCC を有効にしていなかったため、同じビットレートを指定しても Sora 2025.1.0 以降の方が実ビットレートは低くなることがあります
  • Sora 2025.2.0 以降は音声も TWCC の対象になるため、音声を含めた帯域の推定が行われます

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

ここでは、後述する実測値と同じ libwebrtc M155、VP8、Opus、IPv4 の条件で、ネットワークに余裕がある場合の例を説明します。

映像のオーバーヘッド

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

  • IPv4/UDP (ネットワークでパケットを送るための基本的な仕組み) のヘッダー
  • RTP (音声や映像をリアルタイムに転送するプロトコル) のヘッダー
  • RTP のヘッダー拡張 (TWCC の通し番号などの追加情報)
  • 再送用のヘッダー (RTX)

この条件では、映像の計算に使われるオーバーヘッドは 1 パケットあたり約 50 バイト、基準となるパケットサイズは約 1200 バイトです。

50 / 1200 x 100 から、以下では映像のパケットのオーバーヘッドを映像への配分の約 4% として概算します。 実際の映像のオーバーヘッドは、条件によって変わります。

また、指定した映像のビットレートは、音声と映像を合わせた送信量の厳密な上限にはなりません。 音声と映像の最小割り当ての合計が指定値を超える場合、libwebrtc は帯域の制約を引き上げることがあります。 音声 (Opus) のビットレートと音声のオーバーヘッドが先に確保され、残りが映像に配分されます。

音声のオーバーヘッド

音声の計算に使われるオーバーヘッドは IPv4/UDP のヘッダーが 28 バイト、音声の RTP ヘッダーとヘッダー拡張が合計 24 バイトです。

音声パケットは 20 ms ごとに 1 回、1 秒あたり 50 回送信されるので、音声のオーバーヘッドは (28 + 24) x 8 x 50 = 20800 bps となり、20.8 kbps が確保されます。実際の音声のオーバーヘッドは、条件によって変わります。

そのため、音声に 32 kbps を指定した場合の割り当ては 52.8 kbps、64 kbps を指定した場合は 84.8 kbps です。 音声のビットレートを大きくするほど、映像のビットレートから差し引かれる分も大きくなります。

計算例

上記の条件での計算例は、次のとおりです。 映像の概算値は、映像への配分から映像のパケットのオーバーヘッドを差し引いた値です。 実際に映像エンコーダーに指示されるビットレートには、さらにコーデック固有のオーバーヘッドやエンコーダーによる調整が影響します。

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

音声とオーバーヘッド

映像の配分

映像のオーバーヘッド

映像の概算値

500 kbps

32 kbps + 20.8 kbps

447.2 kbps

約 18 kbps

約 429 kbps

500 kbps

64 kbps + 20.8 kbps

415.2 kbps

約 17 kbps

約 399 kbps

2.5 Mbps

32 kbps + 20.8 kbps

2447.2 kbps

約 98 kbps

約 2.35 Mbps

2.5 Mbps

64 kbps + 20.8 kbps

2415.2 kbps

約 97 kbps

約 2.32 Mbps

5 Mbps

32 kbps + 20.8 kbps

4947.2 kbps

約 198 kbps

約 4.75 Mbps

5 Mbps

64 kbps + 20.8 kbps

4915.2 kbps

約 197 kbps

約 4.72 Mbps

指定した映像のビットレートが小さいほど、音声への配分やオーバーヘッドが占める割合は大きくなります。

音声のビットレートを指定しない場合、libwebrtc のデフォルト値 (モノラルで 32 kbps、ステレオで 64 kbps) が使われます。Sora のデフォルトではステレオが有効です。

ビットレートの実測値

libwebrtc M155 を利用して、 sendonly で計測した値です。

  • 音声は Opus を指定し、ビットレートは指定していません
  • 映像は VP8 を指定し、1280x720、30 fps のテスト映像 (FFmpeg の testsrc2) を入力しています
  • 通信は IPv4 で、Sora 内蔵の TURN を経由しています

各値は、40 秒間の送信のうち、後半 20 秒間に取得した値の中央値です。

targetBitrate は映像の目標ビットレート、実ビットレートは音声+映像の合計です。

設定

映像の targetBitrate

音声

映像の実ビットレート

合計

設定との差

100 kbps

30 kbps

64 kbps

30 kbps

94 kbps

6 kbps

500 kbps

386 kbps

64 kbps

391 kbps

454 kbps

46 kbps

2.5 Mbps

2.27 Mbps

64 kbps

2.29 Mbps

2.36 Mbps

143 kbps

5 Mbps

4.61 Mbps

64 kbps

4.69 Mbps

4.75 Mbps

247 kbps

この計測では、音声のビットレートを指定していないためデフォルト値の 64 kbps になります。実際の音声ペイロードは約 63.7 kbps で送信されていました。

Opus は可変ビットレートで動作するため、音声の実ビットレートは入力内容によって変わります。 指定した映像のビットレートから、音声のビットレートと音声パケットのオーバーヘッドが確保されます

映像では配分とパケットサイズから 1 秒あたりのパケット数を求め、整数に切り上げた数をもとにオーバーヘッドを差し引きます。ビットレートが低いほど、これらのオーバーヘッドが相対的に大きな割合を占めます。

サイマルキャスト利用時の目標ビットレート

サイマルキャストでは outbound-rtp が RID ごとに出力され、 targetBitrate は RID ごとの目標ビットレートです。 RID ごとの目標値は設定ビットレートによって変わります。

libwebrtc M155 で、 sendonly の VP8 / VP9、1280x720、30 fps のテスト映像 (FFmpeg の testsrc2)、Opus 64 kbps、IPv4 を計測した値です。 各値は 40 秒間の送信のうち、後半 20 秒間の中央値です。

r0 / r1 / r2 は映像、合計は音声+映像です。 目標値は libwebrtc のテーブルと前述のオーバーヘッド計算から求めた値です。

VP8

設定

r0 (目標 / 実測)

r1 (目標 / 実測)

r2 (目標 / 実測)

音声

合計

設定との差

500 kbps

150 / 146 kbps

249 / 230 kbps

0 / 0 kbps

64 kbps

439 kbps

61 kbps

1.2 Mbps

150 / 160 kbps

700 / 901 kbps

0 / 0 kbps

63 kbps

1.12 Mbps

75 kbps

2.5 Mbps

150 / 146 kbps

500 / 485 kbps

1.67 / 1.60 Mbps

63 kbps

2.30 Mbps

203 kbps

5 Mbps

150 / 146 kbps

500 / 487 kbps

4.07 / 3.97 Mbps

64 kbps

4.67 Mbps

333 kbps

VP9

設定

r0 (目標 / 実測)

r1 (目標 / 実測)

r2 (目標 / 実測)

音声

合計

設定との差

500 kbps

142 / 133 kbps

257 / 232 kbps

0 / 0 kbps

64 kbps

429 kbps

71 kbps

1.2 Mbps

142 / 132 kbps

420 / 389 kbps

509 / 487 kbps

64 kbps

1.07 Mbps

129 kbps

2.5 Mbps

142 / 134 kbps

420 / 390 kbps

1.76 / 1.63 Mbps

64 kbps

2.21 Mbps

286 kbps

5 Mbps

142 / 132 kbps

420 / 389 kbps

4.16 / 3.93 Mbps

63 kbps

4.51 Mbps

486 kbps

差は設定ビットレートやコーデックによって変わります。

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

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

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

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

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

視聴側の RID 自動切り替え

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

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

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

確認方法

配信側のビットレート

クライアントの getStats() で、送信映像の outbound-rtp 統計を取得します。

  • targetBitrate: 取得時点の映像エンコーダーの目標ビットレート (bps)
  • bytesSent: 再送分を含む累積送信ペイロードのバイト数
  • retransmittedBytesSent: 累積再送ペイロードのバイト数

同じ id の統計を 2 回取得し、次の式で計測区間の実ビットレート (bps) を算出します。

(bytesSent の差分 x 8) / 経過秒数

経過秒数は、2 回の timestamp の差分 (ms) を 1000 で割った値です。 targetBitrate と比較する場合は、各計測時の bytesSent から retransmittedBytesSent を差し引き、その差分を使って再送分を除いた実ビットレートを算出します。

視聴側の推定帯域

シグナリング通知機能が有効で、 sora.conf の signaling_notify_network が true の場合、シグナリング通知 network.status の estimated_bandwidth で、Sora からクライアントへの推定帯域を確認できます。 通知の条件と形式は ネットワークのシグナリング通知 をご確認ください。

サーバー側の TWCC の送受信

統計 API で、通信中に次のカウンターが増えているかを確認します。 配信側との通信では最初の 2 項目、視聴側との通信では後半の 2 項目が対応します。

項目

内容

total_received_rtp_hdrext_transport_wide_cc

配信側から受信した、TWCC の通し番号が付いた RTP パケットの数

total_sent_rtcp_rtpfb_transport_wide

配信側に送信した TWCC のフィードバックの数

total_sent_rtp_hdrext_transport_wide_cc

視聴側に送信した、TWCC の通し番号が付いた RTP パケットの数

total_received_rtcp_rtpfb_transport_wide

視聴側から受信した TWCC のフィードバックの数

よくある質問

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

はい。TWCC を利用する場合、libwebrtc は音声への配分やオーバーヘッドを差し引いたビットレートを映像エンコーダーに指示します。

そのため、ネットワークに余裕があっても実ビットレートは設定値を下回ることがあります。 差は一定の割合ではなく、低ビットレートでは音声への配分やオーバーヘッドの影響が大きくなります。

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

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

TWCC を無効にすることはできますか?

いいえ。Sora には、TWCC を無効にする公開設定はありません。

TWCC のフィードバックを利用した帯域推定により、クライアントの libwebrtc は帯域の変化に合わせて送信ビットレートを調整します。これにより、ネットワークの混雑によるパケットの遅延やロスを抑えられます。