Closed9

RUSH - Reliable (unreliable) streaming protocol

voluntasvoluntas

RUSH - 信頼性のある(信頼性のない)ストリーミングプロトコル

# 概要

RUSHは、ライブビデオをインジェストするためのアプリケーションレベルのプロトコルです。このドキュメントでは、プロトコルのコア部分と、それがどのようにQUICにマッピングされるかについて説明しています。

1. はじめに

RUSHは、ライブビデオのインジェスト用に設計された双方向アプリケーションレベルのプロトコルで、QUICの上で動作します。

RUSHは、RTMP(Real-Time Messaging Protocol)の後継プロトコルとして開発され、新しいオーディオおよびビデオコーデックのサポート、新しいメッセージタイプによる拡張性、マルチトラックのサポートを目標としています。また、RUSHは、QUICストリームを利用することで、アプリケーションがデータ配信の保証を制御するオプションを提供します。

本書では、RUSHプロトコル、ワイヤフォーマット、およびQUICマッピングについて説明します。

voluntasvoluntas

2. 規約と定義

本文書のキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」、「OPTIONAL」は、以下のようにすべて大文字で表示されている場合に限り、BCP 14 [RFC2119] [RFC8174]に記載されているとおりに解釈されるものとする。

フレーム/メッセージ。
クライアントとサーバーが交換できる情報の論理的単位

PTSでは
プレゼンテーションタイムスタンプ

DTS
デコーディングタイムスタンプ

AAC:
アドバンスト・オーディオ・コーデック

NALU: network abstract layer unit

VPS:
video parameter set (H265 video specific NALU)

SPS:
シーケンス・パラメータ・セット (H264/H265ビデオ専用NALU)

PPS:
ピクチャ・パラメータ・セット (H264/H265ビデオ固有のNALU)

ADTSヘッダ:
オーディオデータトランスポートストリームヘッダ

ASC:
オーディオ専用コンフィグ

GOP:
Group of Pictures(グループオブピクチャー)の略で、フレーム内、フレーム間の配置順を指定する。

voluntasvoluntas

3. オペレーションの理論

3.1. 接続の確立

RUSHを使用してライブ配信を行うために、クライアントはALPNトークンである "rush "を使用してQUIC接続を確立します。

QUIC接続が確立すると、クライアントは新しい双方向のQUICストリームを作成し、開始フレームIDを選択し、そのストリーム上で4.2.1項の接続フレームを送信します。このストリームを「コネクトストリーム」と呼ぶ。

クライアントは動作モードの設定をコネクトフレームのペイロードで送信しますが、ペイロードのフォーマットはTBDです。

1つの接続は、1つのビデオを送信するためにのみ使用されるべきである(SHOULD)。

3.2. ビデオデータの送信

クライアントは、ConnectAckフレームセクション4.2.2を待つか、またはConnectフレームの送信後すぐにデータの送信を開始するかを選択できます。

トラックとは、データを論理的に整理したもので、例えば、ビデオの場合、1つのビデオトラックと2つのオーディオトラック(2つの言語用)があります。クライアントは、複数のトラックのデータを同時に送信することができます。

各トラックのエンコードされたオーディオまたはビデオデータは、フレーム(4.2.6項または4.2.5項参照)にシリアル化され、クライアントからサーバーに送信されます。各トラックには、単調に増加するフレームIDシーケンスがあります。クライアントは最初のフレームID=1で開始しなければなりません(MUST)。

動作モード(セクション4.3)に応じて、クライアントはオーディオおよびビデオフレームをコネクトストリームで、またはフレームごとに新しいQUICストリームで送信します。

マルチストリームモード(4.3.2項)では、クライアントは対応するQUICストリームをリセットすることで、フレームの送信を停止することができます。この場合、フレームがサーバに受信されたことは保証されません。

3.3. データの受信

Connectフレームを受信したサーバーは、ConnectAckフレーム4.2.2項を返信し、オーディオ/ビデオデータの受信準備を行います。

マルチストリームモード(セクション4.3.2)では、サーバーがConnectフレームを受信する前にオーディオまたはビデオデータを受信することが可能です。実装では、データをバッファリングするかドロップするかを選択できます。コネクトフレームの到着前に、オーディオ/ビデオデータを正しく解釈することはできません。

ノーマルモード(セクション4.3.1)では、フレームが送信された順にアプリケーション層に到着することがトランスポートによって保証されています。

マルチストリームモードでは、フレームが送信された順番とは異なる順番でアプリケーション層に到着する可能性があるため、サーバーは受信したすべてのトラックについて最終受信フレームIDを追跡しなければなりません(MUST)。あるトラックのフレームシーケンスIDにギャップがあると、順番通りでない配信を示している可能性があるため、サーバは不足しているフレームが到着するまで待ってもよい(MAY)。サーバーは、対応するQUICストリームがリセットされた場合、フレームが失われたと考えなければなりません。

