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.
In some rare cases during ice connection stage
change may result in deadlock. This fix makes
iceConnectionState and connectionState atomic
which should prevent deadlock.
now proctected by lock:
- CreateOffer
- CreateAnswer
- AddTransceiverFromKind
- AddTransceiverFromTrack
newRTPTransceiver is no longer a PeerConnection method;
pc.addRTPTransceiver would fire onNegotiationNeeded;
pc.AddTrack, pc.RemoveTrack now hold lock for the entire function;
Fixes TestNegotiationNeededStressOneSided() by waiting til all
tracks added to pcA and the negotiation completed
CurrentRemoteDescription and PendingRemoteDescription both access
members of the PeerConnection that should be protected by a lock.
Co-authored-by: Markus Tzoe <chou.marcus@gmail.com>
in CurrentLocalDescription() or PendingLocalDescription():
when gathering local candidates in populateLocalCandidates(),
agent would try submitting a task via run():
a.chanTask <- task
the chanTask is consumed by a bg routine using taskLoop():
for {
select {
case <-a.done:
return
case t := <-a.chanTask:
t.fn(a.context(), a)
close(t.done)
after()
}
}
while there're other routines using the agent, e.g. calling
`agent.updateConnectionState()`
a.afterRun(func(ctx context.Context) {
a.chanState <- newState
})
and the submitted task would be run by the `after()` func in
`taskLoop()`, where the `a.chanState` is handled by
`agent.startOnConnectionStateChangeRoutine()`
this `after()` task may block the bg routine when there's ongoing
event handler `agent.onConnectionStateChange()`, which would
eventually call PeerConnection's onICEConnectionStateChange():
pc.mu.Lock()
pc.iceConnectionState = cs
handler := pc.onICEConnectionStateChangeHandler
pc.mu.Unlock()
which would try to hold the PeerConnection lock, causing deadlock
Use fine granularity rw-mutex to protect rtpTransceivers and for
exclusively accessing AddTrack and RemoveTrack
Fixes `shouldAddCandidates` typo in sdp.go
Which were previously unable to:
1. have a sending track set to them, or
2. receive a track after renegotiation.
I'm not 100% sure if this covers all cases where a track is added and
removed and then added again. BUT IIRC there was a change that did not
allow transceiver reuse after a track was removed from it. Again, not
100% sure.
Fixes#1722.
When a local peer connection has a single transceiver with a sendrecv
direction, and the remote has a transceiver with a recvonly direction,
the local peer connection must change the transceiver direction to
sendonly.
When a local peer connection has a single transceiver with a recvonly
direction, and the remote has a transceiver with a recvonly direction,
the local peer connection must create another transceiver with a
sendonly direction.
A unit test is added to cover all possible cases.
If an API is shared between PeerConnections they would use the same
MediaEngine. A MediaEngine contains negotiated PayloadTypes so if the
PeerConnections were answering you would end up in invalid states.
Add DisableMediaEngineCopy to SettingEngine in case user needs old
behavior.
Resolves#1662
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
When a new SSRC is seen we start a Read loop for the packets. However if
we only see one packet this loop will just sit forever. If a user
doesn't send us enough packets to finish probing it will prevent any
subsequent streams from being probed.
Relates to #1345
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
* Return error to user when remote doesn't support codecs
* Assert that bindings are properly incremented/decremented
* Assert that a added track doesn't error even when disconnected
Relates to #1526