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].
Instead of having logic in pion/webrtc and pion/sdp move all logic to
pion/ice. Users of pion/ice don't want to import these packages to use
basic pion/ice functionality.
Extmaps are configured via the SettingEngine. This allows a user
to set arbitrary values, and when answering ids and entries are
properly excluded.
Co-authored-by: Gabor Pongracz <gabor.pongracz@proemergotech.com>
This commit adds an option to put DTLS Fingerprint specification
at the media description level rather then the session description
level. This enhances compatibility with some 3rd party webrtc
implementations (notably Kurento).