フレームシーケンスのギャップを検出すると、サーバは実装で定義された時間の間、不足しているフレームが到着するのを待ってもよい(MAY)。不足しているフレームが到着しない場合、サーバはそれらを失われたものとみなし、残りのフレームの処理を継続するべきです(SHOULD)。例えば、サーバーがトラック1の次のフレームを受信し、実装で定義されたタイムアウト後にフレーム#4が到着しなかった場合、サーバーはフレーム5と6の処理を継続するべきです(SHOULD)。

クライアントがストリーミングを終了すると、クライアントはEnd of Videoフレーム(4.2.3項)を送信し、これ以上データを送信しないことをサーバに示します。

3.4. 再接続

QUICの接続がいずれかの時点で終了した場合、クライアントは単に接続確立プロセス(セクション3.1)を繰り返し、終了した場所で同じビデオの送信を再開することで再接続してもよい(MAY)。別のサーバによる新しい接続の終了をサポートするために、クライアントは、ビデオトラックがデコードできることを保証するために、I-フレームから始まるビデオフレームの送信を再開すべきです(SHOULD)。

再接続は、サーバーがメンテナンスのために「離席」する必要がある場合に、サーバーが開始することができます。この場合、サーバーは GOAWAY フレーム (4.2.7節) を送信して、クライアントに接続を優雅に閉じることを通知します。これにより、クライアントはいくつかのデータの送信を終え、新しい接続を確立して、中断することなく送信を続けることができます。

voluntasvoluntas

4. ワイヤーフォーマット

4.1. フレームヘッダー

クライアントとサーバーは、フレームを使って情報を交換します。フレームにはさまざまな種類があり、各フレームのペイロードはその種類によって異なります。

一般的なフレーム形式:

0       1       2       3       4       5       6       7
+--------------------------------------------------------------+
|                       Length (64)                            |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+------------------------------------------------------+
|Type(8)| Payload ...                                          |
+-------+------------------------------------------------------+

Length(64):
各フレームはlengthフィールドで始まります。これは64ビットのサイズで、フレームのサイズをバイト単位で表します(定義済みのフィールドを含むため、LENGTHが100バイトの場合、PAYLOADの長さは100 - 8 - 8 - 1 = 82バイトとなります)。

ID(64):
すべての新しいフレームは、同じトラック内の前のフレームのものよりも大きいシーケンスIDを持たなければなりません(MUST)。トラックIDは各フレームで指定されます。トラックIDが指定されていない場合は、暗黙的に0となります。

Type(8):
フレームのタイプを表す1バイト。

定義済みのフレームタイプ:

Length(64):
各フレームはlengthフィールドで始まります。これは64ビットのサイズで、フレームのサイズをバイト単位で表します(定義済みのフィールドを含むため、LENGTHが100バイトの場合、PAYLOADの長さは100 - 8 - 8 - 1 = 82バイトとなります)。

ID(64):
すべての新しいフレームは、同じトラック内の前のフレームのものよりも大きいシーケンスIDを持たなければなりません(MUST)。トラックIDは各フレームで指定されます。トラックIDが指定されていない場合は、暗黙的に0となります。

Type(8):
フレームのタイプを表す1バイト。

定義済みのフレームタイプ:

https://www.ietf.org/archive/id/draft-kpugin-rush-00.html#table-1

4.2. フレーム

4.2.1. 接続フレーム

+--------------------------------------------------------------+
|                       Length (64)                            |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+-------+---------------+---------------+--------------+
| 0x0   |Version|Video Timescale|Audio Timescale|              |
+-------+-------+---------------+---------------+--------------+
|                    Live Session ID(64)                       |
+--------------------------------------------------------------+
| Payload ...                                                  |
+———————————————————————————————+

バージョン:
プロトコルのバージョン(初期バージョンは0x0)。

ビデオタイムスケール:
この接続のすべてのビデオフレームタイムスタンプのタイムスケール。推奨値30000

オーディオタイムスケール:
この接続におけるすべてのオーディオサンプルタイムスタンプのタイムスケール、推奨値はオーディオサンプルレートと同じ、例えば44100

