diff --git a/pc/peer_connection_jsep_unittest.cc b/pc/peer_connection_jsep_unittest.cc index 00e202c1b5..f0accf4909 100644 --- a/pc/peer_connection_jsep_unittest.cc +++ b/pc/peer_connection_jsep_unittest.cc @@ -1915,6 +1915,68 @@ TEST_F(PeerConnectionJsepTest, RollbackRestoresMid) { EXPECT_TRUE(callee->SetLocalDescription(std::move(offer))); } +TEST_F(PeerConnectionJsepTest, RollbackRestoresInitSendEncodings) { + auto caller = CreatePeerConnection(); + RtpTransceiverInit init; + init.direction = RtpTransceiverDirection::kSendRecv; + RtpEncodingParameters encoding; + encoding.rid = "hi"; + init.send_encodings.push_back(encoding); + encoding.rid = "mid"; + init.send_encodings.push_back(encoding); + encoding.rid = "lo"; + init.send_encodings.push_back(encoding); + caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init); + auto encodings = + caller->pc()->GetTransceivers()[0]->sender()->init_send_encodings(); + EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer())); + EXPECT_NE(caller->pc()->GetTransceivers()[0]->sender()->init_send_encodings(), + encodings); + EXPECT_TRUE(caller->SetLocalDescription(caller->CreateRollback())); + EXPECT_EQ(caller->pc()->GetTransceivers()[0]->sender()->init_send_encodings(), + encodings); +} + +TEST_F(PeerConnectionJsepTest, RollbackDoesNotAffectSendEncodings) { + auto caller = CreatePeerConnection(); + auto callee = CreatePeerConnection(); + RtpTransceiverInit init; + init.direction = RtpTransceiverDirection::kSendOnly; + RtpEncodingParameters encoding; + encoding.rid = "hi"; + init.send_encodings.push_back(encoding); + encoding.rid = "mid"; + init.send_encodings.push_back(encoding); + encoding.rid = "lo"; + init.send_encodings.push_back(encoding); + caller->AddTransceiver(cricket::MEDIA_TYPE_VIDEO, init); + callee->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); + callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); + caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()); + auto params = caller->pc()->GetTransceivers()[0]->sender()->GetParameters(); + EXPECT_TRUE(params.encodings[0].active); + params.encodings[0].active = false; + caller->pc()->GetTransceivers()[0]->sender()->SetParameters(params); + auto offer = caller->CreateOffer(); + std::string offer_string; + EXPECT_TRUE(offer.get()->ToString(&offer_string)); + std::string simulcast_line = + offer_string.substr(offer_string.find("a=simulcast")); + EXPECT_FALSE(simulcast_line.empty()); + EXPECT_TRUE(caller->SetLocalDescription(std::move(offer))); + EXPECT_TRUE(caller->SetLocalDescription(caller->CreateRollback())); + EXPECT_FALSE(caller->pc() + ->GetTransceivers()[0] + ->sender() + ->GetParameters() + .encodings[0] + .active); + offer = caller->CreateOffer(); + EXPECT_TRUE(offer.get()->ToString(&offer_string)); + EXPECT_EQ(offer_string.substr(offer_string.find("a=simulcast")), + simulcast_line); +} + TEST_F(PeerConnectionJsepTest, RollbackRestoresMidAndRemovesTransceiver) { auto callee = CreatePeerConnection(); callee->AddVideoTrack("a"); diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 293c5cb7e7..1381bf99db 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -1423,8 +1423,15 @@ RTCError SdpOfferAnswerHandler::ApplyLocalDescription( const std::vector& streams = channel->local_streams(); transceiver->internal()->sender_internal()->set_stream_ids( streams[0].stream_ids()); + auto encodings = + transceiver->internal()->sender_internal()->init_send_encodings(); transceiver->internal()->sender_internal()->SetSsrc( streams[0].first_ssrc()); + if (!encodings.empty()) { + transceivers() + ->StableState(transceiver) + ->SetInitSendEncodings(encodings); + } } } } else { @@ -2722,6 +2729,10 @@ RTCError SdpOfferAnswerHandler::Rollback(SdpType desc_type) { transceivers()->Remove(transceiver); } } + if (state.init_send_encodings()) { + transceiver->internal()->sender_internal()->set_init_send_encodings( + state.init_send_encodings().value()); + } transceiver->internal()->sender_internal()->set_transport(nullptr); transceiver->internal()->receiver_internal()->set_transport(nullptr); transceiver->internal()->set_mid(state.mid()); diff --git a/pc/transceiver_list.cc b/pc/transceiver_list.cc index aeb89d6928..63d3e67ad8 100644 --- a/pc/transceiver_list.cc +++ b/pc/transceiver_list.cc @@ -36,6 +36,11 @@ void TransceiverStableState::SetRemoteStreamIdsIfUnset( } } +void TransceiverStableState::SetInitSendEncodings( + const std::vector& encodings) { + init_send_encodings_ = encodings; +} + RtpTransceiverProxyRefPtr TransceiverList::FindBySender( rtc::scoped_refptr sender) const { for (auto transceiver : transceivers_) { diff --git a/pc/transceiver_list.h b/pc/transceiver_list.h index 4364c3c2b2..2eb4313915 100644 --- a/pc/transceiver_list.h +++ b/pc/transceiver_list.h @@ -39,11 +39,17 @@ class TransceiverStableState { void SetMSectionIfUnset(absl::optional mid, absl::optional mline_index); void SetRemoteStreamIdsIfUnset(const std::vector& ids); + void SetInitSendEncodings( + const std::vector& encodings); absl::optional mid() const { return mid_; } absl::optional mline_index() const { return mline_index_; } absl::optional> remote_stream_ids() const { return remote_stream_ids_; } + absl::optional> init_send_encodings() + const { + return init_send_encodings_; + } bool has_m_section() const { return has_m_section_; } bool newly_created() const { return newly_created_; } @@ -51,6 +57,7 @@ class TransceiverStableState { absl::optional mid_; absl::optional mline_index_; absl::optional> remote_stream_ids_; + absl::optional> init_send_encodings_; // Indicates that mid value from stable state has been captured and // that rollback has to restore the transceiver. Also protects against // subsequent overwrites.