鱒身(Masu_mi)のブログ

知った事をメモする場所。

RTPを少し調べた

GoRTPのサンプルコードを使って中身に目を通しつつ仕様を勉強していた。

とある会社に興味を持ったためにRTPに興味がでた直接のきっかけ。 もともと負荷分散とか低レイテンシ化を目指した脱TCPに興味があったので少し追ってみた。

使ってみた

検索して一番上に来ていたGoRTPを使った。 サンプルコードから読み始めるのが早い。 使ってキャプチャすると下のようになる。

../../../_images/capture-rtp-list.png
../../../_images/capture-rtcp.png

github.com/beatgammit/rtspも内部のRTP/RTCPを公開している(RTCPのハンドラは未実装だったりととても雑だった)。

参考にしたRFC

概要

用語が複雑なので整理してくれているInformationたち。

RFC7656 NOVEMBER 2015 A Taxonomy of Semantics and Mechanisms for Real-Time Transport Protocol (RTP) Sources
RFC7667 NOVEMBER 2015 RTP Topologies

仕様

リアルタイムアプリケーションに向けられたプロトコルで、通信品質が重要なうえTCPの外側でマルチキャストもサポートされるため関連する話題がとても多かった。

気づいた限りをざっと並べると、 ヘッダ圧縮、QoSのシグナリング、TCPとの共存(輻輳制御)、 マルチキャストのルーティング、パケットロス検知、パケットロス補間(音声・映像)、サンプルのインタリーブ、バッファリング、 符号訂正、多重化、クロック変更、ループ検知、セッション確立、 メディア同期、暗号化、SSRC衝突、などがあった。

プロトコルの基礎部分

代表的なプロファイルがRFC3551で定義されているがそのうちDIV4は望ましくないとしてRFC7007で取り除かれている。

RFC3550 JULY 2003 RTP: A Transport Protocol for Real-Time Applications
RFC3551 JULY 2003 RTP Profile for Audio and Video Conferences with Minimal Control

RTPペイロードの動的割付と多重化などの部分

SDPを使って動的に使い方を割り当てる部分に関して書かれているもの。 複数のRTP Streamを単一のRTPセッションに載せられるようになっている。 またRTP,RTCPを多重化して単一のポートで通信できるようになっている。

RFC3264 JUNE 2002 An Offer/Answer Model with Session Description Protocol (SDP)
RFC4566 JULY 2006 SDP: Session Description Protocol
RFC5761 APRIL 2010 Multiplexing RTP Data and Control Packets on a Single Port
RFC8035 NOVEMBER 2016 Session Description Protocol (SDP) Offer/Answer Clarifications for RTP/RTCP Multiplexing
RFC8108 MARCH 2017 Sending Multiple RTP Streams in a Single RTP Session

RTPの通信品質の制御などについて

RTPの輻輳制御はアプリケーションに任されている。 幾つかのアルゴリズムはあるがスタンダードが確立されてない。 また実装されてないことが多いためネットワークを溢れさせやすい。 最低限必要なcircuit breaker機構が以下で定義されている。

RFC8083 March 2017 Multimedia Congestion Control: Circuit Breakers for Unicast RTP Sessions

RTPプロトコルの概要

RTPは(主に)UDP上で動くストリーム型通信を提供するプロトコルです。 ストリーム型通信と一緒に求められる事が多いマルチキャストもサポートしています。 プロトコルの概念の紹介や説明はRFC7656にまとめられています。

またRTPで扱うデータストリームをRTPストリームと呼びます。 パケットはRTPパケットと呼ばれます。

RTCPはRTPと連携するプロトコルです。 RTPはメディアストリームの転送だけを担っており、RTCPが転送状況のレポーティングなどの周辺サービスを提供しています。 パケットはRTCPパケットと呼ばれます。

RTP ストリーミング配信を頑張る
RTCP ストリーミングの周辺サービスを提供

