03. データモデル: Track・Group・Object
🎯 この章のゴール
- Track → Group → Subgroup → Object の階層を説明できる
- Location による順序付けと Group ID の性質を理解する
- Track Namespace(タプル)とプレフィックス一致、スコープを知る
💡 ひとことで言うと
Track は「テレビのチャンネル」、Group は「途中から見始められる区切り(GOP)」、Object は「1 コマ」。サブスクライバはチャンネルを選び、区切りから見始めます。
4 階層のデータモデル
Object: 最小単位
Object は番地の付いたバイト列です。MOQT のデータモデルの基本要素で、次のフィールドを持ちます。
| フィールド | 意味 |
|---|---|
| Track Namespace / Track Name | 所属するトラック |
| Group ID | 所属する Group |
| Object ID | Group 内での順番 |
| Publisher Priority | パブリッシャが付けた優先度(09 章) |
| Delivery Mode | Subgroup(ストリーム)で送るか Datagram で送るか |
| Subgroup ID | 所属する Subgroup(Datagram の場合はなし) |
| Object Properties | リレーから見えるキーと値のペア(11 章) |
| Object Payload | 中身(空でもよい) |
Object には 2 つのルールがあります。まず、Object はどの経路で取得しても同じバイト列で、内容は時間が経っても変わってはいけません(MUST NOT)。取得できなくなることはあります。
次に、メタデータは暗号化されず、リレーから常に見えます。ペイロードはエンドツーエンドで暗号化してよく、その場合はオリジナルのパブリッシャとエンドサブスクライバだけが読めます。
Subgroup: 同じストリームに乗せる単位
Subgroup は同じ Group 内の Object を Object ID 昇順に並べた列で、できる限り 1 本のストリームで送られます。B が A に依存するなら、A の後ろに B を同じストリームで流すと都合がよい、という考え方です。
上の図のように、時間方向スケーラビリティ(temporal scalability)のある映像なら、レイヤーごとに Subgroup を分けておくと、帯域が足りないときに優先度で拡張レイヤーだけを諦められます。
Group: 参加ポイント
Group は Object の集まりで、他の Group の Object に依存しないように作ります(SHOULD NOT)。そのため Group の先頭が途中参加の入口(join point)になります。映像なら GOP(キーフレーム + 後続フレーム)を 1 Group にするのが定番です。
Group ID は、メディアの時間軸に沿って時間とともに増えるように付けるべき(SHOULD)とされます。ただしネットワークの並べ替えや部分的信頼性のため、受信側には Group が順不同で届きえます。受信側は Object を 1 つ受け取るまで、その Group が存在するかどうか推測できません。
Track: 購読の単位
Track は Group の列で、サブスクライバが購読を申し込む対象です。解像度違いの映像は別々の Track にしておけば、視聴者が環境に合わせて選べます。
Location: Object の座標
Group ID と Object ID の組を Location と呼び、{Group, Object} と書きます。
Location A < Location B ⇔ A.Group < B.Group || (A.Group == B.Group && A.Object < B.Object)例: {4, 100} < {5, 0} < {5, 3}。次章以降で出てくる「Largest Object」「Next Group」などもすべて Location で表します。
Object の 3 つの状態
サブスクライバやキャッシュから見ると、Object は次のどれかの状態です。
- 存在しないと分かっている。この状態は恒久的で、元には戻らない
- 存在すると分かっている。後で「存在しない(取得不能)」に変わることはある
- 不明。まだ届いていないか、まだ作られていない
Object ID が飛んでいても、それだけでは何も分かりません。飛んだ番号は、受信するか「存在しない」と明示されるまで不明のままです。
Track の名前: Namespace + Name
Track は Full Track Name(Track Namespace + Track Name)で識別されます。
- Track Namespace: 0〜32 個のフィールドからなるタプル。例:
(example.com, live, alice) - Track Name: Namespace 内で Track を区別するバイト列。例:
video-1080p
どちらも単なるバイト列で、比較はバイト単位の完全一致です(UTF-8 などに制限するのは上位の仕様の役目)。Full Track Name の合計長は 4,096 バイトまでです。
プレフィックス一致
タプルなので「先頭のいくつかのフィールド」で範囲を指定できます。比較はフィールド単位の完全一致です。
| プレフィックス | (live, sports, soccer) | (live, sportsnews) |
|---|---|---|
(live) | ✅ | ✅ |
(live, sports) | ✅ | ❌(sports ≠ sportsnews) |
この性質を使って、リレーは「(example.com, live) 以下はこのパブリッシャへ」のようにルーティングします(07 章)。
文字列で書くときの表記
ログやファイル名用に、次の表記が推奨されています。
- フィールドを
-でつなぎ、最後のフィールドと Track Name の間は-- a-z A-Z 0-9 _はそのまま、それ以外のバイトは.+ 小文字 16 進 2 桁
example.2enet-team2-project_x--report
Namespace: (example.net, team2, project_x)
Track name: report予約された名前空間
最初のフィールドが .(ピリオド)で始まる名前空間は予約されています。たとえば .session はセッション単位の機能拡張用で、アプリが使ってはいけません。
スコープ: 名前が一意な範囲
スコープは、Full Track Name が特定のトラックを一意に指すことが保証されるサーバーの集合です。どこまでをスコープとするかはアプリが決めます(LAN 内の 1 接続だけ、複数 CDN 全体、など)。特に情報がなければ、接続 URI の authority と path が同じなら同じスコープです。
スコープ内で Full Track Name は一意なので、そのままキャッシュのキーになります。HTTP と違って、リクエストのパラメータでトラックの中身が変わることはありません。
再起動で状態を失ったパブリッシャが同じ Track に以前と違う Object を出すと、不変性の約束を破ります。対策として、名前に時刻を含める、Group ID を現在時刻から始めて必ず以前より大きくする、TRACK_STATUS で以前の最大 Group ID を問い合わせる、などが挙げられています。
🧪 考えてみよう
1080p と 480p の映像、それに日本語音声と英語音声を配信したいとき、Track はいくつ作るのが自然でしょう? 視聴者が独立に選びたいものは別 Track にするのが基本なので、映像 2 + 音声 2 の 4 Track が自然です。MSF ではさらに、それらを説明するカタログ用の Track を置きます(12 章)。
📝 まとめ
- 階層は Track(購読単位)→ Group(参加ポイント)→ Subgroup(ストリーム単位)→ Object(不変のバイト列)
- Object は Full Track Name + Location
{Group, Object}で一意。メタデータは見え、ペイロードは秘匿できる - Track Namespace はタプルで、フィールド単位のプレフィックス一致でルーティングに使う
参考
- draft-ietf-moq-transport-22 §2 Object Data Model
- §8.2 Location / §8.8 Representing Namespace and Track Names
✅ 理解度クイズ
Object は Full Track Name(Namespace + Name)と Group ID・Object ID で一意に決まり、どこからどう取得しても同じバイト列でなければなりません。Track Alias はセッション内の省略表現にすぎません。
Group は他の Group に依存しない(SHOULD)独立した単位で、join point になります。映像なら GOP(キーフレームから始まるフレーム列)を 1 Group にするのが典型です。
Location はまず Group で比較し、Group が同じときだけ Object で比較します。5 > 4 なので {5, 3} の方が大きくなります。
(live, sports) にマッチする Track Namespace は?プレフィックス一致はフィールド単位の完全一致で先頭から比較します。sportsnews は sports とフィールドとして一致しないのでマッチしません。
メタデータ(Group ID、優先度など)は暗号化されず、リレーの配信判断に使われます。ペイロードは不透明で、リレーは結合・分割・改変してはいけません(MUST NOT)。