mirror of
https://github.com/pion/webrtc.git
synced 2025-12-24 11:51:03 +08:00
Fixes for pre-added recvonly transceivers
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.
This commit is contained in:
@@ -1044,7 +1044,8 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
|
||||
}
|
||||
}
|
||||
|
||||
if t == nil {
|
||||
switch {
|
||||
case t == nil:
|
||||
receiver, err := pc.api.NewRTPReceiver(kind, pc.dtlsTransport)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1058,10 +1059,14 @@ func (pc *PeerConnection) SetRemoteDescription(desc SessionDescription) error {
|
||||
t = pc.newRTPTransceiver(receiver, nil, localDirection, kind)
|
||||
|
||||
pc.onNegotiationNeeded()
|
||||
} else if direction == RTPTransceiverDirectionRecvonly {
|
||||
case direction == RTPTransceiverDirectionRecvonly:
|
||||
if t.Direction() == RTPTransceiverDirectionSendrecv {
|
||||
t.setDirection(RTPTransceiverDirectionSendonly)
|
||||
}
|
||||
case direction == RTPTransceiverDirectionSendrecv:
|
||||
if t.Direction() == RTPTransceiverDirectionSendonly {
|
||||
t.setDirection(RTPTransceiverDirectionSendrecv)
|
||||
}
|
||||
}
|
||||
|
||||
if t.Mid() == "" {
|
||||
|
||||
@@ -60,6 +60,85 @@ func sdpMidHasSsrc(offer SessionDescription, mid string, ssrc SSRC) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func TestPeerConnection_Renegotiation_AddRecvonlyTransceiver(t *testing.T) {
|
||||
type testCase struct {
|
||||
name string
|
||||
answererSends bool
|
||||
}
|
||||
|
||||
testCases := []testCase{
|
||||
// Assert the following behaviors:
|
||||
// - Offerer can add a recvonly transceiver
|
||||
// - During negotiation, answerer peer adds an inactive (or sendonly) transceiver
|
||||
// - Offerer can add a track
|
||||
// - Answerer can receive the RTP packets.
|
||||
{"add recvonly, then receive from answerer", false},
|
||||
// Assert the following behaviors:
|
||||
// - Offerer can add a recvonly transceiver
|
||||
// - During negotiation, answerer peer adds an inactive (or sendonly) transceiver
|
||||
// - Answerer can add a track to the existing sendonly transceiver
|
||||
// - Offerer can receive the RTP packets.
|
||||
{"add recvonly, then send to answerer", true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
lim := test.TimeOut(time.Second * 30)
|
||||
defer lim.Stop()
|
||||
|
||||
report := test.CheckRoutines(t)
|
||||
defer report()
|
||||
|
||||
pcOffer, pcAnswer, err := newPair()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = pcOffer.AddTransceiverFromKind(
|
||||
RTPCodecTypeVideo,
|
||||
RtpTransceiverInit{
|
||||
Direction: RTPTransceiverDirectionRecvonly,
|
||||
},
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.NoError(t, signalPair(pcOffer, pcAnswer))
|
||||
|
||||
localTrack, err := NewTrackLocalStaticSample(
|
||||
RTPCodecCapability{MimeType: "video/VP8"}, "track-one", "stream-one",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
if tc.answererSends {
|
||||
_, err = pcAnswer.AddTrack(localTrack)
|
||||
} else {
|
||||
_, err = pcOffer.AddTrack(localTrack)
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
onTrackFired, onTrackFiredFunc := context.WithCancel(context.Background())
|
||||
|
||||
if tc.answererSends {
|
||||
pcOffer.OnTrack(func(track *TrackRemote, r *RTPReceiver) {
|
||||
onTrackFiredFunc()
|
||||
})
|
||||
} else {
|
||||
pcAnswer.OnTrack(func(track *TrackRemote, r *RTPReceiver) {
|
||||
onTrackFiredFunc()
|
||||
})
|
||||
}
|
||||
|
||||
assert.NoError(t, signalPair(pcOffer, pcAnswer))
|
||||
|
||||
sendVideoUntilDone(onTrackFired.Done(), t, []*TrackLocalStaticSample{localTrack})
|
||||
|
||||
closePairNow(t, pcOffer, pcAnswer)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Assert the following behaviors
|
||||
* - We are able to call AddTrack after signaling
|
||||
|
||||
@@ -115,6 +115,12 @@ func (t *RTPTransceiver) setSendingTrack(track TrackLocal) error {
|
||||
t.setDirection(RTPTransceiverDirectionSendonly)
|
||||
case track == nil && t.Direction() == RTPTransceiverDirectionSendrecv:
|
||||
t.setDirection(RTPTransceiverDirectionRecvonly)
|
||||
case track != nil && t.Direction() == RTPTransceiverDirectionSendonly:
|
||||
// Handle the case where a sendonly transceiver was added by a negotiation
|
||||
// initiated by remote peer. For example a remote peer added a transceiver
|
||||
// with direction recvonly.
|
||||
case track != nil && t.Direction() == RTPTransceiverDirectionSendrecv:
|
||||
// Similar to above, but for sendrecv transceiver.
|
||||
case track == nil && t.Direction() == RTPTransceiverDirectionSendonly:
|
||||
t.setDirection(RTPTransceiverDirectionInactive)
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user