初期の仕様ではRTP,RTCPは分離されたチャンネル(IP/UDPでは別port)を利用するように設計されていました。 特にIP/UDP上ではRTP(偶数のポート番号),RTCP(RTPのポート番号+1)という制約がありました。 しかし最近はそのようなポート番号の縛りはありません。ただし後方互換製の問題もあるので特別の理由がなければ守るのが良いと思われます。

RTPの設計方針はApplication Level Framing(ALF) に基づいていて、 配信の詳細はアプリケーションが握りトランスポートレイヤは基本的な転送のみを行うべきという方針を取っています。 そのためRTP,RTCPはアプリケーションに対してストリーミングを提供するためのフレームワークを提供するに留まっています

RTPペイロードの具体的な解釈の仕方や使い方をプロファイルと呼びます。 代表的なプロファイルはRFC3551で定義されておりRFC3550と合わせてRTP/AVPと表示します。

構成

RTPパケット
RTP通信に使われているパケット SSRC, PTフィールドなどを持つ
RTPペイロード
RTPパケットで運ばれるデータ部分
RTPストリーム
配信されている連続メディア SSRCフィールドで識別される
SSRC
RTPストリームの識別子でランダムに作成される 衝突もあるので解消するアルゴリズムなどが定義されている
RTPセッション
RTPストリームが流れる論理単位 SSRCの名前空間 参加者からはエンドポイントで識別される
エンドポイント
RTPパケットの宛先トランスポートアドレス(RTP,RTCP)の組み合わせを指す
マルチメディアセッション
同一の目的を実現するために用いられている複数のRTPセッションを指す
RTCPパケット
BYE,SR,RR,SDESなど用途に対応したパケットが存在する 1つのUDPパケットに複数のRTCPパケットを載せる

RTPパケット

RFC3550からRTPヘッダを引用すると下になる。

The RTP header has the following format:

 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|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

一部にだけ言及する。

RTPパケットのデータ形式はPTフィールドで識別されます。 SSRCフィールドが一致してPTフィールドが異なるパケットを混在させるのは避けるべきです。 同一データストリーム(SSRCが一致)で複数のPTフィールドの値が混ざると複雑になるため。 (ただし途中で切り替えられる様にする拡張はあるようです)

RTPペイロードの形式の判別

PTフィールドの値から実際のデータ形式(スペック)への対応付は2つの方法があります。

  • プロファイル定義に従い静的に行う
  • 外部のプロトコル(多くの場合はSDP)を通して動的に行う

デフォルトプロファイルはRFC3551でこのプロファイルではdynamic用PTも定義されています。 また各データ形式はRFC3551や他のRFCで定義されています。

代表的な、動的な対応付けはSDP(RFC4566)のOffer/Answerモデルに従うことです。 一般的にはデフォルトプロファイルを用いてdynamic用PT(96-127)を任意のデータ形式に動的に割り当てます。

RFC5761で例に挙げられているSDPによるRTPセッションの記述を下に載せます。

v=0
o=csp 1153134164 1153134164 IN IP6 2001:DB8::211:24ff:fea3:7a2e
s=-
c=IN IP6 2001:DB8::211:24ff:fea3:7a2e
t=1153134164 1153137764
m=audio 49170 RTP/AVP 97
a=rtpmap:97 iLBC/8000
a=rtcp-mux

SDPの各パラメタは以下の様になっている。

v= Protocol Version: 0
o= Origin
c= Connection Data
t= Timing: <start-time>” “<stop-time:-:0:unbounded>
m= Media Description
a= Attributes

メディア記述(Media Description)の形式は下の通りです。

m=<media> <port>[/<number of ports>] <proto> <fmt> ...

fmtに利用するPTフィールドの値(97)が記載されている。またプロトコルはRTP/AVPが指定されているのでRFC3551を使うことがわかる。 アトリビュートでrtpmapを用いてPTフィールドの値(97)とデータ形式(iLBC/8000)を紐付けている。

