banner
fwrite

fwrite

好好生活
twitter
github
email

RTP

RTP プロトコルの紹介#

リアルタイムトランスポートプロトコル RTP(Real-time Transport Protocol)は、IETF のマルチメディアトランスポートワーキンググループによって 1996 年に RFC 1889 で発表され、その後 RFC3550 で更新されたネットワークトランスポートプロトコルです。

それはインターネット標準として RFC 3550 に詳細に説明されています。
RTP プロトコルは、インターネット上で音声と映像を伝送するための標準データパケット形式を詳細に説明しています。最初はマルチキャストプロトコルとして設計されましたが、その後多くのユニキャストアプリケーションで使用されるようになりました。RTP プロトコルは、ストリーミングメディアシステム(RTSP プロトコルと組み合わせて)、ビデオ会議、プッシュトゥトーク(Push to Talk)システム(H.323 または SIP と組み合わせて)で一般的に使用され、IP 電話産業の技術基盤となっています。RTP プロトコルは RTP 制御プロトコル RTCP と共に使用され、ユーザーデータグラムプロトコル(UDP)上に構築されています。

RTP と RTCP#

  • データ転送プロトコル RTP は、リアルタイムでデータを転送するために使用されます。このプロトコルが提供する情報には、タイムスタンプ(同期用)、シーケンス番号(パケット損失と再順序検出用)、およびペイロード形式(データのエンコーディング形式を説明するため)が含まれます。

  • 制御プロトコル RTCP は、QoS フィードバックとメディアストリームの同期に使用されます。RTP に対して、RTCP が占める帯域幅は非常に小さく、通常は 5% です。

RTP の利点#

ストリーミングメディア転送、ビデオ監視、ビデオ会議、音声電話(VOIP)において、RTP プロトコルの適用は欠かせませんが、なぜストリーミングメディアの転送に RTP を使用する必要があるのでしょうか?なぜ RTP を使用しなければならないのでしょうか?

TCP のような信頼性のある転送プロトコルは、タイムアウトと再送メカニズムを通じて、転送データストリーム内の各ビットの正確性を保証しますが、これによりプロトコルの実装や転送プロセスが非常に複雑になります。また、転送中にデータが失われた場合、データ損失の検出(タイムアウト検出)と再送により、データストリームの転送が強制的に一時停止し、遅延が発生します。

RTP プロトコルは UDP ベースの転送プロトコルであり、RTP 自体はデータパケットを順序通りに送信するための信頼性のある転送メカニズムを提供せず、フロー制御や輻輳制御も提供しません。これらのサービスは RTCP に依存しています。このため、失われたデータパケットについては、タイムアウト検出による遅延が存在せず、破棄されたパケットについても、上位層がその重要性に基づいて選択的に再送することができます。

RTP のプロトコル階層#

ストリーミングメディアアーキテクチャ

ストリーミングメディアアプリケーションにおける典型的なプロトコルアーキテクチャ。

2022-06-29-22-46-30

図からわかるように、RTP はトランスポート層に分類され、UDP の上に構築されています。UDP プロトコルと同様に、リアルタイム転送機能を実現するために、RTP も固定のカプセル化形式を持っています。RTP はエンドツーエンドのリアルタイム転送にタイム情報とストリーム同期を提供しますが、サービス品質を保証するものではありません。サービス品質は RTCP によって提供されます。

RTP の動作メカニズム#

アプリケーションが RTP セッションを確立すると、アプリケーションは一対の宛先転送アドレスを決定します。宛先転送アドレスは、ネットワークアドレスと一対のポートで構成され、2 つのポートがあります:1 つは RTP パケット用、もう 1 つは RTCP パケット用で、RTP/RTCP データが正しく送信できるようにします。RTP データは偶数の UDP ポートに送信され、対応する制御信号 RTCP データは隣接する奇数の UDP ポート(偶数の UDP ポート + 1)に送信され、これにより UDP ポートペアが構成されます。RTP の送信プロセスは以下の通りで、受信プロセスは逆になります。

  1. RTP プロトコルは上位層からストリーミングメディア情報ストリーム(例:H.263)を受信し、RTP データパケットにカプセル化します;RTCP は上位層から制御情報を受信し、RTCP 制御パケットにカプセル化します。
  2. RTP は RTP データパケットを UDP ポートペアの偶数ポートに送信します;RTCP は RTCP 制御パケットを UDP ポートペアの奇数ポートに送信します。

