コンテンツにスキップ

MoQT へのメディアの載せ方

MoQT(Media over QUIC Transport、draft-ietf-moq-transport。wired は 18、19、22 の 3 つの版を話し、このガイドの節番号は draft-22 のものです)は、メディアを 4 つの階層で運びます。 メディアのどの部分をどの階層に載せるかで、途中から参加した購読者が最初に何を受け取るか、パケットが 1 つ失われたときに何を失うか、リレー(途中でメディアを中継するサーバー)が何を捨てられるかが決まります。

  • Track:名前の付いた 1 本のメディアの流れです(たとえば参加者 1 人のカメラ映像)。 購読者は、Full Track Name(名前空間と名前の組)で Track を指定します。
  • Group:購読者がそこからデコードを始められる、Object のまとまりです。 ストリーム上では、ハブは購読の Location Filter(どこから受け取り始めるかの指定)を Group 単位で適用します(moqtrun.h の wired_moqt_on_stream_data を参照)。 そのため、途中から参加した購読者は Group の先頭から受け取り始めます。
  • Subgroup:1 つの Group のうち、1 本のストリームに順番どおりに載る Object の集まりです。 このガイドのサンプルは Group ごとに Subgroup を 1 つだけ使うので、1 つの Group が 1 本のストリームになります。
  • Object:リレーが転送する単位です。 1 フレーム、1 メッセージ、または大きなペイロードの 1 断片にあたります。
  • 映像:キーフレーム(そこから単独でデコードを始められるフレーム)ごとに新しい Group を始め、続くフレームを 1 つずつ Object としてその Group に入れます(大きなフレームは複数の Object に分けます)。 Largest Object フィルターで参加した購読者は次の Group、つまり次のキーフレームから受け取るので、最初の Object からデコードできます(フィルターと、それより前の Group の取得は 過去の Object の取得 を参照)。 Group を 1 つ失っても、時間切れになっても、失うのは次のキーフレームまでのフレームだけです。
  • 音声:フレームはそれぞれ単独でデコードできるので、1 フレームを 1 Object にします。 Group の区切りの意味は映像より小さく、1 秒程度ごとに新しい Group を始めれば、途中から参加した購読者もライブに近い位置から聞けます。 音声はデータグラムで送る候補にもなります(ストリームとデータグラム を参照)。
  • チャットメッセージ:1 メッセージを 1 Object にします。 メッセージごとに短いストリームを 1 本使い、データと FIN(ストリームの終わりを示す印)を一緒に送ると、ハブは 1 回の io.send_uni 呼び出しで中継でき、遅いメッセージが次のメッセージを待たせることもありません。
  • 添付ファイル(ファイルや画像):ファイルを約 15 KiB ずつの Object に分け、1 つの Group で送ります。 受信側は順番どおりに組み立て直せ、途中から参加した購読者は添付ファイル全体を受け取るか、まったく受け取らないかのどちらかになります。

WebTransport のストリームは、いくつかに分かれてハブに届きます。 Object が 2 回の受信にまたがって途切れると、ハブはその後半を、ハブ全体で共有するバッファープール(WIRED_MOQTRUN_FRAG_POOL、8 個)の 1 つに保持します。 バッファー 1 つの大きさは WIRED_MOQTRUN_RELAY_FRAG_MAX(16384 バイト)です。 保持した後半がこの大きさに達すると、その Object は保持しきれない大きさだと判断され、ハブはそれを捨ててそのストリームの中継を止めます。 Object 自体のフレーミング(Object ID の差分、ペイロード長)や、アプリが各断片に付けるヘッダーもこの大きさに含まれます。 そのため、ペイロードを約 15 KiB にしておけば、フレーミング込みの Object が 16384 バイトに収まります。 ハブ自身の blob のフレーミングも同じ上限を使い、moqdata_blob_build は blob を最大 MOQDATA_BLOB_CHUNK(16384 バイト)ずつの Object に分けます(データグラムとストリームの配送 を参照)。