要約

  • RFC 3016では、MPEG-4の構文単位をどのRTPパケットへ置くかが障害境界になった。集約はヘッダーを節約する一方、一個の損失で複数単位を同時に失わせた。
  • シーケンス番号、タイムスタンプ、マーカービットは輸送上の構造を示す。設定の保持、復号、表示、視聴を証明するものではない。

映像を「どこで切るか」は、最初は実装上の都合に見える。Path MTUに収め、ヘッダーを増やし過ぎず、送信処理が簡単ならよい。しかし損失が起きた瞬間、その切れ目は障害の境界になる。

2000年11月のRFC 3016は、MPEG-4 AudioとMPEG-4 VisualをMPEG-4 Systemsの同期・ストリーム管理を使わず、RTPへ直接載せる方式を定めた。H.323ならH.245、SIPやRTSPならMIMEとSDPが外側の管理を担える。MPEG-4も他のRTPコーデックと共通の仕組みで扱いやすくなった。

ただし、管理層を省くと責任まで消えるわけではない。設定をどこへ置くか、構文の開始点をどう保つか、どの単位を同じパケットに入れるかは送信実装が決める。その選択が、受信側で残る証拠を決めた。

切れ目は復旧の入口でもあった

MPEG-4 Visualにはコーデック内のエラー耐性機能があった。そのためRFC 3016は、媒体固有の追加RTPヘッダーを設けず、Visualビットストリームをバイト境界で直接payloadへ置いた。

直接配置には順序がある。設定情報やGroup_of_VideoObjectPlaneはpayload先頭、または構文上位のヘッダー直後に置く。複数のヘッダーがあれば、payloadは最上位のものから始める。ヘッダーを複数RTPパケットへ分断してはならない。

これは受信者が再び意味を読み始める位置を守る規則である。ヘッダーの半分ずつを別のデータグラムに入れると、どちらか一方の損失で両方の価値が消える。後続バイトが届いても、解釈の入口がない。

RFCは一個のvideo packetを一個のRTP packetへ入れ、結果がPath MTUを越えないよう調整することを推奨した。損失の多い経路では、VOPヘッダーを含むRTPが失われても、別のvideo packetはHeader Extension Codeを使って復号できる可能性が残る。

しかし小さな単位ではRTP/IPヘッダーの割合が大きい。複数を一個にまとめれば効率は上がる。RFC 3016は同時に、一個のRTP損失でまとめた全video packetが失われると説明した。

ヘッダーを二回減らす選択は、独立していた三個の運命を一個にする選択でもあった。

同じ二個のパケットでも損失結果は違った

禁止例では、二個の論理video packetを二個のRTP packetへ置く二つの並べ方が示された。適切な配置なら、二番目のRTPを失っても二番目の論理単位だけが消える。別の配置では一番目が境界をまたぎ、その残りの後ろに二番目のヘッダーがあるため、二番目のRTP損失で両方が消える。

送信パケット数も欠落数も同じである。違うのは依存の置き場所だけだ。

したがって、パケット損失率だけでは媒体損失を説明できない。欠落したパケットが独立フラグメントだったのか、複数単位の集合だったのか、再同期ヘッダーだったのかを知る必要がある。

coderがvideo packet機能を無効にした場合、VOPは任意のバイト位置で切れた。誤りがないと保証された経路なら固定長分割も使える。一方、損失のある環境では耐性が低い。規格上許される切り方でも、運用上の前提が変われば危険になる。

Markerは終端を示しても、成功を示さなかった

Visualでは、VOPの最後または唯一のRTP packetにmarkerを立てた。複数VOPを一つに入れた場合もmarkerは立ち、timestampは最初のVOP時刻を表した。残りの時刻は内部ヘッダーから求める。

この情報はdepacketizerに有用である。しかし受信証明ではない。marker付きパケット自身が失われることも、前のfragmentだけが失われることもある。組み立て完了後にdecoderが拒否することも、復号後にapplicationが表示しないこともある。

