Media over QuicTransport(MOQT)動向まとめ

IETFのサイトにMedia over QUICに関連するInternet-Draftやinterim Meetingの予定が纏まっている。

前回のinterim-meeting(vol.13)
2023/10/06
に開催された。
スライド・議事録はあるが録画は無し。
draft-ietf-moq-requirements-02
が 2023/09/29に発行。
- vol1との違いについて整理
-
Handling Scalable Video Codecs
セクションの追加- SVCの使う場合、拡張レイヤは前のベースレイヤだけでなく前の拡張レイヤにも依存する。あるオブジェクトを削除すると、依存関係にある全てのオブジェクトが使えなくなる。AV1のドキュメントでも、複雑な依存関係が図示されているため厄介な部分。
- 依存関係をオブジェクトのプロパティとしてエンコードし、その依存関係をクリアできる場合にのみデコードできるようにすることもできるが、relayが複雑になるため、
linear approach
が望ましいと考えている。(linear approachは、依存関係をグラフではなく線形で表すこと?)
-
Application choise for ordering
セクションの追加- アプリケーションは
frame rate first
かdefinition first
かを選択できる- フレームレート優先か画質優先か
- (感想) WebRTCでは、フレームレートと画質の優先度が厳密に決められなかったが、MOQTでは制御できるらしい。風景を流すか人物の映像を流すかアニメーションを流すかで求める形が異なると思われるので、この制御は素晴らしいが、アプリケーション側でこれを指示できるようにするのはちょっと大変そうだ
- 「最低でも720p@15fps、可能であれば30fpsを確保するようにし、その上でさらに利用可能な帯域幅があれば1080pで60fpsを目指す」といった、非常に高度な制御が可能。
- アプリケーションは
-
Linear ordering using priorities
セクションの追加- オブジェクト番号とオブジェクト優先順位の組み合わせを使って依存関係を表現する。(具体例あり)
- オブジェクト番号とオブジェクト優先順位はpublisherによって決定され、relay部分で変更はされない
- (感想) Internet Draftなのでどうなるかわからないが、MUSTになるのかな
-
Intervals and congestion
セクションの追加- オブジェクトの依存関係にはルールが仕様上設定される。このルールによってリレーや他ノードでのリアルタイムな輻輳制御が可能になる。
- 欠点は、drop priority(不要な場合にパケットを落とす) を持つパケットが実際にドロップされた場合、同じグループ内のシーケンス番号が大きく、drop priorityが高いか等しいオブジェクトを全て落とさなければいけなくなること
- (感想) SVCの時は特に依存関係が複雑なので、どのパケットを落とすかのdrop priorityはかなり綿密に決められてないとバグりそう。
-
Relay behavior
セクションの追加- 輻輳発生時に、relayはオブジェクトの優先順位を用いてオブジェクトをドロップさせる。relayが輻輳の発生を検知し、オブジェクトをドロップさせる方法を持っていることが前提となっている
- (感想1) WebRTCにおけるTURNではない。TURNはRTPパケットの中身を見て制御したりしないため
- (感想2) WebRTCにおけるSFUはSFU単体でオブジェクト選択してドロップさせたりはしていない(多分)ため、あくまで輻輳制御して流すパケット量を変更するのはpublisherなので、WebRTCにおけるSFUがこれをできるのであればかなり効率が良さそう。WebRTCではpub->SFU->subという都合上、pubが制御するのはpub <- SFU間のレイテンシ分遅延しそうだから。
- また、間のrelayのところでデータをキャッシュすることができると、再送要求の遅延が短くなるだろう。WebRTCはCDN的な、「ユーザーに近いところでキャッシュする仕組み」が存在しない。
- 前のグループのオブジェクトは、現在のグループのオブジェクトよりも重要度が低ければ、これをドロップしても良い
- 輻輳発生時に、relayはオブジェクトの優先順位を用いてオブジェクトをドロップさせる。relayが輻輳の発生を検知し、オブジェクトをドロップさせる方法を持っていることが前提となっている
-
High Loss Networks
セクションの追加- Web会議システムでは20%以上のパケロスがあるNWで利用されることも多い。この場合、audioは維持してvideoだけ流さないようにする仕組みがよく使われる。
- また、FECや再送などの仕組みによってパケロス耐性を得ることも多い
- 最近では3kbps程度の軽量な音声コーデック(Lyra等)が開発されている
-
interval between access points
セクションの追加- ストリーミングのユースケースでは、「アクセスポイント間の距離が短い」ことを特徴として、再同期が重要視されている。これにより、早送りや巻き戻しなどの機能に利用できる。
- (感想)ここでいう再同期は、キーフレーム(参照フレーム)を受け取らないと映像をデコードできないので、キーフレームを要求する仕組みが必要だということ。WebRTCでは会議への入室時などにキーフレーム要求が走る。
- 参照フレームはサイズが大きく、差分フレームは参照フレームよりもサイズが小さい。差分フレームは参照フレームに依存するような関係。このため、参照フレームを受け取るタイミングでトラフィックのピークが生じる。このピークは、ビデオ会議のようなユースケースよりも、ストリーミングのようなユースケースの方が吸収するのがはるかに簡単である。
- これが理由で、ビデオ会議では、より長いグループ(chromeでは参照フレームの後の差分フレームが30秒くらい続く)が使われている。
- ストリーミングのユースケースでは、「アクセスポイント間の距離が短い」ことを特徴として、再同期が重要視されている。これにより、早送りや巻き戻しなどの機能に利用できる。
-
Media Insection and Redirection
セクションの追加- 広告の挿入などでは、メディアのソースが別のものに切り替わったことを消費者に伝えたい(広告再生中であると消費者が分かるように)。
- メディアのソースが変わったらデコーダの初期化などが必要。なのでこれを消費者に伝える必要がある
- 広告の挿入などでは、メディアのソースが別のものに切り替わったことを消費者に伝えたい(広告再生中であると消費者が分かるように)。
-
Media Encription
セクションの修正
-
次回のinterim-meeting(vol.14)
2024/02/08,09
に開催予定。

ACM Mile-High Video 2024
flano_yukiさんのポストで知った。
2024/02/11~2024/02/14で開催される、映像配信技術のカンファレンスらしい。
Day3にはMOQT関連のセッションがある。
- Video Streaming 4: Low-Latency Media and Media over QUIC
- MoQ Goes to Kindergarten (Our Little Streaming Format Grows up)
- This is The Way: Prioritization in Media-over-QUIC Transport
- MOQTで議論されている「優先順位」の話。オブジェクトの依存関係が複雑になりそうなので、この辺りの議論は最近のMOQTで議論されている大きなトピックなのかも。
- Ultra-low Latency Video Delivery Over WebRTC Data Channels
- MOQTではなく、WebRTC DataChannelを利用した超低遅延配信のセッションっぽい。WebRTC SFUを多段に繋げてやるケースはよくあるが、その中でもDataChannelを使っているのは初めて聞いた。面白そう。
- Toward WebTransport Support in dash.js
- MOQTの普及には再生プレイヤーの対応も必要なので、こういった話がすでに進んでいるのは驚いた。結構普及が早いのかも知れない。

