Skip to content

Track Switching via the SWITCH_FROM parameter#1674

Open
afrind wants to merge 4 commits into
fill-fetchfrom
switch-from-with-enum
Open

Track Switching via the SWITCH_FROM parameter#1674
afrind wants to merge 4 commits into
fill-fetchfrom
switch-from-with-enum

Conversation

@afrind

@afrind afrind commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

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

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.
@afrind afrind added the Design Issues or PRs that change how MoQ works including the wire format. label Jun 15, 2026

@sharmafb sharmafb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flushing some initial comments.

Comment thread draft-ietf-moq-transport.md Outdated
Comment on lines +1683 to +1684
responds with REQUEST_ERROR `INVALID_SWITCH`. The resume subscription
MUST be transitioning from Forward State 0 to 1 as part of the switch; if

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread draft-ietf-moq-transport.md Outdated
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`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See Ian's point above, we could also remove this as an error condition.

Comment thread draft-ietf-moq-transport.md Outdated
Comment on lines +1700 to +1701
* Mode Hard (0x0): sets Forward State 0 on the suspend subscription. If
Publish Done is 1, the publisher also sends PUBLISH_DONE.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which status code should be used in the PUBLISH_DONE message? How about we define a new status code SWITCHING_AWAY?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change in Forward state get communicated via REQUEST_UPDATE?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change in Forward state get communicated via REQUEST_UPDATE?

Not presently. See above.

@afrind afrind added the Switch Issues related to the SWITCH proposal label Jun 18, 2026
Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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

Comment thread draft-ietf-moq-transport.md Outdated
Comment on lines +1700 to +1701
* Mode Hard (0x0): sets Forward State 0 on the suspend subscription. If
Publish Done is 1, the publisher also sends PUBLISH_DONE.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change in Forward state get communicated via REQUEST_UPDATE?

Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be ready?

Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
Switch From Request ID (vi64),
Mode (vi64),
Publish Done (1),
Reserved (7),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we call it 'Reserved bits' or 'Reserved flags' to be clearer?

Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
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`.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See Ian's point above, we could also remove this as an error condition.

Comment thread draft-ietf-moq-transport.md Outdated
Comment on lines +1700 to +1701
* Mode Hard (0x0): sets Forward State 0 on the suspend subscription. If
Publish Done is 1, the publisher also sends PUBLISH_DONE.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change in Forward state get communicated via REQUEST_UPDATE?

Not presently. See above.

Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
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

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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

Comment thread draft-ietf-moq-transport.md Outdated
Switch From Request ID (vi64),
Mode (vi64),
Publish Done (1),
Reserved (7),

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RFC 9000 uses Reserved Bits

Suggested change
Reserved (7),
Reserved Bits (7),

Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
@afrind afrind mentioned this pull request Jun 27, 2026
- 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 fluffy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread draft-ietf-moq-transport.md Outdated
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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed on 7/6 - Descending needs to be supported.

Comment thread draft-ietf-moq-transport.md Outdated

### Relay Handling of SWITCH_FROM {#relay-switch-from}

When a relay receives a message containing SWITCH_FROM, it MUST NOT forward the

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@fluffy

fluffy commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

This should be rebased onto main

Comment thread draft-ietf-moq-transport.md Outdated
Comment thread draft-ietf-moq-transport.md Outdated
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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed 7/6 - no one raised a significant objection to all publishers having to support this.

@vasilvv vasilvv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to overall look good; some comments, plus a note that this depends on text in #1763.

## 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the parameter type be an odd value?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed that change, my bad. I was still thinking of message parameters as KVPs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Design Issues or PRs that change how MoQ works including the wire format. Switch Issues related to the SWITCH proposal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants