Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit 09bd9ba

Browse files
Harald AlvestrandCommit Bot
authored andcommitted
Allow transceivers to be not found in more cases.
This fixes the case where a media section is rejected in an answer, something that is done by SFUs, but not possible using transceiver.stop(). Bug: chromium:1134686 Change-Id: Ia33579070093ab70c4191710fd1dcb3ca377befd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/187349 Reviewed-by: Henrik Boström <[email protected]> Commit-Queue: Harald Alvestrand <[email protected]> Cr-Commit-Position: refs/heads/master@{#32363}
1 parent 38e9b06 commit 09bd9ba

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

pc/peer_connection_rtp_unittest.cc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,28 @@ class PeerConnectionRtpTestUnifiedPlan : public PeerConnectionRtpBaseTest {
164164
protected:
165165
PeerConnectionRtpTestUnifiedPlan()
166166
: PeerConnectionRtpBaseTest(SdpSemantics::kUnifiedPlan) {}
167+
168+
// Helper to emulate an SFU that rejects an offered media section
169+
// in answer.
170+
bool ExchangeOfferAnswerWhereRemoteStopsTransceiver(
171+
PeerConnectionWrapper* caller,
172+
PeerConnectionWrapper* callee,
173+
size_t mid_to_stop) {
174+
auto offer = caller->CreateOffer();
175+
caller->SetLocalDescription(CloneSessionDescription(offer.get()));
176+
callee->SetRemoteDescription(std::move(offer));
177+
EXPECT_LT(mid_to_stop, callee->pc()->GetTransceivers().size());
178+
// Must use StopInternal in order to do instant reject.
179+
callee->pc()->GetTransceivers()[mid_to_stop]->StopInternal();
180+
auto answer = callee->CreateAnswer();
181+
EXPECT_TRUE(answer);
182+
bool set_local_answer =
183+
callee->SetLocalDescription(CloneSessionDescription(answer.get()));
184+
EXPECT_TRUE(set_local_answer);
185+
bool set_remote_answer = caller->SetRemoteDescription(std::move(answer));
186+
EXPECT_TRUE(set_remote_answer);
187+
return set_remote_answer;
188+
}
167189
};
168190

169191
// These tests cover |webrtc::PeerConnectionObserver| callbacks firing upon
@@ -1573,6 +1595,42 @@ TEST_F(PeerConnectionRtpTestUnifiedPlan,
15731595
EXPECT_EQ(0U, callee->pc()->GetReceivers().size());
15741596
}
15751597

1598+
TEST_F(PeerConnectionRtpTestUnifiedPlan,
1599+
SetLocalDescriptionWorksAfterRepeatedAddRemove) {
1600+
auto caller = CreatePeerConnection();
1601+
auto callee = CreatePeerConnection();
1602+
auto video_track = caller->CreateVideoTrack("v");
1603+
auto track = caller->CreateAudioTrack("a");
1604+
caller->AddTransceiver(video_track);
1605+
auto transceiver = caller->AddTransceiver(track);
1606+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1607+
caller->pc()->RemoveTrack(transceiver->sender());
1608+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1609+
caller->AddTrack(track);
1610+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1611+
caller->pc()->RemoveTrack(transceiver->sender());
1612+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1613+
}
1614+
1615+
// This is a repro of Chromium bug https://crbug.com/1134686
1616+
TEST_F(PeerConnectionRtpTestUnifiedPlan,
1617+
SetLocalDescriptionWorksAfterRepeatedAddRemoveWithRemoteReject) {
1618+
auto caller = CreatePeerConnection();
1619+
auto callee = CreatePeerConnection();
1620+
auto video_track = caller->CreateVideoTrack("v");
1621+
auto track = caller->CreateAudioTrack("a");
1622+
caller->AddTransceiver(video_track);
1623+
auto transceiver = caller->AddTransceiver(track);
1624+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1625+
caller->pc()->RemoveTrack(transceiver->sender());
1626+
ExchangeOfferAnswerWhereRemoteStopsTransceiver(caller.get(), callee.get(), 1);
1627+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1628+
caller->AddTrack(track);
1629+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1630+
caller->pc()->RemoveTrack(transceiver->sender());
1631+
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
1632+
}
1633+
15761634
// Test that AddTransceiver fails if trying to use unimplemented RTP encoding
15771635
// parameters with the send_encodings parameters.
15781636
TEST_F(PeerConnectionRtpTestUnifiedPlan,

pc/sdp_offer_answer.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2871,17 +2871,16 @@ RTCError SdpOfferAnswerHandler::UpdateTransceiversAndDataChannels(
28712871
old_remote_content =
28722872
&old_remote_description->description()->contents()[i];
28732873
}
2874-
// In the case where an m-section has completed its rejection,
2875-
// and is not being reused, we do not expect a transceiver.
2876-
if (old_local_content && old_local_content->rejected &&
2877-
old_remote_content && old_remote_content->rejected &&
2878-
new_content.rejected) {
2879-
continue;
2880-
}
28812874
auto transceiver_or_error =
28822875
AssociateTransceiver(source, new_session.GetType(), i, new_content,
28832876
old_local_content, old_remote_content);
28842877
if (!transceiver_or_error.ok()) {
2878+
// In the case where a transceiver is rejected locally, we don't
2879+
// expect to find a transceiver, but might find it in the case
2880+
// where state is still "stopping", not "stopped".
2881+
if (new_content.rejected) {
2882+
continue;
2883+
}
28852884
return transceiver_or_error.MoveError();
28862885
}
28872886
auto transceiver = transceiver_or_error.MoveValue();
@@ -2946,8 +2945,9 @@ SdpOfferAnswerHandler::AssociateTransceiver(
29462945
transceiver = transceivers().FindByMLineIndex(mline_index);
29472946
}
29482947
if (!transceiver) {
2948+
// This may happen normally when media sections are rejected.
29492949
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
2950-
"Unknown transceiver");
2950+
"Transceiver not found based on m-line index");
29512951
}
29522952
} else {
29532953
RTC_DCHECK_EQ(source, cricket::CS_REMOTE);

0 commit comments

Comments
 (0)