IETF公式のMedia Over QUICの概要
Media Over QUICの概要がIETFで公開された。
ユースケース
- ⭐️ライブストリーミング(映像配信など)
- これが一番重視しているユースケースのよう。Youtubeやtwitchなどの数秒~数十秒の遅延を1秒未満に削減することで、配信者と視聴者のインタラクションを強化する。
- リアルタイムコラボレーション(ビデオ会議など)
- 「遅延が低いビデオ会議サービスは、コスト効率の高い方法でスケールアウトすることができません」と書かれていることから、こちらも視野には入れているよう。
- 一方で、WebRTC事業者目線では、まだ遠いんじゃないかなという気がする。RTP Transport など、WebRTC側でも色々と変更が想定され、根本からWebRTC=>MoQへの乗り換えは大変そう。(技術遺産をMoQに載せ替える作業が必要)
- ゲーム(クラウドゲーミング?)
歴史的に重要な観点
いくつかの技術をまとめて一つのテクノロジーセットにするというモチベーションから、複数の技術のいいとこ取りを目指している。
- WebRTC(RTP)のリアルタイムメディアに関する知見
- HLS/DASH/HTTP CDNのスケーラビリティのアイデア
低遅延かつ高品質なプロトコルとして策定が進められている。
- WebRTCは低遅延だが高品質を維持するのが困難。また、スケーラビリティにも問題があり、一般的には数百が限界
- HLSは高品質だが低遅延で配信できない。
その他素晴らしい点
- MoQではメディアをEnd-to-Endで暗号化できる。さらに、暗号化した上で、キャッシュに必要な情報にはアクセスできるように設計されており、relayするサーバでパケットを取捨選択してキャッシュしたり、輻輳制御の結果ドロップしてエンドユーザーに配信することができる。
- MoQはユースケースによって柔軟なカスタマイズが可能である。「フレームレートと画質のどちらを優先するのか」「映像と音声のどちらを優先するのか」「レイテンシと品質のどちらを優先するのか」を選択できる。WebRTCやHLSではこの制御が難しい。
- (感想)「どういった制御をするべきなのか」はユースケースによって異なるため、正しくアプリケーション側で定義するのはそれなりに難しそうだ
気になった点
MOQTがWebRTCやHLSの次の技術であることはわかっていたが、他の市場にも影響を与える可能性が記載されている。
ジェニングス氏は、MoQ はメディア配信を改善するために設計されていますが、それによってさらに多くのことが可能になり、他の市場に利益をもたらすだろうと述べています。
「MoQ は実際には、メディアの配信以上のことを可能にする非常に汎用的なメカニズムです」と彼は説明します。「MoQ を使用すると、低遅延、高ファンアウト、高スケーラビリティで機能するパブリッシャー/サブスクライバー ネットワークをインターネット上に構築でき、これは多くのアプリケーションに使用できます。」
- IoT
- プッシュ通知
- 5Gネットワーク
- テキストメッセージングプロトコル
- (感想) 確かに、WebRTCやWebSocketでも実現可能だが、ビデオ会議システムでは映像・音声はWebRTC、テキストはWebSocketというのが一般的である。ここが面倒なところではあるので、この辺りも含めて一つのプロトコルに統合するというのは革新的。Next WebSocketの側面はあまり聞かなくなっているが、今でも視野の中には入っていそう。
今後の動きで面白そうな点
- 2024/02/06にMOQTのhackathonが予定されており、相互接続試験が行われる予定
- (参加したかった・・・)

ゲーム業界におけるリアルタイム通信プロトコルについて
調べた動機
ゲーム業界でリアルタイム通信プロトコルといえば独自UDPだと思うが、MOQTおよびWebTransportってどうなのだろう?
以前、MIXIさんがWebTransportに独自RTPを載せて運用されていたことがあったので、それに関連して気になった
ゲーム業界においてWebTransportはどうなのか
- QUICならまだしも、WebTransportだとオーバースペック
- WebTransportが乗っかることによるオーバーヘッドもある可能性
- WebTransportはWebブラウザでも動くように設計されているが、ゲームにおいてはサーバーもクライアントも自前で実装できるので、無理にこの仕様に沿う必要がない
- 一方で、メリットもある
- TCP/UDPライクなユースケースに両対応できて、UDPが通らない(QUICが通らない)環境でもTCPでなんとか通信が可能
- (感想) 標準化された技術に乗っかると、オレオレUDPとか作った時にISPでブロックされたりしないとかもありそう。
- ロードバランサーがHTTP3等に対応する可能性が高いため、ロードバランサーで問題が発生する可能性が低い
- TCP/UDPライクなユースケースに両対応できて、UDPが通らない(QUICが通らない)環境でもTCPでなんとか通信が可能
感想
- P2Pで通信したいとなるとWebTransportでは足りなさそうなので、P2Pのためには他の方法を考える必要がある。これは確かに大変そうだ。
- WebTransportはサバクラが先行して策定されていて、p2p-webtransportという単語もあるにはあるが、Web業界的には当分(5年くらい?)サバクラはWebTransport、P2PはWebRTCで棲み分けというのが予想される。
- P2Pとサバクラ両対応なWebRTCでは何が足りないのだろう?
- MIXIさんでも以前WebRTC SFUを使って音声通信を提供されていたようだが、WebTransportの検証に踏み切った理由はスライドからは把握できなかった。
- なんとなく、以下の理由を想像してみた。
- 数百以上の音声通信をWebRTCでやるのは結構大変だから
- WebRTCはウェブ会議に特化した処理になっていて、ゲーム業界むけのカスタマイズをするのが難しい(libwebrtcに手を入れなければならない)
- QUICだとコネクションマイグレーション(接続がwifi -> テザリングに変わっても繋がる)ができる(WebRTCはできない)
- こちらのスライドでは、「ゲームは小さいサイズのデータを高頻度で送るため、従来の暗号化では無駄が多い」と書かれていたので、この辺りも関係しているのかも。

Media Over QUICTransportのプロトコルスタック
引用: https://datatracker.ietf.org/meeting/interim-2023-moq-08/session/moq
- プロトコルスタックとしてはQUIC上に構築される。
- WebTransportも含まれる。WebTransportは省略して、QUICの上に直接構築するのも許容される
- 既存のライブラリを読むと、サーバー側はWebTransportとRAW QUICの両方に対応するようになっている
- WebTransportも含まれる。WebTransportは省略して、QUICの上に直接構築するのも許容される
- MOQTはあくまで制御やペイロードの定義のみであって、ペイロードの中身のメディアフォーマットについては定義していない。
- MOQTの上にWARPやLOC(Low Overhead Media Container)を乗せることを前提にしており、ペイロードフォーマットはこちらの仕様によって決定される。
- WARPはCMAFというファイルフォーマットを前提に設計されている
- CMAFはHLSやMPEG-DASHなどで利用されている仕様
- LOCはWebブラウザのWebCodecs APIのフォーマットをそのまま流す前提に設計されている
- (感想)テキストや3Dデータを流す話もあるらしく、その点ではここの仕様が乱立する可能性がありそう。
- WARPはCMAFというファイルフォーマットを前提に設計されている
- MOQTの上にWARPやLOC(Low Overhead Media Container)を乗せることを前提にしており、ペイロードフォーマットはこちらの仕様によって決定される。
感想
MOQTの上に乗せるメディアフォーマットとしては、LOCの方がWebRTCからの乗り換えにおいては楽かもしれない。一方で、HLSやMPEG-DASHからの乗り換えではWARPの方が楽そう
参照

