The way currently DTLS fingerprints and ICE credentials
are picked is causing interop issues as described in #2621
Peers which don't use Bundle can use different fingerprints
and credentials in each media section. Even though is
not (yet) supported by Pion, receiving an SDP offer from
such a peer is valid.
Additionally if Bundle is being used the group attribute
determines which media section is the master bundle section,
which establishes the transport. Currently Pion always
just uses the first credentials/fingerprint it can find
in the SDP, which results in not spec compliant behavior.
This PR attempts to fix the above issues and make
Pion more spec compliant and interoperable.
Fixes#2621
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
In Go 1.22 and earlier, a ticker needs to be explicitly stopped
when it's no longer useful in order to avoid a resource leak.
In Go 1.23 and later, an orphaned ticker will eventually be
garbage collected, but it's still more thrifty to stop it early.
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.
Fix#2751, updates remote track's rtx ssrc for
simulcast track doesn't contain rtx ssrc in sdp
since readRTX relies on rtx ssrc to determine if
it has a rtx stream.
In the case where a remote track is sending PCMU with payload type 0
checkAndUpdateTrack will fail to update the track codec and params
(because t.PayloadType() is already 0). Add an extra check to handle
this case.
Everytime we receieve a new SSRC we probe it and try to determine the
proper way to handle it. In most cases a Track explicitly declares a
SSRC and a OnTrack is fired. In two cases we don't know the SSRC
ahead of time
* Undeclared SSRC in a single media section (pion/webrtc#880)
* Simulcast
The Undeclared SSRC processing code would run before Simulcast.
If a Simulcast Offer/Answer only contained one Media Section we
would never fire the OnTrack. We would assume it was a failed
Undeclared SSRC processing. This commit fixes the behavior.
This change adapts pion/ice to use a new interface for most network
related operations. The interface was formerly a simple struct vnet.Net
which was originally intended to facilicate testing. By replacing it
with an interface we have greater flexibility and allow users to hook
into the networking stack by providing their own implementation of
the interface.
Introduces AddEncoding method in RTP sender to add simulcast encodings.
Added UTs for AddEncoding.
Also modified the Simulcast send test to use the new API.
If a transceiver is created by remote sdp, then set
prefer codec same as offer peer.
For pion's codec match, it will use exact match
first, and then partial match. If patial match
only, the partial match codecs will become
negotiated codes. So it will be set prefer codec
when only exist partial match. And has same payload.
Add test cast for this.
refer to https://www.w3.org/TR/webrtc/#bib-rfc8829
Problem:
--------
Firefox (testing with Firefox 93) sends an `offer`
with simulcast track which includes both RIDs and SSRCs.
When track details are gathered, RIDs are fetched
using `getRids` which returns a map. A `range` is
done on the returned map and RIDs are appended to
the `rids` array in `trackDetails`.
And then SSRCs are read from SDP and set into the
`ssrcs` array of `trackDetails`.
As map range order is not guaranteed, some times
the RID index and SSRC index in their respective arrays
do not match.
Due to the mismatch, services like ion-sfu which rely
on RID to find the correct spatial layer get confused
and end up forwarding the wrong layer.
Solution(s):
------------
There are three possible solutions I could think of
1. The simplest is to not populate SSRCs in `trackDetails`
if RIDs are available. Let `handleIncomingSSRC` do the
SSRC resolution based on RID.
According to RFC 8853 (https://www.ietf.org/rfc/rfc8853.pdf),
the binding to SSRC should happen using RID.
This is the change I have made in this PR. See testing
below for browsers tested.
2. Look for `simulcast` attribute in SDP and take
the RID ordering from that line in `getRids` if that
attribute is available. If not fall back to `rid` attribute.
Also, change `getRids` to return an array.
But, I cannot find an RFC which defines behaviour when
both RID and SSRC are used in `offer`. The question is,
"Will the `ssrc` attribute ordering match the `rid`
ordering?". If that is not guaranteed, this will run
into trouble.
This should be easy to do though if we want to go down this
route.
3. The hardest option is to change the receiver SSRC based
on RID. But, that makes it too complicated (for example
if we have to change SSRC binding of a receiver based on
received RID, there will be two receivers with the same SSRC
binding unless there is some way to swap bindings of receivers)
Testing:
--------
Tested on Firefox, Firefox 78.15.0esr, Chrome, Ssafari and
ensured that Simulcast sender and receiver are in sync for
rid/ssrc/spatial layer resolution.
Read + Discard packets from the Simulcast repair stream. When a
Simulcast stream is enabled the remote will send packets via the repair
stream for probing. We can't ignore these packets anymore because it
will cause gaps in the feedback reports
Resolves#1957
(*SCTPTransport).generateAndSetDataChannelID performed a double loop to
find the next available data channel ID. This changes that behavior to
generate a lookup map with the taken IDs first, so generating a data
channel ID takes much less time.
Before, it would take more than 1000ms to generate the next data channel
ID once you had roughly 50k of them. Now it only takes 4ms at that same
point.
Fixes#1945
If we have a media section with no SSRC we would fire an OnTrack. This
code now properly ignores a MediaSection that has a rid attribute.
Resolves#1808
It isn't possible to send media if a MediaEngine has no codecs. This
catches a common misconfiguration issues that users find themselves in.
Resolves#1702
Use fine granularity rw-mutex to protect rtpTransceivers and for
exclusively accessing AddTrack and RemoveTrack
Fixes `shouldAddCandidates` typo in sdp.go
ReadDeadline is supported by RTPReceiver but not RTPSender. This
commit attempts to provide similar method for RTPSender.
If SetReadDeadine is called with:
- an empty time.Time: it will clear all previous set deadline.
- a non-empty time.Time: it will abort all pending "ReadRTCP" calls if
the specified time is up.
If the local description keeps getting changed, or in case of a but
in Pion, CreateOffer never terminates, which could cause client software
to hang. Set an arbitrary bound on the number of iterations.
Relates to #1656
pion/srtp requires that all incoming streams are accepted. You
can't close if you have unaccepted streams. At the same time
storeSimulcastStream blocks on taking the DTLSTransport lock.
Move `storeSimulcastStream` into a routine so that all streams can
be accepted and aren't blocked on taking the DTLSTransport lock.
Resolves#1586