Track Switching via the SWITCH_FROM parameter#1674
Conversation
Introduce a new parameter SWITCH_FROM, that can appear in SUBSCRIBE, PUBLISH_OK or REQUEST_UPDATE. The parameter has a Mode enum which can control details of the switching algorithm. The base algorithm and a single "Hard" mode that flips the Forward State are defined. Subsequent PRs will introduce additional modes. The parameter also has a "Publish Done" option which the subscriber uses to control whether the other track is closed or left open after Switch.
sharmafb
left a comment
There was a problem hiding this comment.
Flushing some initial comments.
| responds with REQUEST_ERROR `INVALID_SWITCH`. The resume subscription | ||
| MUST be transitioning from Forward State 0 to 1 as part of the switch; if |
There was a problem hiding this comment.
I think you might want to rephrase this as "The resume subscription MUST either be a new subscription with a Forward State of 1 or be transitioning from Forward State 0 to 1 as part of the switch". The existing sentence applies for REQUEST_UPDATE, but not for new subscriptions.
| responds with REQUEST_ERROR `INVALID_SWITCH`. The resume subscription | ||
| MUST be transitioning from Forward State 0 to 1 as part of the switch; if | ||
| it already has Forward State 1, or the message carrying SWITCH_FROM has | ||
| FORWARD = 0, the publisher responds with REQUEST_ERROR `INVALID_SWITCH`. |
There was a problem hiding this comment.
I think you might want to update the wording under the "Updating Subscriptions" section of the spec, which says: "When a REQUEST_UPDATE is unsuccessful, the publisher MUST also terminate the subscription by sending a PUBLISH_DONE with error code UPDATE_FAILED". This kind of contradicts that section.
There was a problem hiding this comment.
See Ian's point above, we could also remove this as an error condition.
| * Mode Hard (0x0): sets Forward State 0 on the suspend subscription. If | ||
| Publish Done is 1, the publisher also sends PUBLISH_DONE. |
There was a problem hiding this comment.
Which status code should be used in the PUBLISH_DONE message? How about we define a new status code SWITCHING_AWAY?
There was a problem hiding this comment.
Does this change in Forward state get communicated via REQUEST_UPDATE?
There was a problem hiding this comment.
Does this change in Forward state get communicated via REQUEST_UPDATE?
Not presently. See above.
| it already has Forward State 1, or the message carrying SWITCH_FROM has | ||
| FORWARD = 0, the publisher responds with REQUEST_ERROR `INVALID_SWITCH`. | ||
|
|
||
| 2. Sets resume to Forward State 1 and applies the SUBSCRIPTION_FILTER. This |
There was a problem hiding this comment.
| 2. Sets resume to Forward State 1 and applies the SUBSCRIPTION_FILTER. This | |
| 2. Sets the resume Subscription to Forward State 1 and applies the SUBSCRIPTION_FILTER. This |
| * Mode Hard (0x0): sets Forward State 0 on the suspend subscription. If | ||
| Publish Done is 1, the publisher also sends PUBLISH_DONE. |
There was a problem hiding this comment.
Does this change in Forward state get communicated via REQUEST_UPDATE?
| 6. Responds with SUBSCRIBE_OK or REQUEST_OK as appropriate, including | ||
| LARGEST_OBJECT if the SUBSCRIPTION_FILTER is a fill filter type. | ||
|
|
||
| If the publisher times out waiting to be ready to publish an object from the |
| Switch From Request ID (vi64), | ||
| Mode (vi64), | ||
| Publish Done (1), | ||
| Reserved (7), |
There was a problem hiding this comment.
Should we call it 'Reserved bits' or 'Reserved flags' to be clearer?
| responds with REQUEST_ERROR `INVALID_SWITCH`. The resume subscription | ||
| MUST be transitioning from Forward State 0 to 1 as part of the switch; if | ||
| it already has Forward State 1, or the message carrying SWITCH_FROM has | ||
| FORWARD = 0, the publisher responds with REQUEST_ERROR `INVALID_SWITCH`. |
There was a problem hiding this comment.
See Ian's point above, we could also remove this as an error condition.
| * Mode Hard (0x0): sets Forward State 0 on the suspend subscription. If | ||
| Publish Done is 1, the publisher also sends PUBLISH_DONE. |
There was a problem hiding this comment.
Does this change in Forward state get communicated via REQUEST_UPDATE?
Not presently. See above.
| 6. Responds with SUBSCRIBE_OK or REQUEST_OK as appropriate, including | ||
| LARGEST_OBJECT if the SUBSCRIPTION_FILTER is a fill filter type. | ||
|
|
||
| If the publisher times out waiting to be ready to publish an object from the |
There was a problem hiding this comment.
| If the publisher times out waiting to be ready to publish an object from the | |
| If the publisher times out waiting to publish an object from the |
| Switch From Request ID (vi64), | ||
| Mode (vi64), | ||
| Publish Done (1), | ||
| Reserved (7), |
There was a problem hiding this comment.
RFC 9000 uses Reserved Bits
| Reserved (7), | |
| Reserved Bits (7), |
- Use "activating/suspending" instead of "resume/suspend" - In hard mode cancel all outstanding streams - Make including FORWARD a request error, and note it's not an error if suspending is already stopped - Other feedback
fluffy
left a comment
There was a problem hiding this comment.
There is some small clarification changes I think we should make but I'm also fine with merging as is and doing the rest later. I think the basic mechanism proposed here is fine and glad to see it merged in to main draft. If we do merge without fixing the things I brought up, I would ask we opened issue for the ones the editors agree with.
| subscription is in Forward State 0. | ||
|
|
||
| 2. Sets the activating subscription to Forward State 1 and applies the | ||
| SUBSCRIPTION_FILTER. This ensures objects after the Current Group are not |
There was a problem hiding this comment.
at this point in the text, it's not clear to me what SUBSCRIPTION_FILTER we are talking about. I think we just need bit more clarification text, perhaps above this numbered list, to explain the filter part.
| computed from the activating track at the time the request is received, while | ||
| continuing to deliver objects on the suspending subscription. When GROUP_ORDER | ||
| is Descending and Start Group is before the Current Group, the publisher | ||
| waits for the first object in the largest fill group instead. |
There was a problem hiding this comment.
Could we just remove the support for Descending here? Any use case that needs it ? Do it in later PR ? My issue is thinking about how implementations are going to buffer waiting for largetst fill group sounds painful. I don't think about Descending much so I may have this wrong but it does not seem like this case even makes any sense in hard mode. Can it be in a different mode.
There was a problem hiding this comment.
The nature of Descending is that it makes one's head hurt. Anyone whose head is not hurting just hasn't tried to implement it yet.
I don't the the utility of Descending mode is different in Hard vs Soft switch, since it's about the activating subscription "Do I have the first requested object ready yet". I don't think it's any more complicated than Descending support in general -- if you have a cache, then you likely have the object (it's from a more recent group) and if you don't you can issue a Descending FETCH upstream. There shouldn't be a "buffer incoming objects" case?
There was a problem hiding this comment.
Discussed on 7/6 - Descending needs to be supported.
|
|
||
| ### Relay Handling of SWITCH_FROM {#relay-switch-from} | ||
|
|
||
| When a relay receives a message containing SWITCH_FROM, it MUST NOT forward the |
There was a problem hiding this comment.
I think we need a SHOULD NOT instead of MUST NOT. We do the same thing for other things where a local wifi relay that is one the downstream side of a congested WAN link probably would want to forward this upstream.
| track switching (e.g., ABR quality changes, alternate camera angles, or meeting | ||
| participants) without tearing down subscriptions or issuing standalone fetches. | ||
|
|
||
| On receiving a message containing SWITCH_FROM, the publisher: |
There was a problem hiding this comment.
Are all publishers required to support this or just relays ? I think it would be best to have it like it is that everything needs to support this but I can imaging lots of end user clients that are original publishers uploading video might not want to support this. Also - I am happy if we merge this PR without solving this and just raise this as an open issue that can be dealt with later.
There was a problem hiding this comment.
Discussed 7/6 - no one raised a significant objection to all publishers having to support this.
| including the SWITCH_FROM parameter ({{switch-from}}) in a SUBSCRIBE or | ||
| REQUEST_UPDATE on the activating subscription's request stream. This enables | ||
| track switching (e.g., ABR quality changes, alternate camera angles, or meeting | ||
| participants) without tearing down subscriptions or issuing standalone fetches. |
There was a problem hiding this comment.
I think it would be best to define the IANA table for types of switches in PR and have just one entry in it of hard but that sets up the structure for later PRs.
|
This should be rebased onto main |
| computed from the activating track at the time the request is received, while | ||
| continuing to deliver objects on the suspending subscription. When GROUP_ORDER | ||
| is Descending and Start Group is before the Current Group, the publisher | ||
| waits for the first object in the largest fill group instead. |
There was a problem hiding this comment.
Discussed on 7/6 - Descending needs to be supported.
| track switching (e.g., ABR quality changes, alternate camera angles, or meeting | ||
| participants) without tearing down subscriptions or issuing standalone fetches. | ||
|
|
||
| On receiving a message containing SWITCH_FROM, the publisher: |
There was a problem hiding this comment.
Discussed 7/6 - no one raised a significant objection to all publishers having to support this.
| ## Track Switching {#track-switching} | ||
|
|
||
| A subscriber can atomically stop delivery on one subscription (the suspending | ||
| subscription) and start delivery on another (the activating subscription) by |
There was a problem hiding this comment.
nit: add italics for "suspending"/"activating" terms.
Actually, shouldn't it be "suspended" and not "suspending"? "Suspending" implies it's the subscription that has caused suspension, not the one being suspended.
There was a problem hiding this comment.
Italics is a good call. At the beginning of the switch, the suspending stream is active and the activating stream is not, so I think "-ing" is correct.
|
|
||
| 4. Stops delivery on the suspending subscription: | ||
|
|
||
| * Mode Hard (0x0): sets Forward State 0 on the suspending subscription. If |
There was a problem hiding this comment.
"Immediate"? "Hard" seems like a vague term in absence of other modes.
|
|
||
| 2. Sets the activating subscription to Forward State 1 and applies the | ||
| current SUBSCRIPTION_FILTER. This ensures objects after the Current Group | ||
| are not missed. |
There was a problem hiding this comment.
Since this already depending on fill-fetch, maybe "applies the current filter" -> "creates fill-fetch streams as appopriate"? Otherwise it sounds ambiguous as to what we're actually doing.
| the resuming subscription's Request ID (see {{fill-semantics}}), if necessary. | ||
|
|
||
| 6. Responds with SUBSCRIBE_OK or REQUEST_OK as appropriate, including | ||
| LARGEST_OBJECT if the SUBSCRIPTION_FILTER is a fill filter type. |
There was a problem hiding this comment.
I assume that for modes that do not immediately Forward=0 the old subscription, steps 5 and 6 would come before step 4.
|
|
||
| ### SWITCH_FROM Parameter {#switch-from} | ||
|
|
||
| The SWITCH_FROM parameter (Parameter Type 0x24) consists of a varint Switch |
There was a problem hiding this comment.
Shouldn't the parameter type be an odd value?
There was a problem hiding this comment.
Parameters no longer use the even/odd distinction for varint/length prefixed. Each parameter has a bespoke format that must be known in order to parse it.
There was a problem hiding this comment.
I missed that change, my bad. I was still thinking of message parameters as KVPs.
Introduce a new parameter SWITCH_FROM, that can appear in SUBSCRIBE, PUBLISH_OK or REQUEST_UPDATE. The parameter has a Mode enum which can control details of the switching algorithm. The base algorithm and a single "Hard" mode that flips the Forward State are defined. Subsequent PRs will introduce additional modes.
The parameter also has a "Publish Done" option which the subscriber uses to control whether the other track is closed or left open after Switch.
See #1354
Fixes #1519