2024/02/08,09のIETF interim-meetingの1日目まとめ
2日(4回)に分けてMTGが行われた。実際に使われたスライドは01,02の内容のみ。これを二日にかけて議論した模様。
注意事項
こちらのコメントで利用している画像は全て以下のスライドから引用しています
moqt-draft 02における相互接続試験の結果
- draft02への追従はまだ追いついていないようだ。(02は2024/01/24発行のため当然ではある) AlanさんとMartinさんの実装以外は成功していない。
- 01の相互接続試験結果
- 02の相互接続試験結果
- 01の相互接続試験結果
MoQTのissueについての議論
issueはこちらのGithubに挙げられ議論される。
issueの細かい話については把握しきれていないので割愛。以下サマリ
- SUBSCRIBEメッセージにERROR/FIN/RSTがあるが、他にも
TRACK_OVER
とか必要なのでは?また、FINとRSTは同一なのでは?統合してメッセージ減らす余地もあるかもしれない - オブジェクトが全く送信/作成されなかったときに、SUBSCRIBE_FIN/RSTでどうやって表現する?現状表現方法がないので新たなフラグ等が必要になる。
- group N の全てをsubscribeするときにどうやって指示する?
- https://github.com/moq-wg/moq-transport/issues/312
- groupは映像や音声の塊のことで、映像ではkeyframeから最後のdeltaframeまでを指す
Rapid Recoveryについて
有線からwifiに突然切り替えた時に、高速に復旧させる処理
- Receiver側の場合の処理
- こちらは仕様の変更をせずとも実現可能。
- Receiverが切り替わり、QUICコネクションが切断され、Consumerが0人になった場合でも、relayは多少の時間維持するため、復旧可能
- Publisher側の場合の処理
- こちらは仕様の変更が必要。
- Producerが切り替わった場合、QUICコネクションが切断される前にANNOUNCEメッセージがRelayに送られ、このタイミングで同じ名前のTrackが生成されてしまう。同じ名前のTrackが生成されたタイミングで、既存のTrackと新規のTrackのSUBSCRIBEメッセージをPublisherが受け取るようにしたい
そのほかの複数の切り替えシナリオについても議論されている
- QUICのコネクションマイグレーションで再接続はできるのでは?という話
- 議事録の中で、「QUICのコネクションマイグレーション使えば?」「WebTransportはQUICを前提としていない」というやりとりがあった。
- 恐らく、WebTransportはQUICが通らない時のためにover HTTP2も想定しているので、フォールバックした時のことも考えるとQUICのコネクションマイグレーションを前提とした仕様にはできないということなのだろう。
Common Catalog Format
MOQTではOBJECTメッセージがメディアをペイロードとして含めて送受信されますが、ペイロードの仕様については定義しておらず、LOCやWarpなどの仕様によって定義されます。これらの仕様を統合するのがCommon Catalog Formatです。
Common Catalog Formatの概要についてはこちらをどうぞ。
Common Catalog FormatのissueはGithubに挙げられ、議論される。
こちらもPRやissueの議論がメインなので、抜粋して紹介。
- JSONの形式として、JSON Patch(RFC6902)とJSON Merge Patch(RFC7396) のどちらをサポートするか議論になっていたが、 JSON Patch(RFC6902) の対応で合意が取れた
- Catalogのtrack nameが継承できるようになった。
-
commonTrackProperties
プロパティをrootに追加し、継承するプロパティを毎回付与しなくても良いようにする仕様の提案 - DRMを必要とするフォーマットに対してDRMデータを伝送するために、現在のカスタマイズメカニズムは十分か?
- IETF118(2023/11)でCENC DRM情報を付与するためのフィールドが提案されたが、特定の技術に特化しすぎているとして却下された。
- 対案として、DRM情報を伝送するためにカスタムフィールドに好きにフィールドを追加して良いという仕様が提案されている
Live Edge, Expiry Edge & Gaps
ここについては理解が追いついていないため大雑把に要約。
- Groupの中の各Objectの有効期限が異なる場合に、どのような処理をするべきかについて議論?
- 複数Relayがあったときに、Clientが複数のrelayにリクエストを送ると、レスポンスに含まれるlatestなObjectの値がそれぞれ異なる可能性がある件について議論?
- relayからrelayに最新Group/Objectの情報が伝播するまでに時間がかかるためこの問題が発生する?
- 最新Objectがどれかクライアント側でわかったとして、それをリクエストした時に別のrelayにアクセスしてしまったら情報が共有されておらずエラーになるみたいな話かな・・・
- sliding DVR windowを導入する方法が挙げられている
- ex) Objectナンバーが15以前はexpireしていて、15-20がCurren Group, 21-25がFuture Groupの場合に、13-21のObjectのsubscribe要求が来たらどうするか?など
この辺りの解消のためにsubscription APIをSUBSCRIBEとFETCHの二つの仕様に分けることが提案されている
WARP Draftのアップデートについて
WARPについてはflano_yukiさんのこちらの記事をどうぞ
MOQTの上に乗せるフォーマットのことで、以下のようなプロトコルスタックになります。
- IETF117での内容の再掲
- WARPを再利用可能なコンポーネントに分解する。
- (感想)WARPってCMAF前提かと思っていたけど、これを見るとLOCにも対応していそう。となるとLOCとの違いはなんだ?(最新のドラフトちゃんと読まないと分からなさそう)
- WARPを再利用可能なコンポーネントに分解する。
- ドラフト・実装の変更点
- CMAFをRFCの中で参照する場合にどうすれば良いのかという相談
- CMAFはMPEGによって作成された仕様(ISO標準)だが参照して良いのか(HLSは参照しているか良い?)
- (感想)CMAFの仕様書は有料?だから、こういう話が出てるのかも?
- CMAFはMPEGによって作成された仕様(ISO標準)だが参照して良いのか(HLSは参照しているか良い?)
- 重要なissue
- Seeking&DVR: リアルタイムとVODの二つの要素をWARPは兼ねているので、シークバーも使えないと行けない
- Bitrate Adaption: 可変アダプティブビットレートの実現方法
- Adverting Insertion: 広告挿入の実現方法
分散AdaptiveBitRateについて
MOQTでは、Publisher -> Relay1 -> (Relay2) -> Consumer(Client)という流れでデータが流れていくため、どの区間で品質を計測してbitrateを調整するべきなのか?という議論が出てくる。
シンプルにはfinal hopだけやるのが考えられる。
以下の画像の下の構成図のように、final hop以外でもAdaptive Bitrateを実現したい場合には、SUBSCRIBEメッセージを拡張してあげる必要がある
- (感想) 確かに、relay1とrelay2の間の帯域幅が何かしらの原因で圧迫される可能性はある。(例えばUS->EUへの転送など) なので、final hopだけのABRでは上手くいかないかもしれない。
- ここで書かれているABR、サイマルキャスト的な意味で使われていることに注意。複数画質をrelayに送信し、帯域幅によってどの画質を転送するかを決めている。
-
Publisher produces multiple copies of the content at different bitrates
and quality levels.
-
- ここで書かれているABR、サイマルキャスト的な意味で使われていることに注意。複数画質をrelayに送信し、帯域幅によってどの画質を転送するかを決めている。
Content Protetion
ネットワークレイヤーではQUICがTLS/DTLS相当のセキュリティを担保しているが、DRMやE2EE(End-to-End Encription)をどうやって実現するかについての議論。
Encryptionレイヤーの追加
現時点では、EncoderとPacketizer、DecoderとPacketizerの間に新たにEncryptionレイヤーを作成してそこで暗号化することを想定。鍵はライセンスサーバを経由してやり取りを行う。
ecription
プロパティの追加
Encriptionレイヤーを追加するにあたって、CatalogとTrackの両方に encription
プロパティを追加することを提案。
画像にある cenc
は Common Encryption
のことで、MPEG-DASHのDRMで使用されている暗号技術。
ここでは複数の暗号技術を選択できると思われる。
KeyMap
どのgroupがどの復号鍵を使う必要があるかを keyMap
で表現する。暗号化されていないgroupは-1で通知される。
- この仕組みによって、鍵は動的に入れ替えることが可能。
“keyMap”: [
[10, 0], // groups 10 to 19 are encrypted with keys[id=0]
[20, -1], // groups 20 to 24 are unencrypted (an inserted ad)
[25, 1], // groups 25 to 49 are encrypted with keys[id=1]
[50, 2] // groups from 50 onward are encrypted with keys[id=2]
]
Note: groups
感想
- 議論内容がかなり多い。参加者 を見ても、Google/Cisco/Meta/Tencentなど、配信事業をやっている会社の方が参加している(合計33人)。盛り上がっているのかも?
- jitsiの方が参加しているのも見えた。Web会議的な観点ではまだまだ遠いような気がするが、どうだろう・・・
- ところでMOQTとMoQT、WAPRとWarpは正式名称はどれなんだろう?