ライブセッションID:
ブロードキャストの識別子、再接続時、クライアントは同じライブセッションIDを使用しなければならない(MUST

ペイロード:
サーバーが使用できるアプリケーションおよびバージョン固有のデータ。OPTIONAL

このフレームは、クライアントがブロードキャストを開始するために使用します。クライアントは、「Connect frame」の直後に、サーバーからの確認応答を待たずに、他のフレームの送信を開始できます。

クライアントが送信したVERSIONをサーバがサポートしていない場合、サーバはコードUNSUPPORTED VERSIONを含むErrorフレームを送信する。

オーディオタイムスケールまたはビデオタイムスケールが0の場合、サーバーはエラーコード「INVALID FRAME FORMAT」のエラーフレームを送信し、接続を終了する。

クライアントがサーバーからConnectフレームを受信した場合、クライアントはコードTBDのErrorフレームを送信する。

4.2.2. Connect Ackフレーム

0       1       2       3       4       5       6       7
+--------------------------------------------------------------+
|                          17                                  |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+------------------------------------------------------+
| 0x1   |
+-------+

サーバーは、「Connect」フレームへの応答として、サーバーが「バージョン」を受け入れ、データを受信する準備ができていることを示す「Connect Ack」フレームを送信します。

クライアントは、タイムアウト時間内にサーバーからの「Connect Ack」フレームを受信しない場合、接続を終了します。タイムアウトの値は、実装によって選択されます。

QUICの接続期間中に送信できる「Connect Ack」フレームは1回のみである。

サーバーがクライアントからConnect Ackフレームを受信した場合、クライアントはコードTBDのErrorフレームを送信する。

4.2.3. ビデオフレームの終了

+--------------------------------------------------------------+
|                       17                                     |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+------------------------------------------------------+
| 0x4   |
+-------+

End of Videoフレームは、クライアントがデータの送信を終え、接続を終了しようとしているときに送信されます。サーバーは、それ以降に送信されたすべてのフレームを無視すべきである(SHOULD)。

4.2.4. エラーフレーム

+--------------------------------------------------------------+
|                       29                                     |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+------------------------------------------------------+
| 0x5   |
+-------+------------------------------------------------------+
|                   Sequence ID (64)                           |
+------------------------------+-------------------------------+
|      Error Code (32)         |
+------------------------------+

シーケンスID:
ID=0x0はコネクションレベルのエラーを示す。

エラーコード:
32ビット符号なし整数

エラーフレームは、エラーが発生したことを示すために、クライアントまたはサーバーから送信することができます。

エラーの中には致命的なものもあり、エラーフレームを送信した後、接続は閉じられます。

4.2.5. ビデオフレーム

+--------------------------------------------------------------+
|                       Length (64)                            |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+-------+----------------------------------------------+
| 0xD   | Codec |
+-------+-------+----------------------------------------------+
|                        PTS (64)                              |
+--------------------------------------------------------------+
|                        Track ID (64)                         |
+---------------+----------------------------------------------+
| I-Frame ID Offset | Video Data ...                           |
+---------------+----------------------------------------------+

コーデック:
は、このフレームのエンコードに使用されたコーデックを指定します。

PTS:
接続ビデオのタイムスケールにおけるプレゼンテーションのタイムスタンプ

DTS:
接続ビデオのタイムスケールでのデコードタイムスタンプ

対応するコーデックの種類

コーデック。
は、このフレームのエンコードに使用されたコーデックを指定します。

PTS:
接続ビデオのタイムスケールにおけるプレゼンテーションのタイムスタンプ

DTS
DTS:接続ビデオのタイムスケールでのデコードタイムスタンプ

対応するコーデックの種類

https://www.ietf.org/archive/id/draft-kpugin-rush-00.html#table-2

タイムスタンプ:
オーディオデータの最初のオーディオサンプルのタイムスタンプ。

Track ID:
このフレームがあるトラックのID

オーディオデータ:
可変長のフィールドで、コーデックに依存する1つまたは複数のオーディオフレームを含む。

AACコーデックの場合、"オーディオデータ "は1つ以上のAACサンプルで、ADTS HEADERが前に付いている。

152        158       ...     N
+---+---+---+---+---+---+---+...
| ADTS(56)  |  AAC SAMPLE   |
+---+---+---+---+---+---+---+...

連続したオーディオフレームの「オーディオデータ」に含まれるすべてのAACサンプルを、データロスなくバイナリ結合することで、有効なAACビットストリームが生成されなければならない。

OPUS コーデックの場合、「オーディオデータ」は、[RFC7845]で定義されているように、OPUS ヘッダーが前に付いた 1 つ以上の OPUS サンプルである。

4.2.7. ゴーウェイフレーム

0       1       2       3       4       5       6       7
+--------------------------------------------------------------+
|                          17                                  |
+--------------------------------------------------------------+
|                       ID (64)                                |
+-------+------------------------------------------------------+
| 0x14  |
+-------+

GOAWAYフレームは、サーバーのメンテナンスなどのために、サーバーが接続のグレースフルシャットダウンを開始するために使用されます。

GOAWAY を受信すると、クライアントは現在の GOP に残っているフレームを送信し、この接続での新しいフレームの送信を停止しなければなりません (MUST)。クライアントは、新しい接続を確立し、そこでフレームの送信を再開すべきです (SHOULD)。

GOAWAY フレームの送信後、サーバーは実装で定義された時間の間、到着したフレームの処理を続け、その後、サーバーは接続を閉じるべきです (SHOULD)。

4.3. クィックマッピング

RUSHプロトコルの主な目標の1つは、オーディオ/ビデオデータの配信の信頼性を制御する方法をアプリケーションに提供することでした。これは、セクション4.3.2の特別なモードを使用することで達成されます。

4.3.1. ノーマルモード

ノーマルモードでは、RUSHは1つの双方向QUICストリームを使用してデータを送信し、データを受信します。1つのストリームを使用することで、信頼性の高い順番通りの配信が保証され、アプリケーションは紛失したパケットの再送をQUICトランスポート層に頼ることができます。このモードのパフォーマンス特性は、RTMP over TCPに似ています。

4.3.2. マルチストリームモード

通常のモードでは、ビデオフレームに属するパケットが失われた場合、それ以降に送信されたすべてのパケットは、たとえそれらのパケットがサーバに到着していたとしても、アプリケーションには配信されません。これにより、ヘッドオブラインブロッキングが発生し、レイテンシーに悪影響を及ぼします。

この問題に対処するため、RUSHは「マルチストリームモード」を定義しています。このモードでは、オーディオ/ビデオフレームごとに1つのQUICストリームが使用されます。

接続の確立は通常の手順で行われ、クライアントがコネクトフレームを送信した後、ビデオフレームとオーディオフレームが以下のルールで送信されます。

新しいフレームはそれぞれ新しい双方向のQUICストリームで送信されます。
同じトラック内のフレームは、ID(n)=ID(n-1)+1のように、単調に増加するIDを持たなければならない。
受信者は、フレームのIDを使ってトラックを再構築します。

応答フレーム(Connect Ack と Error)は、それを送信したストリームの応答ストリームに含まれます。

クライアントは、オーディオフレームまたはビデオフレームごとに配信タイマーを設定し、タイマーが切れるとQUICストリームをリセットすることで、配信の信頼性を制御してもよい(MAY)。これにより、フレームが時間内に完全に配信されなかった場合、再送を効果的に停止することができます。

タイムアウトは実装で定義されているが、ドラフトの将来のバージョンではネゴシエートの方法を定義する予定である。

voluntasvoluntas

5. エラー処理

エラーを検出したエンドポイントは、そのエラーの存在を相手に知らせるべきです(SHOULD)。エラーはコネクション全体(5.1項参照)、または単一のフレーム(5.2項参照)に影響を与えます。

最も適切なエラーコードは、エラーを通知するエラーフレームに含まれるべきです (SHOULD)。

5.1. 接続エラー

プロトコルのコアには、接続エラーを示す1つのエラーコードが定義されています。

1 - UNSUPPORTED VERSION - サーバーが接続フレームで指定されたバージョンをサポートしていないことを示す。

5.2. フレームエラー

特定のフレームに問題があることを示す、プロトコルのコアに定義された2つのエラーコードがあります。

2 - UNSUPPORTED CODEC - サーバーが指定されたオーディオまたはビデオコーデックをサポートしていないことを示します。

3 - INVALID FRAME FORMAT - 受信機がフレームを解析できなかったか、フィールドの値に問題があったことを示します。

voluntasvoluntas

6. 拡張機能

RUSHは、プロトコルの拡張を許可しています。

拡張は、新しいフレームタイプ(セクション4)、新しいエラーコード(セクション4.2.4)、または新しいオーディオおよびビデオコーデック(セクション4.2.6、セクション4.2.5)を使用することが許可されています。

実装では、すべての拡張可能なプロトコル要素における未知の値やサポートされていない値を無視しなければなりません (MUST)。ただし、codec idはUNSUPPORTED CODECエラーを返します。実装では、未知または未サポートのタイプを持つフレームを破棄しなければなりません (MUST)。

voluntasvoluntas

7. セキュリティに関する検討事項

RUSHプロトコルは、トランスポートが提供するセキュリティ保証に依存しています。

実装は、送信者が故意にシーケンスIDにギャップのあるフレームを送信する場合に対処する準備をすべきである(SHOULD)。

実装は、サーバーがコネクトフレームを一度も受信しない場合に対応する準備をすべきである(セクション4.2.1)。

フレームパーサーは、フレーム長フィールド(4.1項参照)の値が、フレームヘッダーを含むフレームの実際の長さと一致することを保証しなければなりません(MUST)。

実装は、送信者が大きなフレーム長フィールド値を持つフレームを送信する場合に対処する準備をするべきです (SHOULD)。

voluntasvoluntas

8. IANAに関する検討事項

TODO: フレームタイプレジストリ、エラーコードレジストリ、オーディオ/ビデオコーデックレジストリの追加

このスクラップは2022/01/04にクローズされました