I think pion/webrtc v4.2.11 may generate an invalid answer during renegotiation when the same PeerConnection goes through this sequence:
- publish video track (mid 1, 0 is a data channel)
- unpublish video (remove track and stop tranceiver)
- publish audio (new sdp will remove mid 1 and add mid 2)
- publish video again (mid will be 0 2 3)
In my case, the browser's offer is valid, but the answer generated by Pion reassigns RTP header extension IDs in the new video m-section, and Chrome rejects the answer in
setRemoteDescription().
The browser error is:
InvalidAccessError: Failed to execute 'setRemoteDescription' on 'RTCPeerConnection':
Failed to set remote answer sdp:
Failed to update RTP header extensions for m-section with mid='3'.
RTP extension ID reassignment from urn:ietf:params:rtp-hdrext:sdes:mid
to http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 for ID 4.
### Environment
- github.com/pion/webrtc/v4 v4.2.11
- Browser: Chrome 147
- Scenario: browser publisher -> Pion
### Repro sequence
This happens on the same publish PeerConnection:
1. publish video
2. renegotiate to unpublish that video
3. renegotiate to publish audio
4. renegotiate again to publish video
The important detail is that after step 1 and step 2, the old video m-section still exists historically in the same PC, and later audio/video m-sections use different extmap ID
assignments.
### Offer/answer snippets
Earlier video offer/answer used extmaps like:
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
Later audio and new video offer use:
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
That offer is accepted by browsers.
However, the answer generated by Pion for the new video m-section becomes:
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
So in the same answered m-section:
- id=4 is reassigned from offered sdes:mid to transport-cc
- transport-cc appears twice (id=4 and id=3)
Chrome rejects this answer immediately.
### Why I think this is a Pion issue
My understanding is that this is legal on the offer side, because extmap IDs are scoped per m-section, and different m-sections in the same PC can use different ID->URI mappings.
From reading the v4.2.11 source, my hypothesis is:
- negotiated header extensions are being merged into a PC-global map keyed only by extension ID
- an older video m-section's mapping (for example 4 -> transport-cc, 9 -> sdes:mid) leaks into later audio/video m-sections
- when Pion generates the answer for the later video m-section, it reuses stale extmap assignments from the earlier m-section
So this looks like extmap negotiation state is effectively tracked too globally, instead of per m-section / transceiver.
### Expected behavior
For the new video m-section, the answer should preserve the offer's extmap semantics, for example:
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
### Actual behavior
Pion generates an answer where extmap IDs are reassigned using stale mappings from an earlier m-section, and the browser rejects the answer.
I think
pion/webrtc v4.2.11may generate an invalid answer during renegotiation when the samePeerConnectiongoes through this sequence:In my case, the browser's offer is valid, but the answer generated by Pion reassigns RTP header extension IDs in the new video m-section, and Chrome rejects the answer in
setRemoteDescription().The browser error is: