5.4 リアルタイム通信 (RTP)
パケット交換通信が始まったころ、多くのアプリケーションが行うのはファイルの転送だった。しかし早くも 1981 年には、デジタル化された音声といったリアルタイムトラフィックを伝達する実験が開始されている。本書ではアプリケーションに対する「リアルタイム」という言葉を送信したデータが非常に短い時間で転送されることに関して厳しい要件があることを指して使う。リアルタイムアプリケーションの古典的な例として VoIP (Voice over IP) を用いた音声通話がある: 会話を成立させるために許される遅延は非常に短い。これからすぐに見るように、リアルタイムアプリケーションでは本章で議論してきたプロトコルでは満たせない特有の要件がトランスポートプロトコルに対して課される。
マルチメディアアプリケーション ── 映像、音声、データの通信を利用するアプリケーション ── は、 インタラクティブアプリケーションとストリーミングアプリケーションの二つに大別できる。図 147 に典型的なインタラクティブアプリケーションであるビデオ会議ツールを利用する著者らの様子を示す。VoIP と同様に、インタラクティブアプリケーションは最も厳しいリアルタイム要件が課される種類のアプリケーションである。
ストリーミングアプリケーションは音声や映像などのストリームをサーバーからクライアントに転送する。代表的な商用ストリーミングアプリケーションに Spotify がある。また、YouTube や Netflix に代表される映像のストリーミングはインターネットで最も多いトラフィック形式の一つとなっている。ストリーミングアプリケーションには人間同士の対話が介在しないので、下位のプロトコルに対するリアルタイム要件はいくらか緩い。しかしデータの転送が短い時間で行われることは依然として重要となる ── 例えば、「再生」ボタンを押したら映像の再生がすぐに始まるのが望ましく、映像の再生が始まった後にパケットの到着が遅れると映像がカクついたり画像の一部が欠けたりすることになる。つまりストリーミングアプリケーションは厳密にはリアルタイムではないものの、インタラクティブアプリケーションと共通のプロトコルを利用することが正当化される程度にはインタラクティブアプリケーションとの共通点が多い。
リアルタイムなマルチメディアアプリケーション用のトランスポートプロトコルの設計者が多種多様なアプリケーションの要求に応える要件を定義する上で深刻な課題に直面することはここまでの議論から明らかだと思う。加えて彼らは異なるアプリケーション同士の対話 (例えば音声ストリームと映像ストリームの同期) にも注意を払わなければならない。こういった懸念事項が RTP (Real-time Transport Protocol) と呼ばれる主要なリアルタイム通信用トランスポートプロトコルの設計にどのように影響したかをこれから見ていく。
RTP の大部分はかつて特定のアプリケーション自体に埋め込まれていた機能に起源を持つ。RTP が機能を取り込んだアプリケーションの例に vic
と vat
がある。vic
はリアルタイムの映像、vat
はリアルタイムの音声を通信するためのアプリケーションであり、どちらも最初は UDP の上に直接実装されていた。その中で、設計者たちは通信のリアルタイム性を扱うために必要な機能を発見していった。後に彼らはそういった機能は他の多くのアプリケーションでも有用であると認識し、そういった機能を持ったプロトコルを策定した。これが後に RTP として標準化されるプロトコルである。
RTP は様々な下位プロトコルの上に実装できるものの、現在でも通常は UDP の上に実装される。このときプロトコルスタックは図 148 のようになる。ここで、トランスポートプロトコルの上にトランスポートプロトコルが積まれていることに注目してほしい。前節 でも触れたように、そうしてはいけないルールは存在しない。それどころか、UDP はポート番号ベースの簡単な逆多重化という RTP がスタート地点として必要とする機能をたまたま提供するので、それ以外の機能が最小限の UDP を採用するのは理にかなった判断と言える。つまり、RTP はポート番号を一から自作することなく、逆多重化の機能を UDP にアウトソースしている。
5.4.1 要件
汎用マルチメディアプロトコルに対する最も基礎的な要件は同様のアプリケーションとの相互運用ができることである。例えば、独立して実装された二つの音声会議アプリケーションが互いに対話できなければならない。この要件から、アプリケーションはメディアの符号化と圧縮に同じ手法を使うべきであることが明らかに示唆される: そうしなければ、あるホストから送られたデータは別のホストで解読できなくなってしまう。メディアの符号化方式は大量に存在し、それぞれが品質、帯域要件、計算コストに関するトレードオフを独自の方法で解決しているので、特定の符号化方式を使わなければならないとプロトコルが押し付けるのはおそらく悪いアイデアとなる。そうではなく、プロトコルは送信側が受信側に利用する符号化方式を伝える手段、そして両者が利用できる符号化方式が見つかるまで交渉を行う手段を提供すべきである。
ここから、RTP が提供すべき最初の機能は符号化方式を選択するための通信機能だと分かる。この機能はアプリケーションがやり取りするデータの種類 (音声、映像など) の選択も含んでいることに注意してほしい: 符号化方式が確定すれば、どんな種類のデータが符号化されるかも確定する。
符号化方式とは別の要件として、データストリームの受信側が受信するデータと時刻の関係を理解できるようにすることも重要な要件となる。リアルタイムアプリケーションはネットワークを通る間にデータストリームに混入する可能性のあるジッター (時間的な揺らぎ) に対処するために、受信したデータを一旦再生バッファ (playback buffer) に格納する。そのため、再生バッファに格納されたデータを適切なタイミングで再生するには何らかのタイムスタンプの仕組みが必要になる。
単一のメディアストリームにおけるタイミングの管理という問題に関連して、会議における複数のメディアの同期という問題もある。この問題の明らかな例として、同じ送信者から送られてきた音声ストリームと映像ストリームは同期されなければならない。以降で見るように、これは単一のストリームを再生するときのタイミングの同期より少しだけ複雑な問題となる。
さらに別の重要な機能として、パケットロスの通知がある。厳しいレイテンシ要件を持つアプリケーションは TCP のような確実なトランスポートプロトコルを利用できない点に注目してほしい: パケットロスを埋め合わせるためにデータを再送しても、そのデータが到着するころデータは古くなっていて利用価値が無い。そのため、アプリケーションは一部のパケットが到着しない状況に対応できなければならず、このための第一歩が到着しなかったパケットの通知となる。例えば、符号化方式として MPEG を利用する映像アプリケーションは失われたパケットが I フレーム、B フレーム、P フレームのいずれに属するかに応じて処理を変えるだろう。
パケットロスの原因が輻輳である場合もある。マルチメディアアプリケーションは通常 TCP を利用しないので、TCP の輻輳回避機能も持たない。しかし、マルチメディアアプリケーションの多くは輻輳に対処できる ── 例えば符号化アルゴリズムのパラメータを調整して帯域の消費を抑えることができる。こういった対処を行うには、受信側が送信側にパケットロスが起きていることを知らせる仕組みが当然必要になる。
マルチメディアアプリケーションでよく見られる機能として、「フレーム境界の通知」と呼ばれる機能がある。この文脈で「フレーム」はアプリケーションによって異なる。例えば映像アプリケーションでは単一のフレームに対応するパケットがどこからどこまでなのかを通知できると役立つ場合がある。また、音声アプリケーションでは有音部 (talksqurt, 実際に音声が流れている部分) の始まりを示せると便利である。この情報があると受信側は隣接する有音部の間に音は流れないと確信できるので、その間に再生点を移動させることができる。これは単語間の時間を多少変化させてもユーザーは気づかないのに対して、単語が話されている時間を変化させるとユーザーは気が付いて不快に感じるという観察に基づくテクニックである。
リアルタイム通信用プロトコルに入れておきたい最後の機能として、IP アドレスよりユーザーフレンドリーな形で送信者を識別する方法がある。図 147 に示すように、ビデオ会議といったアプリケーションではユーザーインターフェースに参加者を識別する文字列を表示できるので、そういった文字列とデータストリームの関連付けをアプリケーションプロトコルがサポートするのが望ましい。
プロトコルに必要となる機能とは別の要件が一つある: 帯域をそれなりに効率的に利用しなければならない。つまり、長いヘッダーにほんの少ししかデータの付いていないパケットを大量に送って帯域を無駄遣いしないように気を付ける必要がある。その理由は、マルチメディアデータとして最もよく利用される音声のパケットはサンプルがパケットを埋める時間を短くするために小さくされる傾向があるためである。音声サンプルを入れるパケットが長いとサンプルが集まってパケットになるまでの時間が延びてレイテンシが大きくなるので、ユーザーが体感する会話のクオリティは低下する (これはATM セルが固定長を選択した理由の一つである)。データパケット自体が短いとヘッダーが相対的に長くなり、帯域の大部分がヘッダーで満たされ、「有用な」データに使える帯域が減少する。ヘッダーを短くする必要性が RTP の設計に与えた影響を後でいくつか見る。
ここまでに説明した機能の全てをリアルタイム通信用トランスポートプロトコルが本当に持つ必要があるのかについては議論の余地があり、これ以外にも追加すべき機能は存在する。ここでは便利な抽象化と構成要素をアプリケーションに提供することで開発者を簡単にするという考え方が重要となる。例えばタイムスタンプの仕組みを RTP に追加すれば、全てのリアルタイムアプリケーションの開発者が独自にタイムスタンプを実装する時間が節約される。さらに、二つのリアルタイムアプリケーションが相互運用できる可能性も向上する。
5.4.2 RTP の設計
マルチメディアのためのトランスポートプロトコルに対する非常に長い要件リストを説明したので、次はこういった要件を満たすために規定されたプロトコルの詳細を見ていこう。実は RTP の規格は RTP と RTCP (Real-Time Control Protocol) という二つのプロトコルを定義する。RTP はマルチメディアデータの交換に使われ、RTCP は特定のデータフローに関連付けられる制御情報を定期的に送信するために利用される。UDP の上に実装する場合、RTP のデータストリームとそれに関連付いた RTCP の制御ストリームは連続する UDP ポートを利用し、RTP のデータは偶数のポート、RTCP の制御情報はその次の (奇数の) ポートでやり取りされる。
RTP は様々な種類のアプリケーションをサポートできるように設計されているので、新しい種類のアプリケーションが登場するたびに RTP プロトコルを何度も改訂しないで済むように柔軟な仕組みを提供する。アプリケーションのクラス (例えば「音声アプリケーション」) ごとに、RTP は一つのプロファイル (profile) と一つ以上のフォーマット (format) を定義する。プロファイルはそのアプリケーションクラスで用いられる RTP ヘッダーのフィールドの一意な解釈を保証するための様々な情報を提供する (後で具体的な例を詳しく見れば理解できるだろう)。フォーマットの仕様は RTP ヘッダーの後に続くデータの解釈を記述する。例えば RTP ヘッダーの後ろにバイト列がそのまま並び、それぞれが定義された間隔で採取された音声サンプルを表すかもしれない。データのフォーマットがこれより複雑になる場合もある: 例えば MPEG で符号化されたビデオストリームでは、異なる種類の情報を全て表現するためにデータに少なからぬ構造が必要になるだろう。
教訓
RTP の設計は ALF (Application Level Framing, アプリケーションレベルのフレーム化) と呼ばれるアーキテクチャ原則を体現している。この原則は Clark と Tennenhouse によって 1990 年に、新たに出現しつつあったマルチメディアアプリケーション用のプロトコルを設計する上での新しい手法として提唱された。そういった新しいアプリケーションは TCP のような既存のプロトコルでは対応できない可能性が高く、さらに言えばどんな「万能の」プロトコルでも対応できないだろうと彼らは考えた。この原則の核にあるのは「アプリケーションが必要とするものはアプリケーション自身が最もよく理解している」という考え方である。例えば MPEG を利用する映像アプリケーションはフレームが喪失したときに行うべき処理、そして喪失したフレームが I フレームか B フレームかに応じて行うべき異なる処理を他のどんなアプリケーションよりもよく知っている。そのアプリケーションは転送のためにデータをどのように分割すべきかも一番よく理解している ── 例えば、パケットが喪失したときに失われるフレームを一つにするために、異なるフレームに属するデータを同じデータグラムに入れるべきではない。これが理由となって、RTP はプロトコルの詳細の大部分をアプリケーションに特有なプロファイルとフォーマットを規定する文書に任せている。
ヘッダーのフォーマット
図 149 に RTP ヘッダーのフォーマットを示す。最初の 12 バイトは必ず存在し、次の CSRC (contributing source, 貢献送信元) 識別子は特定の状況でのみ使われる。その後には省略可能な拡張ヘッダーが続く (後述)。ヘッダーの後ろには RTP ペイロードがあり、そのフォーマットはアプリケーションによって異なる。このヘッダーには多くの異なるアプリケーションで使われる可能性が高いフィールドだけが含まれている: この裏には「アプリケーション特有の情報はそのアプリケーションでのみ使われる RTP ペイロードを使った方が効率良く伝達できる」という考え方がある。
最初の 2 ビットはバージョンの識別子であり、執筆時点では 2 に設定される。将来のものを含めて RTP の全てのバージョンを識別するためのフィールドがたった 2 ビットとは大胆だと思うかもしれないが、RTP ヘッダーではビットが非常に高価なことを思い出してほしい。さらに、アプリケーションごとにプロファイルとフォーマットが用意されるので、ベースの RTP プロトコルに対する変更が必要になる可能性は普通のプロトコルより低い。仮に RTP の新しいバージョンが必要になったとしても、将来のバージョンを識別できるようにヘッダーフォーマットを変えることはできる。例えば、バージョンフィールドが 3 の新しい RTP ヘッダーは「サブバージョン」フィールドを持つようにすればいい。
次のビットはパディング (padding, P
) ビットであり、何らかの理由で RTP ペイロードにパディングが含まれる場合は 1
に設定される。暗号アルゴリズムからの要請などによって特定のサイズのブロックになるまで RTP ペイロードにパディングが必要になる場合がある。そういった場合には、RTP のヘッダー、ペイロード、パディングを含めた完全な長さが下位層のプロトコル (例えば UDP) のヘッダーに含まれ、RTP パケットの末尾に無視すべきパディングの長さが記される (図 150)。このアプローチによってパディングの有無にかかわらずパケットの長さを表すフィールドが RTP ヘッダーに不必要となる点に注目してほしい。パディングが存在しない通常のケースでも、下位層のプロトコルのヘッダーを見ればパケットの長さを取得できる。
次の拡張 (extension, X
) ビットは拡張ヘッダーの有無を表す。拡張ヘッダーはアプリケーション特有のヘッダーであり、存在する場合はメインヘッダーの後ろに続く。ただし、アプリケーションが特有のヘッダーを利用する場合でも通常はそのヘッダーをペイロードの一部として定義できるので、拡張ヘッダーはほとんど使われない。
X
ビットの後には CSRC (contributing source, 貢献送信元) の個数を表す 4 ビットのフィールド (CC
) が続く。この値が 0
である (貢献送信元が存在しない) 場合もある。貢献送信元については後述する。
先述したように、マルチメディアアプリケーションではフレーム境界を通知する機能が必要になるケースが多い。この機能はマーカー (marker, M
) ビットによって提供される。このビットはプロファイルによって異なる使われ方をする。例えば音声アプリケーションでは有音部の始まりを表すのに M
ビットを利用できる。
M
ビットに続く 7 ビットはペイロードタイプ (payload type, PT
) フィールドであり、このパケットが伝達するマルチメディアデータのタイプを表す。このフィールドの利用例としては、利用できるリソースやクオリティに関するフィードバックに基づいてアプリケーションが符号化方式を変化させる仕組みでの利用が挙げられる。ペイロードタイプフィールドを具体的にどう使うかはここでもアプリケーションプロファイルによって規定される。
ペイロードタイプはデータを異なるアプリケーションに送り分けるための逆多重化鍵としては通常使われないことに注意してほしい。また、単一のアプリケーションが持つ異なるストリーム (例えばビデオ会議アプリケーションにおける音声ストリームと映像ストリーム) にデータを送り分けるために使われることもない。逆多重化は UDP などの下位層によって提供されるためである。このため、通常 RTP を利用する二つのメディアストリームは異なる UDP ポート番号を持つ。
次のシーケンス番号 (sequence number) フィールドは欠けているパケットや順番が前後したパケットを RTP ストリームの受信側で検出するために存在する。送信側はパケットを送信するたびにシーケンス番号を一つ増加させるだけでシーケンス番号の対応が完了する。RTP はパケットを検出しても何も行わない点に注意してほしい。これに対して TCP は再送でパケットロスを修復し、さらにパケットロスを輻輳の兆候と解釈して場合によってはウィンドウサイズの調整を行う。これと異なり、RTP ではパケットロスの対応がアプリケーションに任せられる。RTP が使われる環境ではパケットロスへの対応がアプリケーションによって大きく異なるためである。例えば、映像アプリケーションはパケットが欠けたときに正しく転送された最後のフレームをもう一度表示させるのが最良の選択肢だと判断するかもしれない。さらに、符号化アルゴリズムを調整することで帯域の消費を削減する場合もあるだろう。いずれの機能も RTP には含まれていない。仮にパケットロスが起こったときは送信レートを落とさなければならないと RTP が定めたとしたら、一部のアプリケーションは RTP を全く使えなってしまうだろう。それは実用的なプロトコルの行うことではない。
シーケンス番号フィールドに続くタイムスタンプフィールドは受信側がサンプルを適切な間隔で再生するため、そして異なるメディアストリームを同期するために存在する。必要とされる時刻の粒度はアプリケーションによって異なるので、RTP は時刻を測定する単位を規定しない。そうではなく、タイムスタンプが表すのはクロックが「ティック」した回数であり、ティックの間隔は符号化方式に依存すると規定される。例えば音声アプリケーションが 125 μs ごとにデータをサンプルするなら、その値をクロックの分解能として使うことが考えられる。クロックの分解能は RTP プロファイルやアプリケーションに対するペイロードフォーマットで規定される詳細の一つである。
パケットのヘッダーに含まれるタイムスタンプの値はペイロードに含まれる最初のサンプルが生成された時刻を表す。この値が表すのは時刻ではなく、タイムスタンプの値の差だけが意味を持つ。例えばサンプリングの周期が 125 μs で、パケット \(n + 1\) の最初のサンプルがパケット \(n\) の最初のサンプルより 10 ms 後に生成されるなら、二つのサンプルの間に存在するサンプルの個数は次のように計算できる:
クロックの粒度がサンプリングの周期と同じだと仮定すれば、パケット \(n + 1\) のタイムスタンプはパケット \(n\) のタイムスタンプより 80 だけ大きい値になるはずだと分かる。無音検出などの圧縮テクニックにより実際に送られるサンプルが 80 個より少ない可能性があるものの、タイムスタンプのおかげで受信側は正しい時間的関係を保ってサンプルを再生できることに注目してほしい。
SSRC (synchronization source, 同期送信元) 識別子は RTP ストリームの単一の送信元を一意に識別する 32 ビットの値である。例えばマルチメディア会議では、それぞれの送信者にランダムな SSRC を選択させることで全員に (高い確率で) 異なる SSRC を割り当てられるようにする。送信元の識別子を送信元のネットワークアドレスやトランスポートアドレスと異なる値にすることで、RTP は下位層のプロトコルとの独立性を保証している。また下位層とは別に識別子を用意することで、複数の送信元 (例えば複数のカメラ) を持つ単一のノードがそれぞれの送信元を区別できるようにもなる。後述するように、RTCP にはメディア間の同期を行うための仕組みが存在するので、単一のノードが異なるメディアストリーム (例えば音声と映像) を生成する場合でもそれぞれのストリームが同じ SSRC を使わなくても問題ない。
CSRC (contributing source, 貢献送信元) 識別子はいくつかの RTP ストリームが何らかのミキサーに通されるときにだけ利用される。ミキサーは多くの送信元から受信したデータをまとめて単一のストリームとして送信することで帯域要件を下げるために利用される。例えば、同時に発声する複数人から送られてきた音声ストリームを一度それぞれデコードしてから単一の音声ストリームに再符号化してどこかに送信するといった使い方ができる。このケースでミキサーは自身を同期送信元としてヘッダーに書き込むのに加えて、送ろうとしているパケットに音声が載っている (貢献した) 発言者の SRRC の値を全て貢献送信元として書き込んでからパケットを送信する。
5.4.3 制御プロトコル (RTCP)
RTCP はマルチメディアアプリケーションで利用されるデータストリームと関連付く制御ストリームを提供する。この制御ストリームが持つ主な機能は次の三つである:
-
アプリケーションとネットワークのパフォーマンスに関するフィードバックを行う。
-
同じ送信者から送られてきた異なるメディアストリームの関連付けと同期を行う。
-
ユーザーインターフェースに表示する送信者のアイデンティティを伝達する。
一つ目の機能は輻輳の検出と対処で有用となる。アプリケーションの中には例えば動作レートを変更したり、圧縮方式を強力なものに切り替えたりすることで輻輳を低減できるものがある。逆に輻輳が存在しないときはクオリティの高いストリームを送信できる。また、パフォーマンスに関するフィードバックはネットワークの問題を診断する上でも役立つ。
二つ目の機能は RTP の同期送信元 (SSRC) の識別子によって提供されていると思うかもしれないが、実際には提供されているとは言えない。先述したように、単一のノードが持つ複数のカメラは異なる SSRC の値を持つ。また、同じノードが送信する音声ストリームと映像ストリームが同じ SSRC の値を使わなければならないという要件は存在しない。さらに SSRC は衝突することがあるので、ストリームが持つ SSRC の値を変更する必要が生じる可能性もある。この問題に対処するために、RTCP には CNAME (canonical name, 正規名) と呼ばれる概念が存在する。CNAME は送信者に割り当てられ、その後 CNAME を持った送信者に様々な SSRC の値を関連付ける処理が RTCP の仕組みを用いて行われる。
二つのストリームを関連付けることはメディア間同期という問題の一部でしかない。異なるストリームは全く異なるクロックを持つ (粒度が異なり、不正確さやドリフトの量さえ異なる) ので、ストリームを互いに正確に同期する手段が必要になる。この問題を解決するために、RTCP は RTP データパケットで伝達されるクロックレートに依存したタイムスタンプに実際の時刻を関連付けるためのタイミング情報をやり取りする。
RTCP はいくつかの異なるタイプのパケットを定義する。その一部を示す:
-
送信者レポート (sender report): セッションに属するアクティブな送信者がデータの送信と受信に関する統計情報を報告する。
-
受信者レポート (receiver report): 送信者でない受信者がデータの受信に関する統計情報を報告する。
-
送信元記述 (source description): CNAME などの送信元を記述する情報を伝達する。
-
アプリケーション特有の制御パケット
こういった RTCP パケットは下位プロトコルを通じて送信される (先述の通り、下位プロトコルには通常 UDP が使われる)。複数の RTCP パケットを一つの下位プロトコルの PDU (Protocol Data Unit) に詰め込むことができる1。下位プロトコルの PDU には少なくとも二つの RTCP パケットを入れられることが要求される: 一つはレポートパケット、もう一つは送信元記述パケットに使われる。他のパケットは下位プロトコルのサイズ制限が許す限りパケットに入れることができる。
RTCP パケットの中身を詳しく見ていく前に、マルチキャストグループの全てのメンバーが周期的に制御トラフィックを送信するとそれだけで問題が発生する可能性がある事実を指摘しておく。何らかの対策を講じない限り、消費される帯域の多くが制御トラフィックになりかねない。例えば音声会議では複数人が同時に声を出すことはまずないので、任意の時点で音声を送信するのは多くても二人か三人に過ぎない。しかし制御トラフィックに関してはこういった社会的制限が存在しないので、数千人が参加するような会議では制御トラフィックが深刻な問題になる。この問題に対処するため、RTCP には参加者が増えたときにレポートを送信する頻度を減らす仕組みが存在する。この仕組みは多少入り組んでいるが、RTP データトラフィックと比べたときの RTCP トラフィックの割合を小さく (典型的には 5% 以下に) することが基本的な目標とされる。この目標を達成するため、参加者は利用中と推定されるデータ帯域 (例えば三つの音声ストリームを送信するときの消費帯域の推定値) と参加者数を知っておく必要がある。前者は RTP とは異なる手段 (本節の最後に説明するセッション管理) を使って学習され、後者は他の参加者からの RTCP レポートを通じて学習される。RTCP レポートが送られる頻度は非常に低い可能性があるので参加者数は近似値にしかならないものの、通常はそれで十分となる。さらに、参加者の多くはアクティブな送信者からのレポートを受け取ることを望むはずだという仮定に基づき、RTCP の帯域をアクティブな送信者に多く割り当てることが推奨されている。
参加者が RTCP トラフィックに費やせる帯域の量を計算すると、その量に応じた適切な頻度で周期的にレポートを送信する。送信者レポートと受信者レポートの違いは前者が送信者に関する情報を持つ点のみであり、両方のレポートには前回のレポートから現在のレポートまでの間に全ての送信元から受信したデータに関する情報が含まれる。
送信者レポートだけが持つ追加情報は次の要素からなる:
-
このレポートが生成された瞬間の実際の時刻を表すタイムスタンプ
-
このレポートが生成された瞬間に対応する RTP タイムスタンプ
-
この送信者が送信を開始してから送信したパケット数およびバイト数
最初の二つの値を使うと同じ送信元から送信された異なるメディアストリームの同期が可能になる点に注目してほしい。時刻を RTP タイムスタンプに変換するための情報が送信者レポートによって与えられるので、異なるメディアストリームの同期はそれぞれのメディアストリームが異なる粒度のクロックを使っていたとしても行える。
送信者レポートと受信者レポートの両方には前回のレポートを送信した瞬間からレポートを作成する瞬間までに受信したデータに関する統計情報を報告するブロックが送信元ごとに一つずつ含まれる。各ブロックには特定の送信元に関する次の情報が含まれる:
-
送信元の SSRC
-
前回のレポートを送信した後に送信元から送られたデータパケットで喪失したものの割合 (受信したパケット数と期待されるパケット数から計算される; 後者の値は RTP のシーケンス番号から分かる)
-
送信元から送られたパケットが喪失した通算回数
-
送信元から受信した最も大きなシーケンス番号 (をラップアラウンドに対応するために 32 ビットに拡張した値)
-
送信元から届くパケット間のジッターの推定値 (到着するパケットの間隔を期待される転送間隔と比較することで計算される)
-
送信元から RTCP を通じて最後に受け取ったタイムスタンプ
-
送信元から RTCP を通じて最後に受け取った送信者レポートからの経過時間
想像できるように、この統計情報の受信者はセッションの状態に関して様々なことを学習できる。特に、他の受信者が自身より高いクオリティでストリームを受信していないかどうかを確認できる。もしそのような受信者が存在するなら、それはリソースの予約を行うべきであること、あるいはネットワークが解決すべき問題を抱えていることを示している可能性がある。また、多くの受信者が頻繁なパケットロスを経験していることに気付いた送信者は、送信レートを下げたりパケットロス耐性の高い符号化方式に切り替えたりする判断を行うだろう。
RTCP に関する話題として最後に送信元記述パケットを説明する。送信元記述パケットには最低でも送信者の SSRC と CNAME が含まれる。CNAME の命名では、同期を行う可能性のあるメディアストリーム (例えば個別に生成される同じユーザーからの音声ストリームと映像ストリーム) を生成する全てのアプリケーションが同じ CNAME を使うように命名が行われる。ただし、同じユーザーが生成するメディアストリームが用いる SSRC の値は異なっていて構わない。こうすることで、受信者は同じ送信者からのメディアストリームを識別できるようになる。最もよく使われる CNAME のフォーマットは user@host
の形をしており、host
は送信マシンの完全修飾ドメイン名を表す。例えば、cicada.cs.princeton.edu
上のマシンでユーザー jdoe
が起動したアプリケーションは文字列 jdoe@cicada.cs.princeton.edu
を CNAME として利用する。CNAME は可変長で長くなることが多いので、リアルタイムで処理しなければならないパケットに記される SSRC のフォーマットとしては不適切である。定期的な RTCP メッセージで CNAME を SSRC に関連付けることで、SSRC にはコンパクトで効率に優れるフォーマットを使えるようになっている。
送信元記述パケットにはユーザーの実名やメールアドレスなどの他の情報も含まれる可能性がある。こういった情報はユーザーインターフェースや参加者との連絡で使われるものの、RTP の動作に関して CNAME ほどの重要性はない。
TCP と同様、RTP と RTCP は非常に複雑なプロトコルである。この複雑性は主にアプリケーション設計者の仕事を楽にしようとしたことから生じている。可能なアプリケーションの数には限りがないので、トランスポートプロトコルの設計における主要な課題はアプリケーションが抱える幅広い要求に応えられるだけの十分な一般性をプロトコルに持たせながらもプロトコル自体を実装可能に保つことである。この点で RTP は大きな成功を収めており、インターネットの上で動作する多くのリアルタイムマルチメディアアプリケーションの基礎となっている。
-
訳注: PDU は「パケット」「フレーム」「データグラム」といったデータの送受信単位を一般に指す言葉。 ↩︎