Before this change, if the SDP offer has paused rids,
SDP answer echoed it back. That causes issues where enabling/disabling
of layers is signalled via the signalling channel. The following
scenario breaks
1. PeerB signals PeerA to disable all simulcast layers.
2. PeerA sends an SDP offer with RIDs disabled.
a. NOTE: A renegotiation is not needed, but happens for a different
reason.
3. PeerB signals again to PeerA to re-enable layers.
4. PeerB sends answer for the offer in Step 2 with paused rids.
5. PeerA keeps layers paused.
Adding a setting engine option to not change existing behaviour. Pause
state of a rid will be ignored if setting is enabled.
As defined in [RFC8839], when an ICE restart occurs, a new SDP offer/answer exchange is triggered. However, as WHIP does not support renegotiation of non-ICE-related SDP information, a WHIP client will not send a new offer when an ICE restart occurs. Instead, the WHIP client and WHIP session will only exchange the relevant ICE information via an HTTP PATCH request as defined in Section 4.3.1 and MUST assume that the previously negotiated non-ICE-related SDP information still applies after the ICE restart.
When performing an ICE restart, the WHIP client MUST include the updated "ice-pwd" and "ice-ufrag" in the SDP fragment of the HTTP PATCH request body as well as the new set of gathered ICE candidates as defined in [RFC8840]. Similar to what is defined in Section 4.3.2, as per [RFC9429], only "m=" sections not marked as bundle-only can gather ICE candidates, so given that the "max-bundle" policy is being used, the SDP fragment will contain only the offerer-tagged "m=" line of the bundle group. A WHIP client sending a PATCH request for performing ICE restart MUST contain an If-Match header field with a field-value of "*" as per Section 13.1.1 of [RFC9110].
Co-authored-by: Joe Turki <git@joeturki.com>
The code currently ignores the first packet when reading Simulcast IDs
from a new SSRC, and probes only subsequent packets. This commit makes
it so that we consider the first packet as well (which we already have
read). Helps if the publisher only sends Simulcast IDs on the first
packet.
Done when creating a transceiver from remote description to respect
codec order preference of remote peer.
There was a recent change to include partial matches which overwrote
same codecs and also rtx was getting magled.
Change it by removing codecs from search space as matches are found so
that a codec match is applied only once.
Also, move RTX matching to separate block to ensure proper RTXes ar
matched.
A follow on to https://github.com/pion/webrtc/pull/3200.
This removes the setting engine flag and uses knowledge
of remote direction to decide if a transceiver can be
re-used for sending.
Refactored the code a bit and moved the check into
RTPTransceiver.isSendAllowed.
Re-did the UT to check for re-use cases.
SetDisableTransceiverReuseInRecvonly controls if a
transceiver is re-used when its current direction is `recvonly`.
This is useful for the following scenario
- Remote side sends `offer` with `sendonly` media section.
- Local side creates transceiver in `SetRemoteDescription`
and sets direction to `recvonly.
- Local side calls `AddTrack`.
- As the current direction is `recvonly`, the transceiver added
above will be re-used. That will set the direction to `sendrecv`
and the generated `answer` will have `sendrecv` for that
media section.
- That answer becomes incompatible as the offerer is using
`sendonly`.
Note that local transceiver will be in `recvonly` for both `sendrecv`
and `sendonly` directions in the media section. If the `offer` did use
`sendrecv`, it is possible to re-use that transceiver for sending.
So, disabling re-use will prohibit re-use in the `sendrecv` case also
and hence is slightly wasteful.
For offerer, if the remote side sends early media
before the remote description (answer) is received,
the undeclared SSRC processor can create a receiver
and that receiver could be left dangling as
transceiver `mid` is not updated from remote
description answer.
Still leaving the simulcast probe path and only
avoiding creating a receiver for non-simulcast path.
Add a flag `handleUndeclaredSSRCWithoutAnswer` to control handling
of early media without SDP answer for non-simulcast tracks.
The default behaviour is to not process early media without SDP answer.
- Remove custom atomicBool implementation
- Replace all atomicBool usages with standard library sync/atomic.Bool
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Return an error if a candidate with a username fragment that does
not match the username fragment in the remote description is added.
This usually indicates that the candidate was generated before the
renegotiation.
Introduces a fallback mechanism to handle undeclared SSRCs from multiple
sections using the RTP stream's payload type. For legacy clients
without MID extension support, it documents the existing behavior for
handling undeclared SSRCs in single media sections.
#### Description
Currently, Pion returns an empty `sdpMid` and a 0 `sdpMLineIndex`. This
PR ensures Pion returns the corresponding `sdpMid` and `sdpMLineIndex`
for ICE candidates for clients that expects it. Fixes trickle issues.
#### Changes
1. `ICECandidates`: New fields `SDPMid` and `SDPMLineIndex`.
2. `ICEGatherer`: `SetMediaStreamIdentification` and return the correct
`SDPMid` and `SDPMLineIndex`.
3. `extractICEDetails`: Return a struct instead of multiple values.
4. `extractICEDetails` refactored the media description selection to a
different function.
5. Added new tests.
#### Reference issue
Fixes https://github.com/pion/webrtc/issues/2690
Fixes https://github.com/pion/webrtc/issues/1833
Close peerconnection on DTLS.CloseNotify
could break ice restart with dtls restart,
when the dtls finger-print changed, the
browser could teardown the old dtlstransport
and establish new one then pion could close
the peerconnection and restart failed. So
browser don't do this and spec also don't
say peerconnection should close when dtls
is closed.
If the MediaEngine contains support for them a SSRC will be generated
appropriately
Co-authored-by: aggresss <aggresss@163.com>
Co-authored-by: Kevin Wang <kevmo314@gmail.com>
Resolves#1989Resolves#1675
Should not reuse transceiver (remove & add track)
in one round negotiation, it cause the transceiver
changes ssrc/id without transit to inactive and the
remote peer connection can't fire track close and
OnTrack event.
Map iteration order is not guaranteed by Go, so it's an error to iterate
over a map in places where maintaining the same ordering is important.
This change replaces the map of simulcastRid{} with an array of the same
type. The simulcastRid{} type is extended to hold the rid-id which
previously was used as the key in the map.
Accesses to the map are replaced with range loops to find the desired
rid-id for each case.
Fixes#2838
handleIncomingSSRC will call streamsForSSRC which
opens rtp/rtcp streams that if unhandled can be
leaked resources. Now we will proactively open
them before calling handleIncomingSSRC and close
then later. In the future it would be better to
do this inside handleIncomingSSRC to protect other
callers.
libwebrtc has started sending media probes on an unannounced SSRC(0).
Currently Pion will ignore this as the SSRC hasn't been declared
explicitly and no RID/MID RTP Headers.
This adds a special case to accept SSRC 0 and Read the RTP packets. This
allows the TWCC reports to properly be generated.
Firefox would send updated header extension
in renegotiation, e.g. publish a track without
simucalst then renegotiate second track with
simucalst, the two media secontions will have
different rtp header extensions in offer. Need
to match remote header extentions for each
media sections to avoid second track publish
failed.