Simulcast should be disabled if RID header extension is not supported.

Simulcast is disabled if the RIDs are not negotiated.
This change addresses the scenario in which RIDs are negotiated but
support for the RID extension is not negotiated.
In such cases, the RID extension cannot be used, so support for
simulcast should be turned off, as if RIDs were not negotiated.

A similar case can be made for MIDs, however MIDs are not explicitly
specified in simulcast. RIDs are only guaranteed to be  unique within
a media section so it would seem that MIDs should be required.
However, applications supply RID values and can guarantee their
uniqueness, so unlike RIDs, the use of MIDs is not enforced as mandatory.

Bug: webrtc:10075
Change-Id: Ic1b27878ea152eaee43a38bbfda11144307766fe
Reviewed-on: https://webrtc-review.googlesource.com/c/125176
Commit-Queue: Amit Hilbuch <amithi@webrtc.org>
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26934}
This commit is contained in:
Amit Hilbuch
2019-03-01 13:14:46 -08:00
committed by Commit Bot
parent b1ae10b172
commit aabd036ecb
2 changed files with 48 additions and 7 deletions

View File

@ -3060,6 +3060,18 @@ static RTCError UpdateSimulcastLayerStatusInSender(
return result;
}
static bool SimulcastIsRejected(
const ContentInfo* local_content,
const MediaContentDescription& answer_media_desc) {
bool simulcast_offered = local_content &&
local_content->media_description() &&
local_content->media_description()->HasSimulcast();
bool simulcast_answered = answer_media_desc.HasSimulcast();
bool rids_supported = RtpExtension::FindHeaderExtensionByUri(
answer_media_desc.rtp_header_extensions(), RtpExtension::kRidUri);
return simulcast_offered && (!simulcast_answered || !rids_supported);
}
static RTCError DisableSimulcastInSender(
rtc::scoped_refptr<RtpSenderInternal> sender) {
RTC_DCHECK(sender);
@ -3155,12 +3167,7 @@ PeerConnection::AssociateTransceiver(cricket::ContentSource source,
// Check if the offer indicated simulcast but the answer rejected it.
// This can happen when simulcast is not supported on the remote party.
// This check can be simplified to comparing the number of send encodings,
// but that might break legacy implementation in which simulcast is not
// signaled in the remote description.
if (old_local_content && old_local_content->media_description() &&
old_local_content->media_description()->HasSimulcast() &&
!media_desc->HasSimulcast()) {
if (SimulcastIsRejected(old_local_content, *media_desc)) {
RTCError error =
DisableSimulcastInSender(transceiver->internal()->sender_internal());
if (!error.ok()) {

View File

@ -113,7 +113,7 @@ class PeerConnectionSimulcastTests : public testing::Test {
const std::vector<SimulcastLayer>& answer_layers) {
auto offer = local->CreateOfferAndSetAsLocal();
// Remove simulcast as the second peer connection won't support it.
auto removed_simulcast = RemoveSimulcast(offer.get());
RemoveSimulcast(offer.get());
std::string err;
EXPECT_TRUE(remote->SetRemoteDescription(std::move(offer), &err)) << err;
auto answer = remote->CreateAnswerAndSetAsLocal();
@ -461,4 +461,38 @@ TEST_F(PeerConnectionSimulcastTests,
EXPECT_TRUE(ValidateTransceiverParameters(transceiver, expected_layers));
}
TEST_F(PeerConnectionSimulcastTests, NegotiationDoesNotHaveRidExtension) {
auto local = CreatePeerConnectionWrapper();
auto remote = CreatePeerConnectionWrapper();
auto layers = CreateLayers({"1", "2", "3"}, true);
auto expected_layers = CreateLayers({"1"}, true);
auto transceiver = AddTransceiver(local.get(), layers);
auto offer = local->CreateOfferAndSetAsLocal();
// Remove simulcast as the second peer connection won't support it.
RemoveSimulcast(offer.get());
std::string err;
EXPECT_TRUE(remote->SetRemoteDescription(std::move(offer), &err)) << err;
auto answer = remote->CreateAnswerAndSetAsLocal();
// Setup the answer to look like a server response.
// Drop the RID header extension.
auto mcd_answer = answer->description()->contents()[0].media_description();
auto& receive_layers = mcd_answer->simulcast_description().receive_layers();
for (const SimulcastLayer& layer : layers) {
receive_layers.AddLayer(layer);
}
cricket::RtpHeaderExtensions extensions;
for (auto extension : mcd_answer->rtp_header_extensions()) {
if (extension.uri != RtpExtension::kRidUri) {
extensions.push_back(extension);
}
}
mcd_answer->set_rtp_header_extensions(extensions);
EXPECT_EQ(layers.size(), mcd_answer->simulcast_description()
.receive_layers()
.GetAllLayers()
.size());
EXPECT_TRUE(local->SetRemoteDescription(std::move(answer), &err)) << err;
EXPECT_TRUE(ValidateTransceiverParameters(transceiver, expected_layers));
}
} // namespace webrtc