またSDPを用いて動的にセッションを確立する場合、RTP,RTCPを多重化して同一ポートで通信できるように拡張されています。 これは複数ポートでの通信がNAPTなど中継器の管理コスト増加に繋がることへの対処を意図してRFC5761,RFC8108に記載されています。 利用にはセッション確立の際に合意することが必要(MUST)で失敗した場合は利用できません。 前述の例ではa=rtcp-muxがRTP,RTCP多重化を指定しているパラメタになります。

補足ですが、SDPでは通信路は定義されないためアプリケーションが任意の方法でセッション確立します。

RTCPパケット

RFC3550によって以下が定義されている。 RTP転送を邪魔しないようにビットレートや参加者数を用いてRTCPパケットの送信インターバルの計算方法が定義されている。

SR
送信者(参加者の一部)からの統計情報
RR
受信者(参加者の一部)からの統計情報
SDES
ソース定義: CNAMEでssrcと正規リソースを紐付ける
BYE
参加者がRTPセッションから抜けたことを明示するパケット (一定時間の通信がなければ勝手に他の参加者は気付く)
APP
アプリケーション拡張用

マルチメディアセッション

目的を共有して同時に維持されるRTPセッションの集まりを指します。

RTPでは同期ポリシーの異なるメディアは別の転送経路を利用する事が推奨されています。 これはメディアごとに同期ポリシーやネットワーク上での品質管理を最適化できることが望まれるためです。

そのためメディアごとにRTPセッションを分けるためアプリケーションは複数のRTPセッションで構築されることになります。

RTPセッション

RTPで通信する参加者の連携を指す論理的なグループです。 各ノード(参加者)は同時に複数のRTPセッションに参加できます。 RTPストリームの識別子であるSSRCの名前空間であり複数のRTPストリームを束ねたものになっています。

また各参加者は送信先エンドポイント(アドレス, RTP port, RTCP port)によってRTPセッションを識別します。

マルチキャストの場合は複数の参加者は同一の組を持つでしょう。 ユニキャストの場合はRTPセッションは各ペアごとに組みが異なります。 RTPでは複数の送信元から同一のポートで受信することが可能です。

例えば以下の場合はA,B,C,Rは同一セッションに含まれます。

A -(dst: addr(R), pR(R), pRC(R))-> R
B -(dst: addr(R), pR(R), pRC(R))-> R
C -(dst: addr(R), pR(R), pRC(R))-> R

SRCPの名前空間がRTPセッションなので、RからのRR(RTCP)が送信される範囲が同一セッションになります。

RTPでは下位トランスポートプロトコルを用いたストリームの識別などは推奨されていません。 またRTPではユニキャストであってもRTPセッションへの参加者は2人だと想定できません(トランスレータなどで中継されるからです)。 そのため送信元IPでセッションを分けることができず、同一エンドポイントに届くRTPパケットは同一RTPセッションになります。

また、上記のケースではRからA,B,Cへ同一のRR(RTCP)が送信されます。 RTPのトポロジはRFC7667で詳しく説明されている。

RTPストリーム

RTPセッション内で転送されるデータストリームをRTPストリームと呼ぶ。

一般にRTPセッション内は同じ形式のデータが流れることが望ましい。 複数人で会議をしているなど発生源が異なるRTPストリームはSSRCを用いて識別され同一RTPセッションに流されるのが一般的である。 ただしSSRCで識別するものの正規化して扱う際にはCNAMEを持ちいる。これはSSRCがランダムに採用されるためアプリケーションの再起動や他データソースとの衝突などでSSRCが変更されるためSSRCでは一貫性を保てないためである。

RTPストリームはミキサーによって合成される。その場合はSSRCとして別の番号が振られる。CSRCに元になったストリームのSSRCが最大15個記録される。

応用プロトコル

RTPは連続メディアの配信を提供するフレームワークなので他のプロトコルと連携して、よりアプリケーションに近いプロトコルを構成する。

RTSP(RFC7828)
非ブラウザ標準、IETFで標準化
SIP
セッション確立プロトコル
SRTP
DTLSを使って安全にしたRTP
WebRTC
ブラウザ標準P2Pプロトコル