You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Drop deflate's MUST-implement status in both drafts. A mandatory
algorithm is a conformance burden (a zstd-only endpoint shouldn't be
non-conformant) and doesn't actually guarantee end-to-end compression
on a relayed path anyway. Now both deflate and zstd are simply defined;
endpoints advertise whichever they support, and a publisher uses an
algorithm its peer advertised or `none` if they share none — verbatim,
the same well-defined fallback as any unsupported case. Removes the
"Requirement" column and the "always a safe choice" framing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8bLV6vHzucLNvDhPk3bMP
Copy file name to clipboardExpand all lines: draft-lcurley-moq-compression.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -66,7 +66,7 @@ COMPRESSION Setup Option {
66
66
67
67
**Algorithm**:
68
68
One or more Algorithm identifiers (see [Compression Algorithms](#compression-algorithms)) that the sender can decompress, each a varint, filling the Option Value.
69
-
An endpoint that includes this option MUST list `deflate` (1); the identifier `none` (0) MUST NOT be listed (it requires no negotiation).
69
+
The identifier `none` (0) MUST NOT be listed (it requires no negotiation); an endpoint lists whichever other algorithms it supports.
70
70
An endpoint that does not support the extension omits the option.
71
71
72
72
A sender MUST NOT compress with an algorithm the receiver did not advertise, and MUST NOT compress before it has received the receiver's COMPRESSION option.
@@ -89,7 +89,7 @@ COMPRESSION Track Property {
89
89
**Value**:
90
90
The Algorithm identifier the publisher used for this track's payloads (see [Compression Algorithms](#compression-algorithms)).
91
91
The absence of the property, or a value of `none` (0), means the track is uncompressed and its payloads are always transmitted verbatim.
92
-
The publisher MUST choose an algorithm that its peer advertised in the [COMPRESSION Setup Option](#setup-negotiation); since `deflate` is mandatory to implement, it is always a safe choice.
92
+
The publisher MUST choose an algorithm that its peer advertised in the [COMPRESSION Setup Option](#setup-negotiation), or `none` if the peer advertised none the publisher can produce.
93
93
94
94
The property is fixed for the lifetime of the track and MUST NOT change.
95
95
A relay MUST forward it unchanged on every hop, including a hop that has not negotiated the extension: there it is simply an ignored unknown Key-Value-Pair, but forwarding it lets a further-downstream hop that does negotiate the extension still act on the publisher's algorithm.
@@ -124,13 +124,13 @@ A relay or cache can hold the object payloads compressed in memory and forward t
| 0 | none | Verbatim; the absence of compression. Never advertised. |
130
+
| 1 | deflate | Raw DEFLATE {{RFC1951}}, with no zlib or gzip framing. |
131
+
| 2 | zstd | Zstandard {{RFC8878}}. |
132
132
133
-
Every endpoint that advertises this extension MUST implement `deflate`, so the publisher always has a safe choice; `zstd` is optional.
133
+
Endpoints advertise whichever of these algorithms they support; none is mandatory, and a publisher uses one its peer advertised (or `none` if they share none).
134
134
Further algorithms MAY be registered (see [IANA Considerations](#iana-considerations)).
The Compression Parameter advertises the payload compression [algorithms](#compression) the sender can *decompress* on this hop.
635
635
The Parameter Value is a sequence of algorithm identifiers, each a variable-length integer, packed back-to-back to fill the Parameter Length.
636
-
An endpoint that supports compression MUST include `deflate` (1); `none` (0) MUST NOT be listed. An endpoint that does not support compression omits the parameter.
636
+
The identifier `none` (0) MUST NOT be listed. An endpoint that does not support compression omits the parameter.
637
637
638
638
A relay MUST NOT forward the parameter (see [Session](#session)); it is negotiated independently on each hop.
639
639
The list constrains what a publisher may use: a publisher MUST set `Publisher Compression` to an algorithm its peer advertised here (see [TRACK_INFO](#track-info)), and more generally a sender MUST NOT compress with an algorithm the receiver did not advertise, nor compress at all before it has received the receiver's Compression Parameter.
@@ -869,7 +869,7 @@ The compression algorithm the original publisher applied to this Track's payload
869
869
- `0` (`none`): payloads are uncompressed (the default).
870
870
- `1` (`deflate`) or `2` (`zstd`): payloads are compressed with that algorithm.
871
871
872
-
The publisher MUST choose an algorithm its peer advertised in the [Compression Parameter](#compression-parameter); `deflate` is mandatory to support, so it is always a safe choice.
872
+
The publisher MUST choose an algorithm its peer advertised in the [Compression Parameter](#compression-parameter), or `0` if the peer advertised none the publisher can produce.
873
873
The value is fixed for the lifetime of the Track and forwarded unchanged by relays, so even a hop that does not compress passes it along for a further-downstream hop to act on.
874
874
It does not by itself cause compression: a receiver decompresses if and only if the value names a non-`none` algorithm and the receiver advertised that algorithm in its own [Compression Parameter](#compression-parameter); otherwise the payloads are verbatim (see [Compression](#compression)). A subscriber that does not recognize the value treats the payloads as verbatim, so an unknown future algorithm degrades to uncompressed rather than blocking the Track.
875
875
@@ -885,13 +885,13 @@ A hop compresses a Track's payloads when, and only when, `Publisher Compression`
| 0 | none | Verbatim; the absence of compression. Never advertised. |
891
+
| 1 | deflate | Raw DEFLATE {{!RFC1951}}, with no zlib or gzip framing. |
892
+
| 2 | zstd | Zstandard {{!RFC8878}}. |
893
893
894
-
Every endpoint that supports compression MUST implement `deflate`, so the publisher always has a safe choice; `zstd` is optional, and further algorithms MAY be defined by future extensions.
894
+
Endpoints advertise whichever of these algorithms they support; none is mandatory, and a publisher uses one its peer advertised, or `none` if they share none. Further algorithms MAY be defined by future extensions.
895
895
896
896
Compression is **group-scoped** and applied only to frame payloads, never to the FRAME framing. Within a group the payloads form a single compressed stream in the Track's algorithm, reset at each group boundary, whose output is partitioned at frame boundaries: the compressor flushes at the end of each frame so that frame's slice is exactly the bytes stored in its `Payload` (delimited by `Message Length`). Both algorithms provide such a flush that retains the window (DEFLATE's sync flush; Zstandard's `ZSTD_e_flush`), so later frames in a group reuse the compression context. A receiver maintains a single decoder per group, reset at each group boundary, and feeds each frame's `Payload` through it in order: the first frame starts the decoder fresh — so a subscriber joining at a group boundary needs nothing earlier — while later frames retain cross-frame redundancy across the group. There is no shared state between groups; a frame with an empty payload contributes nothing to the stream.
897
897
@@ -1114,7 +1114,7 @@ A generic library or relay MUST NOT inspect or modify the decompressed contents
1114
1114
- Removed `Publisher Max Latency`. The publisher's retention guarantee is no longer part of the wire format; retention for FETCH and future subscriptions is best-effort and left to the publisher.
1115
1115
- Timestamp-based expiration replaces wall-clock arrival time when a Track timescale is negotiated.
1116
1116
- Added QUIC datagram delivery for groups, sharing Subscribe IDs with existing subscriptions (no separate control stream).
1117
-
- Added payload compression, scoped per group. `Publisher Compression` in TRACK_INFO now names the algorithm the publisher used (`none`/`deflate`/`zstd`), and a new SETUP `Compression` parameter carries the algorithms each endpoint can decompress on a hop. The publisher MUST pick an algorithm its peer advertised; `deflate` is mandatory (so always safe) and `zstd` is optional. There is no per-group or per-frame flag on the wire — a receiver decompresses iff `Publisher Compression` names a non-`none` algorithm it advertised, else treats payloads as verbatim. When compressed, a group's frame payloads (only the payloads, never the framing) form a single stream in that algorithm, reset at each group boundary and sliced per frame into each frame's opaque `Payload`, with the algorithm's redundant container bytes omitted (the RFC 7692 trim for deflate; magicless, checksum-less frames for zstd) since moq-lite frames the slices itself; the decoder keeps one context per group. Keeping the framing uncompressed lets a relay store payloads compressed and re-frame across transport versions without recompressing.
1117
+
- Added payload compression, scoped per group. `Publisher Compression` in TRACK_INFO now names the algorithm the publisher used (`none`/`deflate`/`zstd`), and a new SETUP `Compression` parameter carries the algorithms each endpoint can decompress on a hop. The publisher MUST pick an algorithm its peer advertised (or `none` if they share none); `deflate` and `zstd` are defined, neither mandatory. There is no per-group or per-frame flag on the wire — a receiver decompresses iff `Publisher Compression` names a non-`none` algorithm it advertised, else treats payloads as verbatim. When compressed, a group's frame payloads (only the payloads, never the framing) form a single stream in that algorithm, reset at each group boundary and sliced per frame into each frame's opaque `Payload`, with the algorithm's redundant container bytes omitted (the RFC 7692 trim for deflate; magicless, checksum-less frames for zstd) since moq-lite frames the slices itself; the decoder keeps one context per group. Keeping the framing uncompressed lets a relay store payloads compressed and re-frame across transport versions without recompressing.
1118
1118
- Added Qmux [qmux] transport bindings for TCP/TLS and WebSocket, for environments where UDP is unavailable. The WebSocket binding uses the WebSocket message framing in place of the Qmux Record `Size` field.
0 commit comments