draft01から05の変更点
ちゃんと把握しているのが01なので、01から05で変わっていそうなところを整理する
3. Termination
エラーが起きてQUIC/WebTransportコネクションが削除される際のエラーコードが増えた。 Parameter Length Mismatch
などは、とりあえず0x1 Generic Errorとかで実装していたが、これによってエラーの理由が明確になった。
Code | draft-01 | draft-05 |
---|---|---|
0x0 | No Error | No Error |
0x1 | Generic Error | Internal Error |
0x2 | Unauthorized | Unauthorized |
0x3 | Protocol Violation | Protocol Violation |
0x4 | - | Duplicate Track Alias |
0x5 | - | Parameter Length Mismatch |
0x10 | GOAWAY Timeout | GOAWAY Timeout |
4. Priorities
draft-01ではコンセンサスが取れておらず、TODO状態になっていたが、draft-05ではそれなりに定まっている。
- DataPlane相当のOBJECT / OBJECT_WITHOUT_LENGTHメッセージを除いたControlメッセージは、全てのOBJECT系メッセージよりも優先されるべきである [SHOULD]
- PublisherとSubscriber両方に優先順位をつけることができ、複数のSubscriberの優先度が同じ場合には、Publisherの優先度を元に優先順位が決定する。PublisherもSubscriberも優先度が同じ場合には実装によって挙動は異なる
- Subscriberの優先度は
SUBSCRIBE_UPDATE
メッセージによって変更することができる - Subscriptionは複数のグループが送信可能な場合はgroup idの数値の昇順・降順の順番で送られるべきである [SHOULD]
- どちらを選ぶかは
SUBSCRIBE
メッセージで指定する
- どちらを選ぶかは
- 同じgruop内のObjectはIDが低い数値のものから優先的に送信する。
5. Relays
draft-01では SUBSCRIBE_ERROR
SUBSCRIBE_DONE
メッセージのステータスコードが厳密に定義されていなかったこともあり、draft-05ではそこの詳細化が行われている。
SUBSCRIBE_ERROR
のステータスコードが追加
Code | Reasion |
---|---|
0x0 | Internal Error |
0x1 | Invalid Range |
0x2 | Retry Track Alias |
SUBSCRIBE_DONE
のステータスコードが追加
Code | Reasion |
---|---|
0x0 | Unsubscribed |
0x1 | Internal Error |
0x2 | Unauthorized |
0x3 | Track Ended |
0x4 | Subscription Ended |
0x5 | Going Away |
0x6 | Expired |
また、以前はRelayサーバー周りの挙動についてあまり書かれていなかったが、 UNANNOUNCE
ANNOUNCE_CANCEL
メッセージが追加されたことでこれらを扱うフローについて追記された。
- PublisherがANNOUNCEしたものに対する新しいSubscriptionを停止したい時、
UNANNOUNCE
を送る - Subscriber(ここではrelayを指す?)は
ANNOUNCE_CANCEL
メッセージを送ることで、以前ANNOUNCE_OK
と応答した ものに対する Subscriptionを新たに中継しないことを示す。
UNANNOUNCE
メッセージに対する relayサーバーの返答が ANNOUNCE_CANCEL
メッセージになるというわけではなく、独立したメッセージっぽい。
6. Message
MOQTメッセージの種類がかなり増えた。また、各種メッセージが持つプロパティの名前が変更されたり移動したりしている。特に、SUBSCRIBE
や OBJECT
周りの変更点が多く、draft01ではメディア処理についてあまり考えられていなかったのが、version4つ分の検討によってかなり進んだ印象。
Code | draft-01 | draft-05 |
---|---|---|
0x0 | OBJECT_STREAM | |
0x1 | - | OBJECT_DATAGRAM |
0x2 | SUBSCRIBE_UPDATE | |
0x3 | SUBSCRIBE | SUBSCRIBE |
0x4 | SUBSCRIBE_OK | SUBSCRIBE_OK |
0x5 | SUBSCRIBE_ERROR | SUBSCRIBE_ERROR |
0x6 | ANNOUNCE | ANNOUNCE |
0x7 | ANNOUNCE_OK | ANNOUNCE_OK |
0x8 | ANNOUNCE_ERROR | ANNOUNCE_ERROR |
0x9 | UNANNOUNCE | UNANNOUNCE |
0xA | UNSUBSCRIBE | UNSUBSCRIBE |
0xB | SUBSCRIBE_DONE | |
0xC | ANNOUNCE_CANCEL | |
0xD | - | TRACK_STATUS_REQUEST |
0xE | - | TRACK_STATUS |
0x10 | GOAWAY | GOAWAY |
0x40 | CLIENT_SETUP | CLIENT_SETUP |
0x41 | SERVER_SETUP | SERVER_SETUP |
0x50 | - | STREAM_HEADER_TRACK |
0x51 | - | STREAM_HEADER_GROUP |

Githubで議論されている最近ホットそうなissue
-
Object/group TTL: https://github.com/moq-wg/moq-transport/issues/249
- https://github.com/moq-wg/moq-transport/issues/440 も関連issue
- 映像の場合、Keyframe/Deltaframeで依存性があるため、それを適切にキャッシュするにはどうするべきかという議論らしい。
- HLSのようにキャッシュをうまく使うのがMOQTには求められているため、この辺りは重要な議論になりそう(QUICやHTTP CDN周りの話も出てきていてあまり理解できていない・・・)
-
Adaptive Bit Rateの実現方法: https://github.com/moq-wg/moq-transport/issues/259
- WebRTCのように、送信側でABRをやるのがリアルタイム通信においては良いが、HLS/DASHは送信側ABRと受信側ABRを組み合わせて使っている。
- WebRTCはGCCを使っているが、このアルゴリズムは古く、ツギハギして作られているため理解するのが難しい&理解している人がかなり少ない
- 受信側ABRは色々な研究がなされており、2024ACM MMSysでも
Grand Challenge on Offline Reinforcement Learning for Bandwidth Estimation in Real Time Communications
というコンペが行われるらしい。 - Lukeさんの意見では、第三の方法としての Server-side ABRのよう。(一部反対意見もあり)
- QUICの輻輳制御は固定されているので、QUIC WGとも協調して議論していく必要がある?
-
FECの実現方法: https://github.com/moq-wg/moq-transport/issues/320
- QUICは複数のデータグラムを結合することがあるため、FECのように、1パケットごとに個別の処理を行う形だと、MOQT上でFECが実装できない。
- QUICがデータグラムを結合しないように要求するか、QUICレイヤーでFECを導入してもらう必要があり、今後どうするか・・・
- 議論は既にしており、こちらのドラフトが解決策の一つ
- QUICはCDN企業の多くが参加して設計しているが、MOQTのWGにはakamaiの方も参加していて、CDN企業と近い場所で議論が出来ているのは素晴らしいなと思った。