RTP パケットには RTP データのみが含まれ、制御は RTCP プロトコルによって提供されます。RTP は 1025 から 65535 の間で未使用の偶数 UDP ポート番号を選択し、同じセッション内の RTCP は次の奇数 UDP ポート番号を使用します。ポート番号 5004 と 5005 はそれぞれ RTP と RTCP のデフォルトポート番号として使用されます。RTP パケットのヘッダ形式は図 2 のようになります。最初の 12 バイトは必須です。

2022-06-29-22-46-40

アプリケーション層#

RTP はアプリケーション層の一部であるべきです。アプリケーションの送信側では、開発者は RTP パケットをカプセル化するプログラムコードを記述し、その後 RTP パケットを UDP に渡す必要があります。受信側では、RTP パケットが UDP インターフェースを介してアプリケーション層に入った後、開発者が記述したプログラムコードを使用して RTP パケットからアプリケーションデータブロックを抽出する必要があります。

RTP メッセージ#

まず、RTP のパケットヘッダを見てみましょう。RTP メッセージヘッダ形式(RFC3550 Page12 を参照):

2022-06-29-22-47-13

  • バージョン番号(V):2 ビット、使用される RTP バージョンを示します。
  • パディングビット(P):1 ビット、このビットが 1 の場合、この RTP パケットの末尾には追加のパディングバイトが含まれます。
  • 拡張ビット(X):1 ビット、このビットが 1 の場合、RTP 固定ヘッダの後に拡張ヘッダが続きます。
  • CSRC カウンタ(CC):4 ビット、固定ヘッダの後に続く CSRC の数を含みます。
  • マーカー ビット(M):1 ビット、このビットの解釈は設定ドキュメント(Profile)によって行われます。RTP の最小制御プロファイルで音声およびビデオ会議で動作する音声ストリームの場合、マーカービットは 1 に設定され、静寂期間の後に送信された最初のデータパケットを示します。それ以外の場合は 0 に設定されます。
  • ペイロードタイプ(PayloadType):7 ビット、RTP ペイロードのタイプを識別します。
  • シーケンス番号(SN):16 ビット、RTP データパケットが送信されるたびにシーケンス番号が 1 増加します。受信側はこれを使用してパケット損失を検出し、パケットシーケンスを再構築できます。
  • タイムスタンプ(Timestamp):32 ビット、そのパケット内のデータの最初のバイトのサンプリング時刻を記録します。
  • 同期ソース識別子(SSRC):32 ビット、同期ソースは RTP パケットストリームの発信元を指します。同じ RTP セッション内で同じ SSRC 値を持つ 2 つのエンティティは存在できません。この識別子はランダムに選択され、RFC1889 では MD5 ランダムアルゴリズムが推奨されています。
  • 貢献ソースリスト(CSRC List):0~15 項、各項目は 32 ビットで、RTP ミキサーによって生成された新しいパケットに貢献するすべての RTP パケットのソースを示します。ミキサーはこれらの貢献 SSRC 識別子をリストに挿入します。SSRC 識別子はすべてリストされ、受信側が会話の両者の身元を正しく特定できるようにします。

RTP 拡張ヘッダ構造#

2022-06-29-22-47-30

RTP 固定ヘッダの拡張ビットが 1 の場合(注意:CSRC リストがある場合は、CSRC リストの後に続きます)、可変長のヘッダ拡張部分が RTP 固定ヘッダの後に追加されます。ヘッダ拡張には、拡張項目内の 32 ビットワードの数を示す 16 ビットの長さフィールドが含まれ、4 バイトの拡張ヘッダを除外します(したがって、ゼロは有効な値です)。

