Hey Quicers,

I presented an extension
<https://www.ietf.org/archive/id/draft-lcurley-moq-probe-00.html> to the
MoQ working group and Ian suggested it could/should be in QUIC instead.

*tl;dr* A way for receivers to know the sender's estimated bitrate and to
request increasing it.

The problem involves application-limited flows like live media. Suppose
we're currently downloading a 3Mb/s video stream (720p) and need to decide
if our connection can support 6Mb/s (1080p). There's no way to gradually
increase the media bitrate; these renditions are fixed. The viewer buffers
(spinny boye) if we try to download an unsustainable rendition.

Unfortunately, individual media frames may not be large enough to fill the
congestion window. CUBIC/Reno/BBR can't increase the window/pacing rate
unless the connection is fully utilized (not application-limited). We get
stuck with an artificially low bitrate estimate that won't reach 6Mb/s
unless bufferbloat causes some queuing (ironic). I-frames cause a tiny
burst but it's never enough.

HLS/LL-HLS avoids this problem by batching frames, allowing us to burst
these fragments (usually at least 500ms) to saturate the window. However,
this increases latency by the same amount. Twitch wanted to avoid adding
any latency and instead "solved" this issue by running a periodic speed
test, downloading 128KB of zeroes.

But WebRTC has a better solution. It periodically probes higher bitrates by
speculatively retransmitting media in flight. The QUIC equivalent would be
retransmitting STREAM frames that have not yet been marked as lost. This
adds a crude form of redundancy, so even if our probe causes packet loss,
it partially masks the problem.

I implemented this for our MoQ rollout (10%) while at Twitch. The average
production bitrate increased roughly 1Mb/s (3 -> 4) compared to the
existing client-side ABR, all because we were more confidently able to
switch to higher renditions. But they ended up laying off 80% of the
company and shuttering the baremetal CDN, so take my anecdote with a grain
of salt lul.

My MoQ extension more-or-less looks like this:
 -->  PROBE_REQUEST      target_bitrate=0
 <--  PROBE_RESPONSE  estimated_bitrate=3000000
 <--  PROBE_RESPONSE  estimated_bitrate=3123456
 -->  PROBE_REQUEST      target_bitrate=6000000
 <--  PROBE_RESPONSE  estimated_bitrate=4999999
 <--  PROBE_RESPONSE  estimated_bitrate=6233345
(success, we can switch up)

Now the important question: Would this be the sort of extension that would
be useful at the QUIC layer?

We don't *need* a QUIC extension because a sender can already implement
this. All QUIC receivers MUST be prepared to receive overlapping STREAM
frames, as that can happen naturally due to ack timers. If application
limited, the QUIC library just needs to retransmit some STREAM frames
already in flight.

At a minimum, I need an API to get the sender's estimated bitrate (very
common) and another to probe for a higher bitrate (afaik no implementations
exist). This is the type of thing we'll need in the WebTransport API (W3C)
if we ever want to reach WebRTC parity.

But it's not clear if we should transmit these PROBE_XXX messages at the
QUIC layer or as part of MoQ. It could be useful for other
application-limited protocols, and tighter integration with the QUIC stack
could help (ex. send a PROBE_RESPONSE immediately after processing an ACK).

Reply via email to