moq-transforkについて
このドラフト自体はmoq-transport draft-03から派生して書かれたもので、現在仕様策定が進んでいるmoq-transportに対して、大きく変更を加えたものである。
MOQTはQUICに依存しているため、QUICがサポートしていないことは実現できない。それによって、重要なプロパティが未定義になっており、MOQTには欠陥が残っているというのが、このmoq-transforkのドラフトを書いた理由のようだ。
派生したドラフトとはいえ、完全に別個の実装を新たに作りたいわけではなく、ここで記述した内容はMOQTWGに持ち込まれ、Github issueで議論されているものもある。
なので、もしかしたらdraft 04,05でmoq-transforkの内容が一部含まれているかも。
Objectモデル
MOQTにおいてはメディアの概念とObjectモデルが対応しており、グループはVideoのGoP(I/P/Bフレームをまとめたgroup of picture)、オブジェクトはVideoフレームに相当する。
しかし、QUICとマッピングされた概念ではなく、動的にQUICストリームのプロパティが色々なトラック・グループ・オブジェクト間で移動してしまう(?)ので、すぐに管理不能になるだろうと指摘している。
おそらくは、Lukeさんが想定したよりも仕様が複雑になってしまっているのだろう。
MoqTransforkでは、ObjectモデルはQUICに直接マッピングされた概念であるため、この管理が楽になる(らしい)
Priority
MOQTにおいては、送信側が優先順位を決定する。(これはLukeさん自身が間違ったアプローチを提案したと書かれている)
より良い方法として、送信側・受信側が協調して決定する必要がある。
MoqTransforkでは、優先順位の決定をsubscriberに移譲する。
Control Streams
MOQTにおいては、ANNOUNCEなどの制御メッセージは一つのストリームを共有する仕様になっているため、HoLBの可能性がある。
MoqTransforkでは、サブスクリプションごとに一つのストリームを使い、たくさんの制御メッセージを送ってもHoLBが起きないようにする。また、これによってQUICのステートをそのまま扱うようになり、UNANNOUNCEやUNSUBSCRIBE、SUBSCRIBE_DONE, SUBSCRIBE_ERROR, SUBSCRIBE_RESETなどのメッセージは消せるようになる。
Byte Offsets
MOQTにおいては、接続やSubscriptionが中断された場合、中断されたところから再開するために、グループのObject IDを使っている。しかし、オブジェクトの一部分は再度ダウンロードされることによって、キャッシュが断片化される(?)問題がある。
MoqTransforkでは、FETCHメッセージを使い、Byte Offsetsで始まる不完全なグループを提供する(ちょっと理解が及ばなかった)。
Datagrams
MOQTにおいては、送信者のpublisher track preferenceを通して、QUICのdatagramでOBJECTメッセージを送ることをサポートしているが、これは高レイテンシでも構わないユーザーは体験が悪い
MoqTransforkでは、subscriberがQUICのStreamとDatagramのどちらで受け取りたいかを選べるようにする。DatagramはGroupがMTUより小さく、希望するレイテンシがRTTより少ない時にのみ使用されるべきである。
これによって、Streamのオーバーヘッドを削減しながら再生できる。
おそらく、Datagramはドロップするが、Streamは再送されるため、高レイテンシでも構わないならStream使って、特定の場合だけDatagramを選択しろよってことなのだろう。
Use-Cases
MOQTにおいてはユースケースが曖昧になっており、そのせいで不必要な機能が生じている。
MoqTransforkにおいては、Appendixとしてユースケースを明示し、それに推奨されるアプローチを明記している。

Common Catalog Format draft00と01の変更点
Catalog Formatについてはこちらの記事がおすすめ
そこまで大きく変更点はない。
- Common Catalog FormatはJSONで各種パラメータを設定するが、そのパラメータの位置が明示されるようになっている。
- 各種パラメータ値の型が決定されている。
- 3.2.12 Track operationsが削除されている。
- 以前はAdd/Deleteプロパティがあり、SUBSCRIBE可能かどうかを表現していた。
- おそらくだが、MOQT draft-05を読むと
TRACK_STATUS
メッセージなどもあるので、Common Catalog FormatからMOQTに責任が移ったのだろう。

IETF119で話されてた内容から面白かったもの
- LOCのモチベーション
- CMAFはフレームごとに100bytes以上のオーバーヘッドが存在する。audioの場合は100%以上のオーバーヘッドとなる
- CMAFはheaderや複数フレームをパッケージング(chunks/fragments/segments)する時に複雑
- parseする必要なく、フレーム境界がわかる仕様が欲しい

IETF121の変更点についてはこっちのスライドでまとめている

IETF MoQ 中間MTG #7 (2025/2/5実施) のまとめ
参加者
- Martin Duke (Google)
- Will Law (Akamai)
- Magnus Westerlund (Ericsson)
- Suhas Nandakumar (Cisco)
- Mo Zanaty (Cisco)
- Cullen Jennings ( Cisco )
- Mike English
- Gwendal Simon (Synamedia)
- Ian Swett (Google)
- Daniel Fay (Meta)
- Giovanni Marzot (Vivoh/MarzResearch)
- Mirja Kühlewind (Ericsson)
- Mathis Engelbart (TUM)
概要
- Extensible Object Header が主。
Extensible Object Headerとは
MoQTのOBJECTメッセージに拡張可能なHeaderを追加するために、SETUPメッセージでネゴシエーションを行うもの。HTTPでも同様の機能がある。
この拡張されたHeaderは、Objectに情報を付与することで、リレーサーバーで動作を変更させることができる。例えば、End SubscriberにObjectを送るEdge Relayにおいて、広告を差し込むためにEdge Relayで動作を変更させるような場合に、拡張Headerを使ってその情報を表現する。
つまり、End Subscriberが扱うような、Object Payloadの中身に関するようなmetadataを表現するためのものではない。中間relayサーバーのための情報という側面が強い
この拡張Headerの内容は、WARPやLOCなどの、MoQ Transportの仕様とは別の枠で定義される。
LoCのドラフト でも、LoCのHeader ExtensionはMoQ Header Extensionsに入れる前提で定義されている。
ただ、LoCのドラフトでは
This metadata provides necessary information for end subscribers, relays and other intermediaries to perform their operations without accessing the media payload.
と書かれており、relayのための情報ではなく、End Subscriberのための情報も含まれると書かれている。仕様が書かれたタイミング(2024/10)と中間MTGのタイミング(2025/02)でズレているので、仕様が変更されている可能性はあるが、現時点では齟齬がありそうだ。
また、Capture TimestampなどのLoC Header Extensionsは、機密情報となる場合もあるため、End to Endで暗号化が必要なのでは無いかという点についてもLoCのドラフトでは記載されている。ここについても中間MTGで話している内容とは齟齬がありそうだ。ここも変更される可能性が高い。
議論になっている点
- Object Payloadへその情報を埋め込むのではなくObject HeaderにExtensible Headerとして追加するのは何故か
- リレーがこのHeaderを見て動作を変更したいが、Object Payloadの中身にアクセスできるとは限らないため。E2EEされている場合もある。
- なぜ 事前に仕様に定義せず、Extensible Headerとして定義するのか
- 仕様からこれを切り離すことで、仕様の肥大化を防ぐ
- 多段リレーの場合に、SETUPメッセージはHop-by-Hopで行われるが、そのうちの一つのrelayがその拡張Headerをサポートしていなかった場合の挙動はどうなるのか。
- 要議論
- 現在のdraftでは配信チェーン全体でMoQT versionを強制する機能がない
- 現在のdraftではrelayサーバーはextension headerを変更するべきではないと書かれている
- 要議論
SETUPメッセージにおいては、REQUESTED-EXTENSIONを追加する予定。これによって、clientがCLIENT_SETUPを送信する際にどのextension headerをserverがサポートしているかをネゴることができる。