RTP 固定ヘッダの後には、1 つのヘッダ拡張のみが許可されます。複数の相互運用実装が異なるヘッダ拡張を独立して生成できるようにするため、または特定の実装が複数の異なるヘッダ拡張を持つ場合、拡張項目の最初の 16 ビットは識別子またはパラメータを識別するために使用されます。この 16 ビットの形式は、具体的な実装の上位プロトコルによって定義されます。基本的な RTP 説明は、ヘッダ拡張自体を定義していません。

RTP セッション#

アプリケーションが RTP セッションを確立すると、アプリケーションは一対の宛先転送アドレスを決定します。宛先転送アドレスは、ネットワークアドレスと一対のポートで構成され、2 つのポートがあります:1 つは RTP パケット用、もう 1 つは RTCP パケット用で、RTP/RTCP データが正しく送信できるようにします。RTP データは偶数の UDP ポートに送信され、対応する制御信号 RTCP データは隣接する奇数の UDP ポート(偶数の UDP ポート + 1)に送信され、これにより UDP ポートペアが構成されます。

RTP 送信プロセス#

  1. RTP プロトコルは上位層からストリーミングメディア情報ストリーム(例:H.263)を受信し、RTP データパケットにカプセル化します;RTCP は上位層から制御情報を受信し、RTCP 制御パケットにカプセル化します。
  2. RTP データパケットは UDP ポートペアの偶数ポートに送信され;RTCP は RTCP 制御パケットを UDP ポートペアの受信ポートに送信します。

RTP プロファイルメカニズム#

RTP は具体的なアプリケーションに非常に大きな柔軟性を提供し、転送プロトコルを具体的なアプリケーション環境や具体的な制御戦略から分離します。転送プロトコル自体はリアルタイム転送を完了するメカニズムを提供するだけで、開発者は異なるアプリケーション環境に応じて適切な設定環境や適切な制御戦略を自主的に選択できます。

ここで言う制御戦略とは、特定のアプリケーションニーズに基づいて特定の RTCP 制御アルゴリズムを実装できることを指します。たとえば、前述のパケット損失検出アルゴリズム、パケット損失の再送戦略、ビデオ会議アプリケーションにおける制御スキームなどです(これらの戦略については、今後の記事で説明するかもしれません)。

上記の適切な設定環境は、主に RTP の関連設定とペイロード形式の定義を指します。RTP プロトコルは、さまざまなマルチメディア形式(例:H.264、MPEG-4、MJPEG、MPEG)を広くサポートするために、プロトコル内に具体的なアプリケーション設定を反映させず、プロファイル設定ファイルおよびペイロードタイプ形式説明ファイルの形式で提供します。特定のアプリケーションに対して、RTP はプロファイルファイルおよび関連するペイロード形式説明を定義しています。

RTCP#

サービス品質の監視とフィードバック、メディア間の同期、およびマルチキャストグループ内のメンバーの識別。RTP セッション中、各参加者は定期的に RTCP パケットを送信します。RTCP パケットには、送信されたパケットの数、失われたパケットの数などの統計情報が含まれているため、各参加者はこれらの情報を利用して動的に転送速度を変更したり、ペイロードタイプを変更したりできます。RTP と RTCP は共に使用され、効果的なフィードバックと最小限のオーバーヘッドで転送効率を最適化できるため、特にオンラインでのリアルタイムデータの転送に適しています。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+-------------------------------+
|V=2|P|   IC    |       PT      |             Length            |
+---------------+---------------+-------------------------------+
|                                                               |
|                  Format-specific information                  |
|                                                               |
|                                       +-----------------------+
|                                       |    Padding if P = 1   |
+---------------------------------------+-----------------------+

各フィールドの意味は次のとおりです:

  • バージョン番号、固定で 2;
  • パディング(Padding)フラグ、1 はパディングがあることを示します;
  • エントリ数(Item Count、略称 IC)、RTCP パケットの内容がエントリリストである場合、エントリ数を示します。他の状況では別の意味を持つことがあります;
  • パケットタイプ(Packet Type、略称 PT)、rfc3550 では 5 種類の標準パケットタイプが定義されており、それぞれ sender report (SR)、receiver report (RR)、source description (SDES)、goodbye (BYE)、application-specific message (APP) です;
  • 長さ、パケットヘッダの後の内容の総長さ、単位は 4 バイトで、0 も許可されます;

