#### 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
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
Pion extracts them from ssrc-group line so this didn't failed
Pion<->Pion. Chrome/FireFox uses the dedicated a=ssrc lines and our
Offer/Answer would break negotation
Fixes#2922
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
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
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.
Always handle header extensions from packet read
from interceptor, let interceptor has consistent
chance to process headers
Fix rtx is not negotiated when there is multiple
codecs has same mime but different profile (H264)
Fix rtx stream info missed when SSRC group attr
shows after base track's ssrc attr.
Before a SessionDescription was assumed to be Plan-B if it contained a
MediaName of `audio` or `video`. This PR Changes that behavior.
If SDPSemantics is UnifiedPlan the SessionDescription must contain a
MediaDescription with two SSRCes to be considered a Plan-B. Before if
the MediaDescription had name of `audio` or `video` it was assumed to be
Plan-B.
If SDPSemantics is PlanB or UnifiedPlanWithFallback it maintains the
existing behavior.
Resolves#2193
The result of strconv.Atoi uses an architecture dependent bit size. It
is not safe to use when converted to an integer type of a smaller size,
without performing bounds checking.
Instead, use Parse(U)int with the desired base and size. Though this
returns a (u)int64, it can then be safely converted into a (u)int8 etc.
When running the reflect example against Firefox 99.0.1 I was receiving
errors around parsing the SDP from Pion.
The error was:
SIPCC Failed to parse SDP: SDP Parse Error on line 50: c= connection
line not specified for every media level, validation failed.
According to the RFC
[4566 5.7](https://datatracker.ietf.org/doc/html/rfc4566#section-5.7)
A session description MUST contain either at least one "c=" field in
each media description or a single "c=" field at the session level.
It MAY contain a single session-level "c=" field and additional "c="
field(s) per media description, in which case the per-media values
override the session-level settings for the respective media.
I don't see any errors in the Pion repos for this. Interestingly the
webrtc-rs project that is porting Pion to rust has
[an issue](https://github.com/webrtc-rs/webrtc/issues/144)
where they're encountering this same error.
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.
When creating answer, check ICE role while determining DTLS role.
ORTC thread on how roles are set
https://github.com/w3c/ortc/issues/167#issuecomment-69409953
When remote is ice-lite and there is no answering role set,
the answer uses the default which is DTLS client. So 'setup'
is set as 'active' and answer sent.
But, when DTLS transport is started, it checks the ICE role
and sets itself as DTLS server (because remote is lite
and hence local agent becomes controlling ICE agent).
So, both sides end up being DTLS server and nobody sends
client hello.
If the SRTP Stream hasn't been opened yet we would attempt to process
(and fail) RTP traffic. This change causes us to not even attempt to
read.
No behavior change from this, but will cause less useless logging.
Do the set up of RTP receivers synchronously so that they
are ready to receive media as soon as signalling to remote
side is sent. Once signalling to remote side is sent, the
remote can send media at any time and receiver has to be ready.
Like the bug mentions, a negotiation quickly followed by
a renegotiation left the RTP receivers of the tracks in the
second offer not set up. If the tracks in the renegotiation
happen to be simulcast tracks, they are missed as browsers
send RID only in the first few packets.
The problem can be reproduced by introducing a 1 second
delay in Downstream direction in Network Link Conditioner
and using a modified version of LiveKit JS SDK sample app to
force a double negotiation spaced closely.
With this change, onTrack fires, but the unhandled warning
from RTCP for the highest layer still happens. But, the
track fires almost immediately following that warning
(less than 5 ms later). So, all the simulcast layers
are available.
Resolves#2054
rfc8839#section-5.1 specifies that a WebRTC Agent MUST
ignore any name/value pairs it doesn't understand. When
we parse a candidate and it fails because we don't understand
the type we now log and continue.
Resolvespion/webrtc#1949
rfc8839#section-5.1 specifies that a WebRTC Agent MUST
ignore any name/value pairs it doesn't understand. When
we parse a candidate and it fails because we don't understand
the type we now log and continue.
Resolvespion/webrtc#1949
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.
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
Previously we could have situations where during
first condition like `transceiver.Sender() != nil`
there would be another condition like
`transceiver.Sender().isNegotiated()` where
`.Sender()` could become nil if changed in
a different goroutine.
Use fine granularity rw-mutex to protect rtpTransceivers and for
exclusively accessing AddTrack and RemoveTrack
Fixes `shouldAddCandidates` typo in sdp.go
RegisterHeaderExtension now allows users to enable headers depending on
the type of transceiver that was created.
Also expose GetParameters on RTPSender and RTPReceiver
Co-authored-by: OrlandoCo <luisorlando.co@gmail.com>
Resolves#1554
The use of a BUNDLE transport allows the usage of a single set of
Interactive Connectivity Establishment (ICE)
[I-D.ietf-ice-rfc5245bis] candidates for the whole BUNDLE group.
A given BUNDLE address:port MUST only be associated with a single
BUNDLE group. If an SDP offer or answer contains multiple BUNDLE
groups, the procedures in this specification apply to each group
independently. All RTP-based bundled media associated with a given
BUNDLE group belong to a single RTP session [RFC3550].