MoQ relays for Support of High-Throughput Low-Latency Traffic in 5Gのまとめ
3GPPという団体(携帯通信システムの標準化団体)に所属する(?)方が提出したドラフト。MoQTのextensible headerに非常に強く関係し、extensible headerを支持するユースケースとしても例に挙げられている。
このInternet draftでは、XRでのユースケースを例に出し、なぜMoQTにおいてもextensible headerが必要かを示している。
3GPPは、アプリケーションデータをPDU setというグループで処理するが、この際に、グループ毎に輻輳した際に優先制御したい(優先度が低いものはdropして混雑を回避する)。このために、RTPでは RTP header extensionを使用して制御する。
一方で、MoQTではRTP header extensionに相当するものがないので、MoQTでも同様の概念が欲しい。
MoQTのObject Payloadの中は暗号化されている可能性もあり、relayからアクセスできない場合もあるため、PayloadではなくHeaderにこの情報は必要となる。
そして、このDraftでは、MoQ Extension Headerとして、xr-metadataというHeader名をつけ、Headerの仕様について以下のように定義している。これらはMoQTのSETUPメッセージによってClientとServer間でネゴシエーションされる。
- 3gpp-xr
- 0x00: No XR metadata
- 0x01: Release 18 XR metadata
- 0x02: Release 19 XR metadata
- 0x03: both
- 3gpp-xr-options
- 0x00: No optional metadata
- この場合は3gpp-xrは0x00でなければならない
- 0x01: PSSize and NPDS metadata included
- PSSize: PDUSetの全体のサイズを示すmetadata?
- NPDS: PDUSetの中に含まれるPDUの個数を示すmetadata?
- 0x00: No optional metadata
また、MoQT Object内部では、以下の情報が含まれる
- MoQT Datagramを利用する場合
- 3gpp-xr = 0か1の場合、全てのObjectに以下が含まれる
- E(1bit)
- D(1bit)
- PSI(4bit)
- PSSN(10bit)
- PSN(6bit)
- 3gpp-xr = 1の場合、Objectに以下が含まれる可能性がある
- BSize(bit数未定)
- TTNS(bit数未定)
- 3gpp-xr = 0か1 かつ 3gpp-xr-options = 0 の場合、Objectに以下が含まれる可能性がある
- PSSize(24bit)
- NPDS(16bit)
- 3gpp-xr = 0か1の場合、全てのObjectに以下が含まれる
- MoQT Streamを利用する場合
- 3gpp-xr = 0か1の場合、全てのObjectに以下が含まれる
- D(1bit)
- PSI(4bit)
- PSSN(10bit)
- 3gpp-xr = 1の場合、Objectに以下が含まれる可能性がある
- BSize(bit数未定)
- TTNS(bit数未定)
- 3gpp-xr = 0か1 かつ 3gpp-xr-options = 0 の場合、Objectに以下が含まれる可能性がある
- PSSize(24bit)
- NPDS(16bit)
- 3gpp-xr = 0か1の場合、全てのObjectに以下が含まれる
筆者は3GPPについては詳しく知らないが、おそらく3GPPではXR向けの要件を取り込んだversion18,19の仕様があるのだろう。このHeaderは3GPP XR仕様のどのversionをサポートするかを示す。
3GPP XR の仕様については以下のサイトに説明があった。
3GPP(3rd Generation Partnership Project) Release 15(以下,Rel-15)で策定された5GC(5G Core network)*1のアーキテクチャは,Rel-16およびRel-17での拡張に引き続き,5G-Advancedの最初のリリースと位置づけられるRel-18においても,さまざまな分野で拡張があった.特に,VR(Virtual Reality)*2,AR(Augmented Reality)3,XR(Extended Reality)4などによる拡張現実感(以下,「拡張現実感」)とメディアサービス,時刻サービスと確定性通信5,ネットワークスライシング6,RNAA(Resource owner-aware Northbound Application Program Interface Access)*7,インテント駆動管理において,以下の機能改善と新しい技術領域の追加が行われた.
Rel-18より前の5GS(5G System)*25QoSの枠組みでは,これらのフレームを伝送するすべてのPDU(Protocol Data Unit)26は,QoSフロー27ごとに設定された同一のQoSパラメータを使用して処理される.
Rel-18では,NG-RAN(Next Generation-Radio Access Network)*28の無線リソーススケジューリングを改善するために,このようなフレームを伝送する個々のPDUに対して異なるQoS処理(異なる優先順位など)を使用できる.これにより,特に輻輳状況において,NG-RANがアプリケーションのPDUの内容と重要性をより良く認識している場合に,サービスのユーザ体験が向上する.
XR向けの仕様はRelease18以降で追加されているようなので、5G NWでXRデータの優先制御を行うためにはRelease18以降の仕様を見るのが良さそうだ。
Relayの挙動としては以下の通り定義されている
- EはQUIC streamのFIN flagから設定される
- PSNは、STREAMフレームオフセット順に受信したQUIC/UDP/IPパケットに基づいて生成される。欠落パケットがある場合、リレーは、STREAMフレームオフセットとパスMTUを使用して、1つ以上の欠落パケットの後に受信したパケットのシーケンス番号を決定することができる。

Scalable Event-Based Video Streaming for Machines with MoQ についてのまとめ
ベイラー大学の助教授のFreeman AndrewさんがMoQTのメーリスで貼っていた論文。
Arxivにも似たような論文を記載しているが、多少違う部分がある。おそらく↑はMoQ WGに向けてアレンジしたものだろう。
概要
イベントカメラ(センサーで動きを検知してその差分でフレームを表現するカメラ)でもMoQTを使うことで、超大量のセンサーデータを転送したいというもの。
カメラではあるが、厳密には1ピクセルごとにセンサーが変化を検知するような形なので、従来の映像コーデックなどは適用できない。そして、このイベントカメラは1秒で100万回程度変更差分を検知する場合もあるので、サンプリングレート100MHz、100万FPSとも言える。720pだと500Mbpsにもなる。
いくつかこのイベントカメラ向けのコーデックの研究もあり、最近ではJPEGがJPEG-XEというのを出したが、まだまだ大容量すぎる状態。
このイベントカメラはComputer Visionにおいて物体認識などで使われている。多くの場合は、ローカルで処理するか、同一NWで処理がなされる。
しかし、クラウドで処理したいニーズも当然あるため、このMoQTを活用できるのではないか?というモチベーションがある。
このイベントカメラのデータ転送においては、以下の要件を満たしたい。
- リアルタイムの転送
- 後からデータを確認するための転送
https://mailarchive.ietf.org/arch/msg/moq/6cXvYsL1xDctXfYT1v5rxNpHcJg/ より引用
また、Low Latency Targetにおいては、送信したいイベントの中でも、優先順位を設定したい。
MoQTのSubgroupを用いて、50msごとにタイムウィンドウを切り、最初のN個のデータをSubgroup=0、次のN個のデータをSubgroup=1、残りのデータをSubgroup=2として、ID順に優先順位を設定すると、最初の重要なデータの優先順位を上げることが可能。
https://mailarchive.ietf.org/arch/msg/moq/6cXvYsL1xDctXfYT1v5rxNpHcJg/ より引用
WebRTCのPriority APIなどでは、帯域幅の割り当ての優先はしてくれるが、送信順の優先順位は決定してくれないので、優先されない点が厳密にはある。例えば再送処理なども逐次行われるだろうが、一番下のレイヤーを最優先して欲しい。
SFUでこの辺りまで厳密に制御するようにコードを書けば出来ると思われる(結局はRTPパケットをどういう順序にするかという話でしかないので)が、仕様としては存在していないので、実装としても現時点では存在していないかもしれない。(もしご存知の方がいれば教えてください)
MoQTはその優先制御のアルゴリズムがかなり議論されているので、WebRTCとは仕様レベルではそこが差分となるかも。

