Reland "Enable DD and VLA header extensions by default for Simulcast/SVC"
This is a reland of commit 33c7edd58ad0edc71939b9372fff3ab563c1f4a7
taking into account GFD which can be enabled by field trials and somewhat conflicts with DD
Original change's description:
> Enable DD and VLA header extensions by default for Simulcast/SVC
>
> When Simulcast (more than one encoding) or SVC (a scalability mode
> other than the default L1T1) is used, enable the AV1 Dependency
> Descriptor and the video-layer-allocations RTP header extensions by
> default.
>
> The RTP header extensions API can be used to disable them if needed.
>
> BUG=webrtc:15378
>
> Change-Id: I587ac32c9d681461496a136f6950b007e72da86d
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326100
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
> Commit-Queue: Philipp Hancke <phancke@microsoft.com>
> Cr-Commit-Position: refs/heads/main@{#41332}
Bug: webrtc:15378
Change-Id: I190edc9435083c0a0a65a6959363f3c41e4a3d1b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/330563
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41615}
diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc
index 34d744a..de31b2e 100644
--- a/pc/rtp_transceiver.cc
+++ b/pc/rtp_transceiver.cc
@@ -171,6 +171,35 @@
: media_engine()->voice().send_codecs());
senders_.push_back(sender);
receivers_.push_back(receiver);
+
+ // Set default header extensions depending on whether simulcast/SVC is used.
+ RtpParameters parameters = sender->internal()->GetParametersInternal();
+ bool uses_simulcast = parameters.encodings.size() > 1;
+ bool uses_svc = !parameters.encodings.empty() &&
+ parameters.encodings[0].scalability_mode.has_value() &&
+ parameters.encodings[0].scalability_mode !=
+ ScalabilityModeToString(ScalabilityMode::kL1T1);
+ if (uses_simulcast || uses_svc) {
+ // Enable DD and VLA extensions, can be deactivated by the API.
+ // Skip this if the GFD extension was enabled via field trial
+ // for backward compability reasons.
+ bool uses_gfd =
+ absl::c_find_if(
+ header_extensions_to_negotiate_,
+ [](const RtpHeaderExtensionCapability& ext) {
+ return ext.uri == RtpExtension::kGenericFrameDescriptorUri00 &&
+ ext.direction != webrtc::RtpTransceiverDirection::kStopped;
+ }) != header_extensions_to_negotiate_.end();
+ if (!uses_gfd) {
+ for (RtpHeaderExtensionCapability& ext :
+ header_extensions_to_negotiate_) {
+ if (ext.uri == RtpExtension::kVideoLayersAllocationUri ||
+ ext.uri == RtpExtension::kDependencyDescriptorUri) {
+ ext.direction = RtpTransceiverDirection::kSendRecv;
+ }
+ }
+ }
+ }
}
RtpTransceiver::~RtpTransceiver() {
diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc
index d75e9645..b6dc7b2 100644
--- a/pc/rtp_transceiver_unittest.cc
+++ b/pc/rtp_transceiver_unittest.cc
@@ -481,6 +481,81 @@
RtpTransceiverDirection::kStopped)));
}
+TEST_F(RtpTransceiverTestForHeaderExtensions,
+ SimulcastOrSvcEnablesExtensionsByDefault) {
+ std::vector<RtpHeaderExtensionCapability> extensions = {
+ {RtpExtension::kDependencyDescriptorUri, 1,
+ RtpTransceiverDirection::kStopped},
+ {RtpExtension::kVideoLayersAllocationUri, 2,
+ RtpTransceiverDirection::kStopped},
+ };
+
+ // Default is stopped.
+ auto sender = rtc::make_ref_counted<MockRtpSenderInternal>();
+ auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
+ RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
+ rtc::Thread::Current(), sender),
+ RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
+ rtc::Thread::Current(), rtc::Thread::Current(), receiver_),
+ context(), extensions,
+ /* on_negotiation_needed= */ [] {});
+ std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions =
+ transceiver->GetHeaderExtensionsToNegotiate();
+ ASSERT_EQ(header_extensions.size(), 2u);
+ EXPECT_EQ(header_extensions[0].uri, RtpExtension::kDependencyDescriptorUri);
+ EXPECT_EQ(header_extensions[0].direction, RtpTransceiverDirection::kStopped);
+ EXPECT_EQ(header_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri);
+ EXPECT_EQ(header_extensions[1].direction, RtpTransceiverDirection::kStopped);
+
+ // Simulcast, i.e. more than one encoding.
+ RtpParameters simulcast_parameters;
+ simulcast_parameters.encodings.resize(2);
+ auto simulcast_sender = rtc::make_ref_counted<MockRtpSenderInternal>();
+ EXPECT_CALL(*simulcast_sender, GetParametersInternal())
+ .WillRepeatedly(Return(simulcast_parameters));
+ auto simulcast_transceiver = rtc::make_ref_counted<RtpTransceiver>(
+ RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
+ rtc::Thread::Current(), simulcast_sender),
+ RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
+ rtc::Thread::Current(), rtc::Thread::Current(), receiver_),
+ context(), extensions,
+ /* on_negotiation_needed= */ [] {});
+ auto simulcast_extensions =
+ simulcast_transceiver->GetHeaderExtensionsToNegotiate();
+ ASSERT_EQ(simulcast_extensions.size(), 2u);
+ EXPECT_EQ(simulcast_extensions[0].uri,
+ RtpExtension::kDependencyDescriptorUri);
+ EXPECT_EQ(simulcast_extensions[0].direction,
+ RtpTransceiverDirection::kSendRecv);
+ EXPECT_EQ(simulcast_extensions[1].uri,
+ RtpExtension::kVideoLayersAllocationUri);
+ EXPECT_EQ(simulcast_extensions[1].direction,
+ RtpTransceiverDirection::kSendRecv);
+
+ // SVC, a single encoding with a scalabilityMode other than L1T1.
+ webrtc::RtpParameters svc_parameters;
+ svc_parameters.encodings.resize(1);
+ svc_parameters.encodings[0].scalability_mode = "L3T3";
+
+ auto svc_sender = rtc::make_ref_counted<MockRtpSenderInternal>();
+ EXPECT_CALL(*svc_sender, GetParametersInternal())
+ .WillRepeatedly(Return(svc_parameters));
+ auto svc_transceiver = rtc::make_ref_counted<RtpTransceiver>(
+ RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
+ rtc::Thread::Current(), svc_sender),
+ RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
+ rtc::Thread::Current(), rtc::Thread::Current(), receiver_),
+ context(), extensions,
+ /* on_negotiation_needed= */ [] {});
+ std::vector<webrtc::RtpHeaderExtensionCapability> svc_extensions =
+ svc_transceiver->GetHeaderExtensionsToNegotiate();
+ ASSERT_EQ(svc_extensions.size(), 2u);
+ EXPECT_EQ(svc_extensions[0].uri, RtpExtension::kDependencyDescriptorUri);
+ EXPECT_EQ(svc_extensions[0].direction, RtpTransceiverDirection::kSendRecv);
+ EXPECT_EQ(svc_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri);
+ EXPECT_EQ(svc_extensions[1].direction, RtpTransceiverDirection::kSendRecv);
+}
+
} // namespace
} // namespace webrtc