diff --git a/peerconnection.go b/peerconnection.go index 668b86a146b..2ed56a054de 100644 --- a/peerconnection.go +++ b/peerconnection.go @@ -379,15 +379,15 @@ func (pc *PeerConnection) checkNegotiationNeeded() bool { //nolint:gocognit for _, t := range pc.rtpTransceivers { // https://www.w3.org/TR/webrtc/#dfn-update-the-negotiation-needed-flag // Step 5.1 - // if t.stopping && !t.stopped { + // if t.stopping && !t.IsStopped() { // return true // } m := getByMid(t.Mid(), localDesc) // Step 5.2 - if !t.stopped && m == nil { + if !t.IsStopped() && m == nil { return true } - if !t.stopped && m != nil { + if !t.IsStopped() && m != nil { // Step 5.3.1 if t.Direction() == RTPTransceiverDirectionSendrecv || t.Direction() == RTPTransceiverDirectionSendonly { descMsid, okMsid := m.Attribute(sdp.AttrKeyMsid) @@ -416,7 +416,7 @@ func (pc *PeerConnection) checkNegotiationNeeded() bool { //nolint:gocognit } } // Step 5.4 - if t.stopped && t.Mid() != "" { + if t.IsStopped() && t.Mid() != "" { if getByMid(t.Mid(), localDesc) != nil || getByMid(t.Mid(), remoteDesc) != nil { return true } @@ -1765,7 +1765,7 @@ func (pc *PeerConnection) AddTrack(track TrackLocal) (*RTPSender, error) { // transceiver can be reused only if it's currentDirection never be sendrecv or sendonly. // But that will cause sdp inflate. So we only check currentDirection's current value, // that's worked for all browsers. - if !t.stopped && t.kind == track.Kind() && t.Sender() == nil && + if !t.IsStopped() && t.kind == track.Kind() && t.Sender() == nil && !(currentDirection == RTPTransceiverDirectionSendrecv || currentDirection == RTPTransceiverDirectionSendonly) { sender, err := pc.api.NewRTPSender(track, pc.dtlsTransport) if err == nil { @@ -2025,9 +2025,7 @@ func (pc *PeerConnection) Close() error { // https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-close (step #4) pc.mu.Lock() for _, t := range pc.rtpTransceivers { - if !t.stopped { - closeErrs = append(closeErrs, t.Stop()) - } + closeErrs = append(closeErrs, t.Stop()) } pc.mu.Unlock() diff --git a/rtptransceiver.go b/rtptransceiver.go index f94b9ed70aa..ca808bd07e4 100644 --- a/rtptransceiver.go +++ b/rtptransceiver.go @@ -21,8 +21,8 @@ type RTPTransceiver struct { codecs []RTPCodecParameters // User provided codecs via SetCodecPreferences - stopped bool - kind RTPCodecType + isStopped *atomicBool + kind RTPCodecType api *API mu sync.RWMutex @@ -35,7 +35,7 @@ func newRTPTransceiver( kind RTPCodecType, api *API, ) *RTPTransceiver { - t := &RTPTransceiver{kind: kind, api: api} + t := &RTPTransceiver{kind: kind, api: api, isStopped: &atomicBool{}} t.setReceiver(receiver) t.setSender(sender) t.setDirection(direction) @@ -150,6 +150,10 @@ func (t *RTPTransceiver) Direction() RTPTransceiverDirection { // Stop irreversibly stops the RTPTransceiver func (t *RTPTransceiver) Stop() error { + if t.isStopped.swap(true) { + return nil + } + if sender := t.Sender(); sender != nil { if err := sender.Stop(); err != nil { return err @@ -166,6 +170,11 @@ func (t *RTPTransceiver) Stop() error { return nil } +// IsStopped returns true if RTPTransceiver is stopped, else returns false +func (t *RTPTransceiver) IsStopped() bool { + return t.isStopped.get() +} + func (t *RTPTransceiver) setReceiver(r *RTPReceiver) { if r != nil { r.setRTPTransceiver(t)