Media Interop Draft version-01 のまとめ
MoQTを利用したライブ配信やビデオチャットのユースケースにおいてmediaのフォーマットについて定義したドラフト。low overhead packagerという名前で定義されていて、これはLOC(Low Overhead Container)とは別物のようだ。
Object Format
mediaのObjectのフォーマットは以下の通り
{
Media Type (i)
Media Payload (...)
}
Media Typeは以下のコードで表現される。
Code | Value |
---|---|
0x0 | Video H264 in AVCC with LOC packager |
0x1 | Audio Opus bitstream |
0x2 | UTF-8 text |
0x3s | Audio AAC-LC in MPEG4 |
Media Payload
H264 with LOC packager format
{
Seq ID (i)
PTS Timestamp (i)
DTS Timestamp (i)
Timebase (i)
Duration (i)
Wallclock (i)
Metadata Size (i)
Metadata (..)
Payload (..)
}
Opus with LOC packager format
{
Seq ID (i)
PTS Timestamp (i)
Timebase (i)
Sample Freq (i)
Num Channels (i)
Duration (i)
Wall Clock (i)
Payload (..)
}
AAC-LC in MPEG4 bitstream
{
Seq ID (i)
PTS Timestamp (i)
Timebase (i)
Sample Freq (i)
Num Channels (i)
Duration (i)
Wall Clock (i)
Payload (..)
}

MoQ UseCases version-00のまとめ (MoQ Transfork)
Luky Carleyさんが提出したドラフトで、MoQ WGとは別のアプローチで出されたドラフトっぽい。
そこまでちゃんと読めていないので気になったところを箇条書きでピックアップしておく。
- SVCなどで複数画質でエンコードした場合、moqtransforkではその画質毎にTrackとしてpublishする。
- 従来のMoQTではSubgroupの利用を想定しているはず。このdraftでTrack毎にしたいモチベーションはわからなかった
- MoqTransforkの目標の一つは、複数のレイテンシのサポートを行うこと。レイテンシとリーダビリティ(品質)のトレードオフを選択できるようにすること
- 想定しているユースケース
- Realtime通話
- 低遅延ライブ配信
- 高品質ライブ配信
- Video On Demand

MoQT draft-08公開
draft-08が2025/02/12に公開された。06と比較してどのような差分があるかを確認する。https://author-tools.ietf.org/iddiff
差分確認にはiddiffというツールが良い。draft06と08の差分比較
- Session Terminationの終了条件が増えた
- Control Message Timeout
- Control Messageへのレスポンスに時間がかかりすぎた場合
- Data Stream Timeout
- Dataを送信するのに時間がかかりすぎた場合
- Control Message Timeout
- SUBSCRIBE_NAMESPACEがSUBSCRIBE_ANNOUNCESに変更
- Priorityの挙動が厳密に定義
- Subscriber Priority > Publisher Priority > Group Orderの順番に優先順位が決定される。
- SUBSCRIBES_BLOCKEDが追加
- MAX_SUBSCRIBE_IDを超えるSUBSCRIBEを受けた時に返却するMessage
- FETCH, FETCH_OK, FETCH_ERRORが追加
- FETCHは過去、SUBSCRIBEは現在から未来のデータを取得するように使い分けがきめらえた
- さらに、過去から未来に向けてデータを取得したい場合はJoining Fetchというパラメータで判別を行う
- FETCHにはstandalone Fetch(0x1)とJoining Fetch(0x2)がある
- さらに、過去から未来に向けてデータを取得したい場合はJoining Fetchというパラメータで判別を行う
- FETCHは過去、SUBSCRIBEは現在から未来のデータを取得するように使い分けがきめらえた
- ObjectStatusからEnd of Subgroupが削除された

