Signal extmap-allow-mixed by default on session level
The extmap-allow-mixed SDP attribute signals that one- and two-byte RTP
header extensions can be mixed. In practice, this also means that WebRTC
will support two-byte RTP header extensions when this is signaled by
both peers.
Bug: webrtc:9985
Change-Id: I80a3f97bab162c7d9a5acf2cae07b977641c039d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/197943
Commit-Queue: Emil Lundmark <lndmrk@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33036}
diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h
index 92d965b..d7f4e19f 100644
--- a/api/peer_connection_interface.h
+++ b/api/peer_connection_interface.h
@@ -621,12 +621,8 @@
absl::optional<CryptoOptions> crypto_options;
// Configure if we should include the SDP attribute extmap-allow-mixed in
- // our offer. Although we currently do support this, it's not included in
- // our offer by default due to a previous bug that caused the SDP parser to
- // abort parsing if this attribute was present. This is fixed in Chrome 71.
- // TODO(webrtc:9985): Change default to true once sufficient time has
- // passed.
- bool offer_extmap_allow_mixed = false;
+ // our offer on session level.
+ bool offer_extmap_allow_mixed = true;
// TURN logging identifier.
// This identifier is added to a TURN allocation
diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc
index d8cb159..940d746 100644
--- a/pc/media_session_unittest.cc
+++ b/pc/media_session_unittest.cc
@@ -2347,64 +2347,112 @@
}
TEST_F(MediaSessionDescriptionFactoryTest,
- CreateAnswerSupportsMixedOneAndTwoByteHeaderExtensions) {
+ OfferAndAnswerDoesNotHaveMixedByteSessionAttribute) {
MediaSessionOptions opts;
- std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, NULL);
- // Offer without request of mixed one- and two-byte header extensions.
+ std::unique_ptr<SessionDescription> offer =
+ f1_.CreateOffer(opts, /*current_description=*/nullptr);
offer->set_extmap_allow_mixed(false);
- ASSERT_TRUE(offer.get() != NULL);
- std::unique_ptr<SessionDescription> answer_no_support(
- f2_.CreateAnswer(offer.get(), opts, NULL));
- EXPECT_FALSE(answer_no_support->extmap_allow_mixed());
- // Offer with request of mixed one- and two-byte header extensions.
+ std::unique_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer.get(), opts, /*current_description=*/nullptr));
+
+ EXPECT_FALSE(answer->extmap_allow_mixed());
+}
+
+TEST_F(MediaSessionDescriptionFactoryTest,
+ OfferAndAnswerHaveMixedByteSessionAttribute) {
+ MediaSessionOptions opts;
+ std::unique_ptr<SessionDescription> offer =
+ f1_.CreateOffer(opts, /*current_description=*/nullptr);
offer->set_extmap_allow_mixed(true);
- ASSERT_TRUE(offer.get() != NULL);
+
std::unique_ptr<SessionDescription> answer_support(
- f2_.CreateAnswer(offer.get(), opts, NULL));
+ f2_.CreateAnswer(offer.get(), opts, /*current_description=*/nullptr));
+
EXPECT_TRUE(answer_support->extmap_allow_mixed());
}
TEST_F(MediaSessionDescriptionFactoryTest,
- CreateAnswerSupportsMixedOneAndTwoByteHeaderExtensionsOnMediaLevel) {
+ OfferAndAnswerDoesNotHaveMixedByteMediaAttributes) {
MediaSessionOptions opts;
AddAudioVideoSections(RtpTransceiverDirection::kSendRecv, &opts);
- std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, NULL);
- MediaContentDescription* video_offer =
- offer->GetContentDescriptionByName("video");
- ASSERT_TRUE(video_offer);
+ std::unique_ptr<SessionDescription> offer =
+ f1_.CreateOffer(opts, /*current_description=*/nullptr);
+ offer->set_extmap_allow_mixed(false);
MediaContentDescription* audio_offer =
offer->GetContentDescriptionByName("audio");
- ASSERT_TRUE(audio_offer);
+ MediaContentDescription* video_offer =
+ offer->GetContentDescriptionByName("video");
+ ASSERT_EQ(MediaContentDescription::kNo,
+ audio_offer->extmap_allow_mixed_enum());
+ ASSERT_EQ(MediaContentDescription::kNo,
+ video_offer->extmap_allow_mixed_enum());
- // Explicit disable of mixed one-two byte header support in offer.
- video_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kNo);
- audio_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kNo);
+ std::unique_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer.get(), opts, /*current_description=*/nullptr));
- ASSERT_TRUE(offer.get() != NULL);
- std::unique_ptr<SessionDescription> answer_no_support(
- f2_.CreateAnswer(offer.get(), opts, NULL));
- MediaContentDescription* video_answer =
- answer_no_support->GetContentDescriptionByName("video");
MediaContentDescription* audio_answer =
- answer_no_support->GetContentDescriptionByName("audio");
- EXPECT_EQ(MediaContentDescription::kNo,
- video_answer->extmap_allow_mixed_enum());
+ answer->GetContentDescriptionByName("audio");
+ MediaContentDescription* video_answer =
+ answer->GetContentDescriptionByName("video");
EXPECT_EQ(MediaContentDescription::kNo,
audio_answer->extmap_allow_mixed_enum());
+ EXPECT_EQ(MediaContentDescription::kNo,
+ video_answer->extmap_allow_mixed_enum());
+}
- // Enable mixed one-two byte header support in offer.
- video_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kMedia);
+TEST_F(MediaSessionDescriptionFactoryTest,
+ OfferAndAnswerHaveSameMixedByteMediaAttributes) {
+ MediaSessionOptions opts;
+ AddAudioVideoSections(RtpTransceiverDirection::kSendRecv, &opts);
+ std::unique_ptr<SessionDescription> offer =
+ f1_.CreateOffer(opts, /*current_description=*/nullptr);
+ offer->set_extmap_allow_mixed(false);
+ MediaContentDescription* audio_offer =
+ offer->GetContentDescriptionByName("audio");
audio_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kMedia);
- ASSERT_TRUE(offer.get() != NULL);
- std::unique_ptr<SessionDescription> answer_support(
- f2_.CreateAnswer(offer.get(), opts, NULL));
- video_answer = answer_support->GetContentDescriptionByName("video");
- audio_answer = answer_support->GetContentDescriptionByName("audio");
- EXPECT_EQ(MediaContentDescription::kMedia,
- video_answer->extmap_allow_mixed_enum());
+ MediaContentDescription* video_offer =
+ offer->GetContentDescriptionByName("video");
+ video_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kMedia);
+
+ std::unique_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer.get(), opts, /*current_description=*/nullptr));
+
+ MediaContentDescription* audio_answer =
+ answer->GetContentDescriptionByName("audio");
+ MediaContentDescription* video_answer =
+ answer->GetContentDescriptionByName("video");
EXPECT_EQ(MediaContentDescription::kMedia,
audio_answer->extmap_allow_mixed_enum());
+ EXPECT_EQ(MediaContentDescription::kMedia,
+ video_answer->extmap_allow_mixed_enum());
+}
+
+TEST_F(MediaSessionDescriptionFactoryTest,
+ OfferAndAnswerHaveDifferentMixedByteMediaAttributes) {
+ MediaSessionOptions opts;
+ AddAudioVideoSections(RtpTransceiverDirection::kSendRecv, &opts);
+ std::unique_ptr<SessionDescription> offer =
+ f1_.CreateOffer(opts, /*current_description=*/nullptr);
+ offer->set_extmap_allow_mixed(false);
+ MediaContentDescription* audio_offer =
+ offer->GetContentDescriptionByName("audio");
+ audio_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kNo);
+ MediaContentDescription* video_offer =
+ offer->GetContentDescriptionByName("video");
+ video_offer->set_extmap_allow_mixed_enum(MediaContentDescription::kMedia);
+
+ std::unique_ptr<SessionDescription> answer(
+ f2_.CreateAnswer(offer.get(), opts, /*current_description=*/nullptr));
+
+ MediaContentDescription* audio_answer =
+ answer->GetContentDescriptionByName("audio");
+ MediaContentDescription* video_answer =
+ answer->GetContentDescriptionByName("video");
+ EXPECT_EQ(MediaContentDescription::kNo,
+ audio_answer->extmap_allow_mixed_enum());
+ EXPECT_EQ(MediaContentDescription::kMedia,
+ video_answer->extmap_allow_mixed_enum());
}
// Create an audio and video offer with:
diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc
index abedf48..b7be44d 100644
--- a/pc/peer_connection_interface_unittest.cc
+++ b/pc/peer_connection_interface_unittest.cc
@@ -3900,17 +3900,17 @@
TEST_P(PeerConnectionInterfaceTest, ExtmapAllowMixedIsConfigurable) {
RTCConfiguration config;
- // Default behavior is false.
+ // Default behavior is true.
CreatePeerConnection(config);
std::unique_ptr<SessionDescriptionInterface> offer;
ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
- EXPECT_FALSE(offer->description()->extmap_allow_mixed());
- // Possible to set to true.
- config.offer_extmap_allow_mixed = true;
+ EXPECT_TRUE(offer->description()->extmap_allow_mixed());
+ // Possible to set to false.
+ config.offer_extmap_allow_mixed = false;
CreatePeerConnection(config);
offer.release();
ASSERT_TRUE(DoCreateOffer(&offer, nullptr));
- EXPECT_TRUE(offer->description()->extmap_allow_mixed());
+ EXPECT_FALSE(offer->description()->extmap_allow_mixed());
}
INSTANTIATE_TEST_SUITE_P(PeerConnectionInterfaceTest,
diff --git a/pc/session_description.h b/pc/session_description.h
index 52a3a1f..9ec371e 100644
--- a/pc/session_description.h
+++ b/pc/session_description.h
@@ -272,10 +272,7 @@
webrtc::RtpTransceiverDirection direction_ =
webrtc::RtpTransceiverDirection::kSendRecv;
rtc::SocketAddress connection_address_;
- // Mixed one- and two-byte header not included in offer on media level or
- // session level, but we will respond that we support it. The plan is to add
- // it to our offer on session level. See todo in SessionDescription.
- ExtmapAllowMixed extmap_allow_mixed_enum_ = kNo;
+ ExtmapAllowMixed extmap_allow_mixed_enum_ = kMedia;
SimulcastDescription simulcast_;
std::vector<RidDescription> receive_rids_;
@@ -633,12 +630,7 @@
// Default to what Plan B would do.
// TODO(bugs.webrtc.org/8530): Change default to kMsidSignalingMediaSection.
int msid_signaling_ = kMsidSignalingSsrcAttribute;
- // TODO(webrtc:9985): Activate mixed one- and two-byte header extension in
- // offer at session level. It's currently not included in offer by default
- // because clients prior to https://bugs.webrtc.org/9712 cannot parse this
- // correctly. If it's included in offer to us we will respond that we support
- // it.
- bool extmap_allow_mixed_ = false;
+ bool extmap_allow_mixed_ = true;
};
// Indicates whether a session description was sent by the local client or
diff --git a/pc/session_description_unittest.cc b/pc/session_description_unittest.cc
index 75e0974..c990cf6 100644
--- a/pc/session_description_unittest.cc
+++ b/pc/session_description_unittest.cc
@@ -17,7 +17,8 @@
TEST(MediaContentDescriptionTest, ExtmapAllowMixedDefaultValue) {
VideoContentDescription video_desc;
- EXPECT_EQ(MediaContentDescription::kNo, video_desc.extmap_allow_mixed_enum());
+ EXPECT_EQ(MediaContentDescription::kMedia,
+ video_desc.extmap_allow_mixed_enum());
}
TEST(MediaContentDescriptionTest, SetExtmapAllowMixed) {
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index edd8db6..8ec5a7b 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -2570,6 +2570,7 @@
std::vector<std::unique_ptr<JsepIceCandidate>>* candidates,
webrtc::SdpParseError* error) {
auto media_desc = std::make_unique<C>();
+ media_desc->set_extmap_allow_mixed_enum(MediaContentDescription::kNo);
if (!ParseContent(message, media_type, mline_index, protocol, payload_types,
pos, content_name, bundle_only, msid_signaling,
media_desc.get(), transport, candidates, error)) {
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index cf53847..12ab730 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -153,6 +153,7 @@
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
+ "a=extmap-allow-mixed\r\n"
"a=msid-semantic: WMS local_stream_1\r\n"
"m=audio 2345 RTP/SAVPF 111 103 104\r\n"
"c=IN IP4 74.125.127.126\r\n"
@@ -223,6 +224,7 @@
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
+ "a=extmap-allow-mixed\r\n"
"a=msid-semantic: WMS local_stream_1\r\n"
"m=audio 9 RTP/SAVPF 111 103 104\r\n"
"c=IN IP4 0.0.0.0\r\n"
@@ -373,6 +375,7 @@
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
+ "a=extmap-allow-mixed\r\n"
"a=group:BUNDLE audio_content_name video_content_name\r\n"
"a=msid-semantic: WMS local_stream_1\r\n"
"m=audio 2345 RTP/SAVPF 111 103 104\r\n"
@@ -433,6 +436,7 @@
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
+ "a=extmap-allow-mixed\r\n"
"a=msid-semantic: WMS local_stream_1 local_stream_2\r\n"
"m=audio 2345 RTP/SAVPF 111 103 104\r\n"
"c=IN IP4 74.125.127.126\r\n"
@@ -516,6 +520,7 @@
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
+ "a=extmap-allow-mixed\r\n"
"a=msid-semantic: WMS local_stream_1\r\n"
// Audio track 1, stream 1 (with candidates).
"m=audio 2345 RTP/SAVPF 111 103 104\r\n"
@@ -628,6 +633,7 @@
"o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"t=0 0\r\n"
+ "a=extmap-allow-mixed\r\n"
"a=msid-semantic: WMS local_stream_1\r\n"
// Audio track 1, with 1 stream id.
"m=audio 2345 RTP/SAVPF 111 103 104\r\n"
@@ -2752,10 +2758,9 @@
TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithExtmapAllowMixed) {
jdesc_.description()->set_extmap_allow_mixed(true);
std::string sdp_with_extmap_allow_mixed = kSdpFullString;
- InjectAfter("t=0 0\r\n", kExtmapAllowMixed, &sdp_with_extmap_allow_mixed);
// Deserialize
JsepSessionDescription jdesc_deserialized(kDummyType);
- EXPECT_TRUE(SdpDeserialize(sdp_with_extmap_allow_mixed, &jdesc_deserialized));
+ ASSERT_TRUE(SdpDeserialize(sdp_with_extmap_allow_mixed, &jdesc_deserialized));
// Verify
EXPECT_TRUE(CompareSessionDescription(jdesc_, jdesc_deserialized));
}
@@ -2763,9 +2768,10 @@
TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutExtmapAllowMixed) {
jdesc_.description()->set_extmap_allow_mixed(false);
std::string sdp_without_extmap_allow_mixed = kSdpFullString;
+ Replace(kExtmapAllowMixed, "", &sdp_without_extmap_allow_mixed);
// Deserialize
JsepSessionDescription jdesc_deserialized(kDummyType);
- EXPECT_TRUE(
+ ASSERT_TRUE(
SdpDeserialize(sdp_without_extmap_allow_mixed, &jdesc_deserialized));
// Verify
EXPECT_TRUE(CompareSessionDescription(jdesc_, jdesc_deserialized));