From 6a3bbefd583dfbc1c0cb1013dda17a26da3f989d Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Tue, 12 Dec 2023 14:45:31 +0100 Subject: [PATCH] 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 > Reviewed-by: Danil Chapovalov > Commit-Queue: Philipp Hancke > 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 Reviewed-by: Harald Alvestrand Reviewed-by: Florent Castelli Reviewed-by: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41615} --- pc/rtp_transceiver.cc | 29 +++++++++++++ pc/rtp_transceiver_unittest.cc | 75 ++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index 34d744a3bb..de31b2e36a 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -171,6 +171,35 @@ RtpTransceiver::RtpTransceiver( : 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 d75e964509..b6dc7b2bb9 100644 --- a/pc/rtp_transceiver_unittest.cc +++ b/pc/rtp_transceiver_unittest.cc @@ -481,6 +481,81 @@ TEST_F(RtpTransceiverTestForHeaderExtensions, RtpTransceiverDirection::kStopped))); } +TEST_F(RtpTransceiverTestForHeaderExtensions, + SimulcastOrSvcEnablesExtensionsByDefault) { + std::vector extensions = { + {RtpExtension::kDependencyDescriptorUri, 1, + RtpTransceiverDirection::kStopped}, + {RtpExtension::kVideoLayersAllocationUri, 2, + RtpTransceiverDirection::kStopped}, + }; + + // Default is stopped. + auto sender = rtc::make_ref_counted(); + auto transceiver = rtc::make_ref_counted( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), sender), + RtpReceiverProxyWithInternal::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + std::vector 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(); + EXPECT_CALL(*simulcast_sender, GetParametersInternal()) + .WillRepeatedly(Return(simulcast_parameters)); + auto simulcast_transceiver = rtc::make_ref_counted( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), simulcast_sender), + RtpReceiverProxyWithInternal::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(); + EXPECT_CALL(*svc_sender, GetParametersInternal()) + .WillRepeatedly(Return(svc_parameters)); + auto svc_transceiver = rtc::make_ref_counted( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), svc_sender), + RtpReceiverProxyWithInternal::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + std::vector 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