WARP draft-03まとめ
02からの差分はこんな感じで、以前Common Catalog Formatで定義されていた各種フィールドが取り込まれた。
サッと見る限り、このフィールドの内容や設計思想は以前のCommon Catalog Formatの仕様と変わっていなさそう。WARPのdraftではCatalogと呼ばれているので、今後はCatalogと呼ぶことにする。
Catalogとは?
Media Over Quic Transport(MOQT)で利用するメディア情報及びそのパッケージング手法を伝達する手段。
MOQTでは、このカタログを受け取って、好きなものをSubscribeすることでメディアを受信する。
WebRTCにおけるSDPのm行に近い。
WebRTCのSDPはずっとPlainTextだが、MOQTではJSONオブジェクトで管理される。
WebRTCのSDP
v=0
o=- 4340214655134371844 2 IN IP4 127.0.0.1
s=-
t=0 0
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=sendrecv
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 124 119 123 118 114 115 116
c=IN IP4 0.0.0.0
a=sendrecv
Catalog
{
"version": 1,
"streamingFormat": "1",
"streamingFormatVersion": "0.2",
"commonTrackFields": {
"namespace": "conference.example.com/conference123/alice",
"packaging": "loc",
"renderGroup": 1
},
"tracks": [
{
"name": "video",
"selectionParams":{"codec":"av01.0.08M.10.0.110.09","width":1920,"height":1080,"framerate":30,"bitrate":1500000}
},
{
"name": "audio",
"selectionParams":{"codec":"opus","samplerate":48000,"channelConfig":"2","bitrate":32000}
}
]
}
WebRTCのSDPでは、ICE Candidate(自身のlocal IP, global IP, TURN IP)も含めてやり取りされるが、MOQTではP2Pをサポートしていないため、Common Catalog Formatでもメディア情報のみ。
Catalogの送信方法
Catalogは「メディアの一種」として取り扱われる。
MOQTのメディアは、ANNOUNCE(配信宣言) → SUBSCRIBE(受信要求) → OBJECT(メディアデータ)という流れで送られるが、ANNOUNCE(配信宣言)ではメディア情報までは共有されず、使う名前空間の宣言のみ。
Common Catalog Formatは、メディアの一種として取り扱われるため、おそらく以下の流れが想定されている。
ANNOUNCE → SUBSCRIBE → OBJECT(Catalog) → SUBSCRIBE(MediaのTrack指定) → OBJECT(メディアデータ)
そして、Catalogは共通してCatalogというTrackNameを持ち、TrackName上の予約語となる。TrackNameSpaceはANNOUNCEで伝達され、具体的なTrackNameについては、TrackName=CatalogをSUBSCRIBEし、OBJECTメッセージとして受信することで具体的なメディアの情報を取得することができる。
Catalogの更新方法
Catalogは JSON-Patch
方式で差分更新が可能。差分更新のデータもおそらくOBJECTメッセージを使ってメディアと同じように送信される。
以下のようなベースとなるCommon Catalog Formatがあった場合に、
{
"version": 1,
"streamingFormat": "1",
"streamingFormatVersion": "0.2",
"commonTrackFields": {
"namespace": "conference.example.com/conference123/alice",
"packaging": "loc",
"renderGroup": 1
},
"tracks": [
{
"name": "video",
"selectionParams":{"codec":"av01.0.08M.10.0.110.09","width":1920,"height":1080,"framerate":30,"bitrate":1500000}
},
{
"name": "audio",
"selectionParams":{"codec":"opus","samplerate":48000,"channelConfig":"2","bitrate":32000}
}
]
以下のようなオペレーション要求がJSONで送られる。
画面共有のtrackを追加する場合
[
{
"op": "add", // 他に replace, remove, copy, move, testがある
"path": "/tracks/-",
"value": {
"name": "screen",
"selectionParams":
{
"codec":"vp8",
"width": 1920,
"height": 1080,
"framerate": 30,
"bitrate": 1500000
}
}
},
......
]
このオペレーションの結果、tracks配下にvideo,audioに加えてscreenが追加される
{
"version": 1,
"streamingFormat": "1",
"streamingFormatVersion": "0.2",
"commonTrackFields": {
"namespace": "conference.example.com/conference123/alice",
"packaging": "loc",
"renderGroup": 1
},
"tracks": [
{
"name": "video",
"selectionParams":{"codec":"av01.0.08M.10.0.110.09","width":1920,"height":1080,"framerate":30,"bitrate":1500000}
},
{
"name": "audio",
"selectionParams":{"codec":"opus","samplerate":48000,"channelConfig":"2","bitrate":32000}
},
/////////////////////////////////////////////////////////
{
"name": "screen",
"selectionParams":{"codec":"vp8","width": 1920,"height": 1080,"framerate": 30,"bitrate": 1500000}
}
/////////////////////////////////////////////////////////
]
}
WebRTCのSDPだと文字列検索で行を特定して消したり追加したりしていたけど、JSON&JSON-Patchでやれることになって快適になっている。

MoQT draft-09のまとめ
08から1ヶ月も経っていないのもあって、ほとんど変化なし。
- SUBSCRIBE_ANNOUNCESでANNOUNCEだけでなくUNANNOUNCEも受け取ることが明記された
- SUBSCRIBEのFilter Typeから Latest Groupが削除された
- FETCH(Joining FETCH) が実装されて、Latest Object + Joining FETCHと同じだからということらしい
- https://github.com/moq-wg/moq-transport/issues/679
- Object Extension CountがObject Extension Lengthに変更
- Extension数ではなく、Object Extension block全体のlength(bytes数)になった
- OBJECT_DATAGRAMからObject Payload LengthとObject Statusが削除された

QUICの輻輳制御のアルゴリズム(BBRv1?)がRTCに適切でない理由
元Twitch、現DiscordのLukeさんがメーリスにて発言していた。数ヶ月の調査によって得られた貴重なノウハウなのでメモしておく。解釈違いがあるかもなので要注意。
- BBRv1(および一般的なTCP輻輳制御)はNWをフルに活用出来ない(2Mbpsの余裕があっても1Mbpsしか出ないなど)
- 輻輳ウィンドウを利用可能帯域幅限界まで最大化させるのが非常に遅く、ロスすると急降下する
- これによって、RTCにはBBRv1は向かない。BBRv3はどうか不明
- 解決策Aは、LL-HLSとLL-DASHで採用されている方法で、フレームを束ねておく。
- 束ねたフレームがバーストすると、輻輳ウィンドウを最大化させるのに多くの時間がかかるものの、輻輳ウィンドウが乗算で増加し、bitrateが増加する。Lukeさんの調査によると、1フレーム分のレイテンシは発生したものの、推定bitrateは二倍になった
- 解決策Bは、QUICにプロービングを実装すること
- BBRはプロービングを1/8の頻度で送る?(解釈間違えてるかも)ことを明示しているが、あえてその設定を無視したプロービングを自身のQUICライブラリに実装した。これによって、輻輳ウィンドウの制御により多くの時間が費やされ(?)、輻輳ウィンドウを増加させることができる。これも推定bitrateを倍にした
リアルタイム輻輳制御では、これらの問題が発生するため、MoQTでも考慮する必要があるようだ。
QUICの輻輳制御自体はアルゴリズム選択の自由はありそうなので、「どのアルゴリズムを選択するべきなのか?」とか「ブラウザ内部のQUICのアルゴリズムとの相性が・・・」みたいな話が議論になりそうか?

2025/03時点でのWebCodecsのSVC対応状況(Google Chrome)
SVCコーデックに概要についてはこちらが詳しい。
WebCodecsはSVCに対応しており、VideoEncoderのconfigにて scalabilityMode
を指定することで利用できる。
しかし、mdnには下記の通り、直接的にどのモードが対応しているかは書かれていない。
A string containing an encoding scalability mode identifier as defined in WebRTC.
W3CのWebRTCのdraftには大量のモードが記されているが、これらが実際に使えるかどうかは知らなかった。
実際に調べてみたところ、2025年3月現在でも、時間スケーラビリティ、つまりはframerateでスケールする L1Tn方式
しかサポートしていないようだ。
種別 | 備考 | 対応状況 |
---|---|---|
L1T1 | 基本形 | ◯ |
L1T2 | 2層の時間スケーラビリティ(framerate) | ◯ |
L1T3 | 3層の時間スケーラビリティ(framerate) | ◯ |
S2T1 | 2層の空間スケーラビリティ(resolution) | × |
S2T2 | 2層の空間スケーラビリティ(resolution) * 2層の時間スケーラビリティ(framerate) | × |
L2T1 | 2層の空間スケーラビリティ(resolution) | × |
L2T2 | 2層の空間スケーラビリティ(resolution) * 2層の時間スケーラビリティ(framerate) | × |
L2T2_KEY | keyframeのみ | × |
MoQTではSubgroupを用いて、SVCのレイヤー毎に優先度制御を行うことを想定しているが、現在の対応状況だと L1Tn方式
しか対応していないので、フレームレートでレイヤーを分けて、「NW帯域がきつい時は10FPS、余裕がある時は30FPSにする」みたいなことは可能だが、「NW帯域がきつい時は解像度低、余裕がある時は解像度高」みたいなことは不可能。フレームレートと解像度の両方使ってレイヤーを分けることもできない。
もし、実現したい場合は、解像度でtrackNameを分けて、その中でフレームレートでSubgroupで分けるみたいなことが必要になりそうだ。
- video track(SD画質)
- L1T3
- temporalLayerId=0: 10fps
- temporalLayerId=1: 20fps
- temporalLayerId=2: 30fps
- L1T3
- video track(HD)
- L1T3
- temporalLayerId=0: 10fps
- temporalLayerId=1: 20fps
- temporalLayerId=2: 30fps
- L1T3

MoQT draft-10のまとめ
09が出てから2日しか経っていないが、IETF122滑り込みで再度変更が入った。
仕様変更というよりかは、順番の整頓のみ。
draft-09時点でも似たようなことは書かれていたが、多少文章が変わっていそうなので、PublisherとSubscriber間でのメッセージのやり取りの文章は再度整理しておく。
- Publisher, SubscriberがどうやってSUBSCRIBE/FETCHメッセージを送り合うかが明記された(4章)
- SubscriberはPublisherとTrackに対するSUBSCRIBEやFETCHを通してインタクションを行いSUBSCRIBE_OK/FETCH_OKとOBJECTを受け取ることを期待する
- PublisherはSUBCRIBEの応答として正確に一つのSUBCRIBE_OK/SUBSCRIBE_ERRORを、FETCHの応答として正確に一つのFETCH_OK/FETCH_ERRORを送らなければならない
- Subscriberは応答メッセージを複数受け取ったらプロトコルエラーとしてセッションをクローズするべき
- SubscriberはUNSUBSCRIBEを送信するか、SUBSCRIBE_DONEかSUBSCRIBE_ERRORを受け取るまではSUBSCRIBEの情報を保持し続ける
- SubscriberはFETCH_CANCELの送信かFETCH_ERRORの受信かFETCH用ストリームのFINかRESET_STREAMを受信するまではFETCHの情報を保持し続ける
- FETCH用ストリームがすでにオープンしている場合はFETCH_CANCELに加えてSTOP_SENDINGも送信しても良い
- PublisherはUNSUBSCRIBEかFETCH_CANCELを受信すると、SUBSCRIBE/FETCH情報を即座に破棄できる
- その際に、SUBSCRIBE/FETCHに紐づいている全てのストリームリセットしなければならない
- FETCHデータストリームを破棄した後にFETCH情報を破棄しても良い
- PublisherはSUBSCRIBE_DONEを送信した後、即座にSUBSCRIBE情報を破棄できるが、関連する全てのストリームを閉じるまでSUBSCRIBE_DONEを送ってはならない
- データストリームを全て閉じたらFETXH情報を破棄して良い
- SUBSCRIBE_ERROR/FETCH_ERRORはPublisherもSubscriberも即座に破棄できる