RTPの一般仕様でも、sequence numberは損失検出と順序復元に使え、timestampはsampling instantと同期計算を表す。実際のpresentationは受信側で後に起きる。markerの意味はpayload formatごとに定義される。「見えた」という共通ビットではない。

音声では前の設定が次のデータを支配した

MPEG-4 AudioはLATMのaudioMuxElementを使った。完全なelementまたはその一部をpayloadへ直接置き、先頭バイトをpayload先頭に合わせる。一個一パケットが推奨され、Path MTUを越える場合にはfragmentationを使えた。

in-band設定では、useSameStreamMuxが前フレームのStreamMuxConfigを再利用すると示せる。設定を毎回送らずに済む反面、前フレームが失われると、現在のelementが完全に届いても復号できない可能性がある。RFCはネットワーク状態に応じて設定を繰り返すよう推奨した。

繰り返し間隔は依存期間である。長ければ、一度の設定損失が多くの後続音声へ波及する。out-of-bandならSDPのconfigへ移せるが、今度は信令が正しい設定を届け、受信者が正しいstreamへ結び付ける必要がある。

切れ目の問題は空間だけでなく時間にも存在した。

能力と現在の設定は別だった

video/MP4V-ESとaudio/MP4A-LATMはMIMEとSDPへ登録された。Visualのprofile-level-idはcodecが扱えるProfile/Level能力を示せる。一方、configは該当bitstreamの設定であり、能力交換に使ってはならないとされた。

同じ能力を持つdecoderでも、現在の設定がなければ復号できない。二者が同じProfile/Levelを宣言しても、実際のstream parameterが一致するとは限らない。SDPは媒体表現の予定を記述するが、経路、到着、復号、表示を観測しない。

FECより前に保護対象の形が決まった

RFC 3016はRFC 2733のGeneric FECやRFC 2198の冗長音声を利用できるとした。ただしFECが受け取る時点で、source packetの中身は既に決まっている。三つをまとめたパケットを回復できれば三つ戻り、回復できなければ三つ消える。

ここがRFC 2733の記事との境界である。FECの記事はparityと回復条件、帯域・遅延を扱う。本稿はその前段、何を一つの保護単位にしたかを扱う。

RFC 2429のH.263+は別の設計を示す。追加payload headerにpicture header情報を写し、元のヘッダー損失後にも復号可能性を残した。RFC 3016はMPEG-4 Visual内部の耐性機能へ依存した。同じRTPでも復旧契約はcodecごとに違った。

後継RFCは番号だけでは分からない非互換を示した

RFC 6416は2011年にRFC 3016を廃止した。主な理由はMPEG-4 Audioと3GPP PSSの不整合であり、新しく必須となったLATM版は旧文書が参照した版とbinary互換ではなかった。StreamMuxConfig、SBR、Parametric Stereo、rate、channel、scalable layerのsignalも改められた。

一部の「RFC 3016実装」は既に新しいLATMを使い、厳密には旧RFCと異なるために後継RFCへ近い場合があった。RFC番号の自己申告だけでは、wire上の形式を特定できない。

後継文書でもVisualの教訓は残った。一単位一パケットは損失を隔離し、集約はoverheadと引き換えに一度の損失範囲を拡大した。

暗号化しても切れ目は移動しなかった

RFC 3016はRTPのsecurity considerationsを継承し、圧縮後の媒体を暗号化できるとした。完全なMPEG-4 Systemsが運べるMPEG-Jやscriptは、この音声・映像限定payloadでは運べない。

暗号化やintegrityは内容と送信元を守る。しかしPath MTUを変えず、失われた設定を再生せず、一個にまとめた論理単位を分離しない。本物で改ざんのないパケットでも、障害単位として大き過ぎることはある。

RFC 3016は普遍的な最小パケットを命じなかった。bitrate、loss、MTU、codec toolが経路ごとに違うからである。その代わり、構文境界を守り、選択の代償を明示した。

どこで切るかは、送信側の小さな判断に見えた。実際には、一度の損失から誰がどこまで回復できるかを決める判断だった。

情報源