Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hints & sendOrder how can they work together #326

Closed
jordicenzano opened this issue Nov 6, 2023 · 5 comments · Fixed by #470
Closed

Hints & sendOrder how can they work together #326

jordicenzano opened this issue Nov 6, 2023 · 5 comments · Fixed by #470
Labels
Needs Discussion Tags for issues which need discussion, ideally at an interim or IETF meeting. Transmission Issues involving what to transmit when, what to drop, priorities, etc

Comments

@jordicenzano
Copy link

If we use hints on SUBSCRIBE (StartGroup, StartObject) I assume is to request objects from the past. Thinking about the live rewind or VOD (archived after live):

  • The objects have a sendOrder burnt-in, and since those were part of a live stream that sendOrder is probably increasing (meaning more recent, higher priority)
  • If player requests objects from 1h in the past, and relay respects the sendOrder the player will start receiving objects from the end of the live stream to the start. Also those will be sent at wire speed

It seems for VOD-like use cases we need a different type of delivery than live edge. Perhaps we should do sliding window and/or sendOrder updates?

Finals questions:

  • Can we use current current hints to deliver VOD?
  • Do we need to add signals?
@kixelated
Copy link
Collaborator

kixelated commented Nov 7, 2023

Absolutely.

sendOrder is meant to avoid head-of-line blocking when subscribed to the live playhead. Everything is delivered on a best-effort basis according to sendOrder with the expectation that there's a limited amount of time to deliver each new frame (jitter buffer size).

But when "subscribed" to old content like VOD, you actually want head-of-line blocking. The player can build up a massive buffer so there's no need to panic; reliable delivery is just fine. In fact when a viewer seeks back to the 12:34 mark of the VOD, they want 12:34 to be the first frame rendered, so that needs to be the first frame delivered. That's not possible with sendOrder unless you subscribe to a single group... assuming sendOrder is incremented per group.


First off, doing an unbounded SUBSCRIBE for VOD is always a mistake. If you want to watch content starting at 12:34, then SUBSCRIBE start=12:34 end=none will absolutely inundate you with media; there's no back-pressure. You might receive hours of media at line-speed overflowing any local buffer, and of course sendOrder will incorrectly send you the newest media first.

At a minimum each SUBSCRIBE needs to be scoped. ex. SUBSCRIBE start=12:34 end=12:45. The player can periodically request chunks to fill the buffer based on the current playback position. sendOrder will still incorrectly send you the newest media first.

One option is to SUBSCRIBE on a per-group basis. ex. SUBSCRIBE start=12:34 end=12:36, wait for SUBSCRIBE_FIN, SUBSCRIBE start=12:36 end=12:38. This is analogous to performing a single HTTP GET at a time like how HLS/DASH perform VOD. There's a small window between each SUBSCRIBE_FIN and SUBSCRIBE where you're not fully utilizing the connection, so it could be slightly better.

Another option to add a command to GET start=12:34 end=12:45, which would tell the relay to disable any congestion control avoidance mechanisms like sendOrder and dropping OBJECTs. This would be reliable hop-to-hop, but not necessarily end-to-end (we should support holes in the VOD).

However it's not clear what a relay is supposed to do when there's simultaneous SUBSCRIBEs and GETs active, since prioritization is performed at a session/connection level. Sometimes you want GET to be higher priority than any live content (DVR), sometimes you want GET to be performed in the background (filling holes in the cache). Maybe GET can provide a sendOrder override or something.

I do think a way of reliably fetching media is necessary, so I would be inclined to add something like GET.

@kixelated
Copy link
Collaborator

@wilaw you probably have some opinions here.

@wilaw
Copy link
Contributor

wilaw commented Nov 7, 2023

I was thinking of it working much like you propose above - the player making a series of bounded requests, so that it can control its forward buffer growth. As the user plays forward, it could just update that subscribe (I think we just approved that control message yesterday) to push out the end range until it reaches EOF.

SUBSCRIBE start=0:0 end=20:0
SUBSCRIBE-UPDATE [1] start=0:0 end=40:0
SUBSCRIBE-UPDATE [1] start=0:0 end=60:0
...
SUBSCRIBE-UPDATE [1] start=0:0 end=343:16

I wouldn't subscribe on a group-by-group basis (even though it would work), as that is just mirroring the unnecessarily verbose HLS behavior. We can take advantage of the sequential delivery that subscription affords to minimize the amount of control requests that must cross the wire and that the relay must process.

As for GET, that is very interesting. We do need a mode where a client can reliably request a range of content and have the relay ignore any priority instructions in the header and also fill in any gaps . I think this should be a new hint on the SUBSCRIBE request rather than a new request .

Imagine SUBSCRIBE start=0:0 end:32:10 reliable=true

This would instruct the relay to do two things:

  1. Never drop an object. When faced with congestion, it should queue the data and always send it reliably.
  2. If it has gaps in the range, it should fill them by making explicit reliable requests back to the origin to fill them.

@afrind
Copy link
Collaborator

afrind commented Nov 7, 2023

Individual Comment:

SUBSCRIBE start=0:0 end:32:10 reliable=true

I think something like a subscribe hint regarding delay vs. drop is useful.

the player making a series of bounded requests

It makes me cringe slightly that we built this beautiful pub/sub and we would not take full advantage of it.

there's no back-pressure

I wonder if another way to spell this is with object flow control (expressed in bytes, object count or both). You could then issue one subscribe for everything you want and then strategically grant more flow control credits to control the receive rate. Maybe there's a way to cleverly use QUIC's flow control instead of a moq one, but we'd need to think through that carefully.

@afrind afrind added the Needs Discussion Tags for issues which need discussion, ideally at an interim or IETF meeting. label Jan 31, 2024
@fluffy
Copy link
Contributor

fluffy commented Feb 4, 2024

This is starting to sound very complicated for relays . What is it that the relay does differently for reliable=true vs false?

@ianswett ianswett added the Transmission Issues involving what to transmit when, what to drop, priorities, etc label Mar 18, 2024
ianswett added a commit that referenced this issue May 27, 2024
Takes an opinionated approach to adding 'Fetch' style functionality within the existing mechanisms.

Can be improved once various TTL/etc PRs land.  For example, we can add a 3rd mode where In Order is preferred within a client specified Delivery Timeout. (#449).

Pulls in concepts from #428 

Fixes #269
Fixes #326
Fixes #350

Closes #421
ianswett added a commit that referenced this issue Jul 3, 2024
…ority (#470)

Adds a SUBSCRIBER_PRIORITY param that can be specified in SUBSCRIBE or
SUBSCRIBE_UPDATE to indicate subscriber priority. Adds Group Order to
SUBSCRIBE to allow indicating Ascending or Descending. Cleans up the
existing priorities section and how Original Subscriber driven
priorities are used.

Fixes #326 
Fixes #396 
Fixes #403
Fixes #419 

Closes #445
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Discussion Tags for issues which need discussion, ideally at an interim or IETF meeting. Transmission Issues involving what to transmit when, what to drop, priorities, etc
Projects
None yet
6 participants