RTCP パケットは単独で送信されることはなく、複合パケット(compound packets)としてパッケージ化されて送信されます。各複合パケットは、通常は UDP/IP パケットで送信される下位のパケットにカプセル化されます。複合パケットを暗号化する場合、RTCP パケットグループのプレフィックスは通常 32 ビットのランダム数です。複合パケットの構造は以下の図のようになります:

+---------------------------------------------------------------+
|                                                               |
|                          IP header                            |
|                                                               |
+---------------------------------------------------------------+
|                                                               |
|                          UDP header                           |
|                                                               |
+---------------------------------------------------------------+
|                  Random prefix (if encrypted)                 |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|V=2|P|   IC    |       PT      |             Length            |
+---------------+---------------+-------------------------------+
|                                                               | first
|                                                               | RTCP
|                  Format-specific information                  | packet
|                                                               |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|V=2|P|   IC    |       PT      |             Length            |
+---------------+---------------+-------------------------------+
|                                                               | second
|                                                               | RTCP
|                  Format-specific information                  | packet
|                                                               |
+---------------------------------------------------------------+

RTCP も UDP を使用して送信されますが、RTCP には制御情報のみがカプセル化されるため、パケットは非常に短く、複数の RTCP パケットを 1 つの UDP パケットにカプセル化できます。RTCP には次の 5 種類のパケットタイプがあります。

タイプ略称用途
200SR(Sender Report)送信者レポート
201RR(Receiver Report)受信者レポート
202SDES(Source Description Items)源点説明
203BYE転送終了
204.APP特定アプリ

上記の 5 種類のパケットのカプセル化は大同小異であり、以下では SR タイプのみを説明し、他のタイプについては RFC3550 を参照してください。

送信者レポートパケット SR(Sender Report)は、送信者がマルチキャスト方式で全受信者に送信状況を報告するために使用されます。SR パケットの主な内容には、対応する RTP ストリームの SSRC、RTP ストリーム内で最新に生成された RTP パケットのタイムスタンプと NTP、RTP ストリームに含まれるパケット数、RTP ストリームに含まれるバイト数が含まれます。SR パケットのカプセル化は以下のようになります:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|    RC   |   PT=SR=200   |             Length            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     SSRC of packet sender                     |
+---------------------------------------------------------------+
|                        NTP timestamp                          |
|                                                               |
+---------------------------------------------------------------+
|                        RTP timestamp                          |
+---------------------------------------------------------------+
|                    Sender's packet count                      |
+---------------------------------------------------------------+
|                    Sender's octet count                       |
+---------------------------------------------------------------+
|                   Receiver report block(s)                    |
|                                                               |
  • バージョン(V):RTP パケットヘッダフィールドと同様。
  • パディング(P):RTP パケットヘッダフィールドと同様。
  • 受信報告カウンタ(RC):5 ビット、この SR パケット内の受信報告ブロックの数で、ゼロも可能です。
  • パケットタイプ(PT):8 ビット、SR パケットは 200 です。
  • 長さフィールド(Length):16 ビット、この SR パケットの長さを 32 ビット単位で示します。
  • 同期ソース(SSRC):SR パケット送信者の同期ソース識別子。対応する RTP パケット内の SSRC と同じです。
  • NTP タイムスタンプ(Network time protocol):SR パケット送信時の絶対時間値。NTP の役割は異なる RTP メディアストリームを同期させることです。
  • RTP タイムスタンプ:NTP タイムスタンプに対応し、RTP データパケット内の RTP タイムスタンプと同じ単位とランダムな初期値を持ちます。
  • 送信者のパケット数:パケット送信開始からこの SR パケットが生成されるまでの間に送信者が送信した RTP パケットの総数。SSRC が変更されると、このフィールドはゼロになります。
  • 送信者のオクテット数:パケット送信開始からこの SR パケットが生成されるまでの間に送信者が送信したペイロードデータの総バイト数(ヘッダとパディングを除く)。送信者が SSRC を変更すると、このフィールドはゼロになります。
  • 同期ソース n の SSRC 識別子:この報告ブロックには、同期ソース n(SSRC_n)から受信したパケットの統計情報が含まれます。
  • 損失率 (Fraction Lost):前回の SR または RR パケット送信以来、同期ソース n(SSRC_n)からの RTP データパケットの損失率を示します。
  • 累積パケット損失数:SSRC_n からのパケット受信開始から SR を送信するまでの間に、SSRC_n から送信された RTP データパケットの損失総数。
  • 受信した最大シーケンス番号:SSRC_n から受信した RTP データパケットの中で最大のシーケンス番号。
  • 受信ジッター (Interarrival jitter):RTP データパケット受信時間の統計的分散推定。
  • 最後の SR タイムスタンプ (Last SR, LSR):最近 SSRC_n から受信した SR パケットの NTP タイムスタンプの中間 32 ビット。現在 SR パケットを受信していない場合、このフィールドはゼロになります。
  • 最後の SR 以来の遅延 (Delay since last SR, DLSR):最後に SSRC_n から受信した SR パケットからこの報告を送信するまでの遅延。

RTP タイムスタンプ#

タイムスタンプは、RTP パケット内のデータの最初のバイトのサンプリング時刻を反映し、セッション開始時のタイムスタンプ初期値もランダムに選択されます。信号が送信されていない場合でも、タイムスタンプの値は時間とともに増加し続けます。受信側はタイムスタンプを使用して、どのデータブロックをいつ復元すべきかを正確に知ることができ、転送中のジッターを排除します。タイムスタンプは、ビデオアプリケーションにおいて音声と画像を同期させるためにも使用されます。

RTP プロトコルではタイムスタンプの粒度は規定されておらず、ペイロードの種類によって異なります。たとえば、サンプリング周波数が 90000 HZ の場合、タイムスタンプの単位は 1/90000 です。もし 1 秒間に 30 フレームを送信する場合、タイムスタンプの増分は 90000/30 = 3000 です。

タイムスタンプの増分は、2 番目の RTP パケットが最初の RTP パケットから送信されるまでの時間間隔であり、ビデオの場合は各フレームの送信間隔時間になります。

コード#

RTP ヘッダ

/*
 * RTP header
 */
typedef struct 
{
#if 0   //BIG_ENDIA
    unsigned int version:2;   /* protocol version */
    unsigned int p:1;         /* padding flag */
    unsigned int x:1;         /* header extension flag */
    unsigned int cc:4;        /* CSRC count */
    unsigned int m:1;         /* marker bit */
    unsigned int pt:7;        /* payload type */
    unsigned int seq:16;      /* sequence number */

#else
    unsigned int cc:4;        /* CSRC count */
    unsigned int x:1;         /* header extension flag */
    unsigned int p:1;         /* padding flag */
    unsigned int version:2;   /* protocol version */
    unsigned int pt:7;        /* payload type */
    unsigned int m:1;         /* marker bit */
    unsigned int seq:16;      /* sequence number */
#endif
    u_int32 ts;               /* timestamp */
    u_int32 ssrc;             /* synchronization source */
    u_int32 csrc[1];          /* optional CSRC list */
} rtp_hdr_t;

RTCP 共通ヘッダ

/*
 * RTCP common header word
 */
typedef struct {
#if 0   //BIG_ENDIA
    unsigned int version:2;   /* protocol version */
    unsigned int p:1;         /* padding flag */
    unsigned int count:5;     /* varies by packet type */
#else
    unsigned int count:5;     /* varies by packet type */
    unsigned int p:1;         /* padding flag */
    unsigned int version:2;   /* protocol version */
#endif
    unsigned int pt:8;        /* RTCP packet type */
    unsigned short length;           /* pkt len in words, w/o this word */

} rtcp_common_t;
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。