diff options
Diffstat (limited to 'pc')
-rw-r--r-- | pc/BUILD.gn | 1 | ||||
-rw-r--r-- | pc/channel_manager.cc | 44 | ||||
-rw-r--r-- | pc/channel_manager.h | 8 | ||||
-rw-r--r-- | pc/media_session.cc | 6 | ||||
-rw-r--r-- | pc/peer_connection.cc | 8 | ||||
-rw-r--r-- | pc/peer_connection_factory.cc | 28 | ||||
-rw-r--r-- | pc/peer_connection_header_extension_unittest.cc | 144 | ||||
-rw-r--r-- | pc/rtp_transceiver.cc | 13 | ||||
-rw-r--r-- | pc/rtp_transceiver.h | 10 | ||||
-rw-r--r-- | pc/rtp_transceiver_unittest.cc | 32 |
10 files changed, 254 insertions, 40 deletions
diff --git a/pc/BUILD.gn b/pc/BUILD.gn index d8561af442..4341ce1492 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -519,6 +519,7 @@ if (rtc_include_tests) { "peer_connection_data_channel_unittest.cc", "peer_connection_end_to_end_unittest.cc", "peer_connection_factory_unittest.cc", + "peer_connection_header_extension_unittest.cc", "peer_connection_histogram_unittest.cc", "peer_connection_ice_unittest.cc", "peer_connection_integrationtest.cc", diff --git a/pc/channel_manager.cc b/pc/channel_manager.cc index ce8f473600..17e47512b4 100644 --- a/pc/channel_manager.cc +++ b/pc/channel_manager.cc @@ -79,14 +79,6 @@ void ChannelManager::GetSupportedAudioReceiveCodecs( *codecs = media_engine_->voice().recv_codecs(); } -void ChannelManager::GetSupportedAudioRtpHeaderExtensions( - RtpHeaderExtensions* ext) const { - if (!media_engine_) { - return; - } - *ext = media_engine_->voice().GetCapabilities().header_extensions; -} - void ChannelManager::GetSupportedVideoCodecs( std::vector<VideoCodec>* codecs) const { if (!media_engine_) { @@ -104,14 +96,6 @@ void ChannelManager::GetSupportedVideoCodecs( } } -void ChannelManager::GetSupportedVideoRtpHeaderExtensions( - RtpHeaderExtensions* ext) const { - if (!media_engine_) { - return; - } - *ext = media_engine_->video().GetCapabilities().header_extensions; -} - void ChannelManager::GetSupportedDataCodecs( std::vector<DataCodec>* codecs) const { *codecs = data_engine_->data_codecs(); @@ -140,6 +124,34 @@ bool ChannelManager::Init() { return initialized_; } +RtpHeaderExtensions ChannelManager::GetDefaultEnabledAudioRtpHeaderExtensions() + const { + if (!media_engine_) + return {}; + return GetDefaultEnabledRtpHeaderExtensions(media_engine_->voice()); +} + +std::vector<webrtc::RtpHeaderExtensionCapability> +ChannelManager::GetSupportedAudioRtpHeaderExtensions() const { + if (!media_engine_) + return {}; + return media_engine_->voice().GetRtpHeaderExtensions(); +} + +RtpHeaderExtensions ChannelManager::GetDefaultEnabledVideoRtpHeaderExtensions() + const { + if (!media_engine_) + return {}; + return GetDefaultEnabledRtpHeaderExtensions(media_engine_->video()); +} + +std::vector<webrtc::RtpHeaderExtensionCapability> +ChannelManager::GetSupportedVideoRtpHeaderExtensions() const { + if (!media_engine_) + return {}; + return media_engine_->video().GetRtpHeaderExtensions(); +} + void ChannelManager::Terminate() { RTC_DCHECK(initialized_); if (!initialized_) { diff --git a/pc/channel_manager.h b/pc/channel_manager.h index 661ab4bbde..fa4bf7b925 100644 --- a/pc/channel_manager.h +++ b/pc/channel_manager.h @@ -75,10 +75,14 @@ class ChannelManager final { // Can be called before starting the media engine. void GetSupportedAudioSendCodecs(std::vector<AudioCodec>* codecs) const; void GetSupportedAudioReceiveCodecs(std::vector<AudioCodec>* codecs) const; - void GetSupportedAudioRtpHeaderExtensions(RtpHeaderExtensions* ext) const; void GetSupportedVideoCodecs(std::vector<VideoCodec>* codecs) const; - void GetSupportedVideoRtpHeaderExtensions(RtpHeaderExtensions* ext) const; void GetSupportedDataCodecs(std::vector<DataCodec>* codecs) const; + RtpHeaderExtensions GetDefaultEnabledAudioRtpHeaderExtensions() const; + std::vector<webrtc::RtpHeaderExtensionCapability> + GetSupportedAudioRtpHeaderExtensions() const; + RtpHeaderExtensions GetDefaultEnabledVideoRtpHeaderExtensions() const; + std::vector<webrtc::RtpHeaderExtensionCapability> + GetSupportedVideoRtpHeaderExtensions() const; // Indicates whether the media engine is started. bool initialized() const { return initialized_; } diff --git a/pc/media_session.cc b/pc/media_session.cc index 9190f6eaf3..2f57e61d08 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -1365,9 +1365,11 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( : MediaSessionDescriptionFactory(transport_desc_factory, ssrc_generator) { channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_); channel_manager->GetSupportedAudioReceiveCodecs(&audio_recv_codecs_); - channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_); + audio_rtp_extensions_ = + channel_manager->GetDefaultEnabledAudioRtpHeaderExtensions(); channel_manager->GetSupportedVideoCodecs(&video_codecs_); - channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_); + video_rtp_extensions_ = + channel_manager->GetDefaultEnabledVideoRtpHeaderExtensions(); channel_manager->GetSupportedDataCodecs(&rtp_data_codecs_); ComputeAudioCodecsIntersectionAndUnion(); } diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 5fccf1f7f2..c6af185d47 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -1907,7 +1907,11 @@ PeerConnection::CreateAndAddTransceiver( RTC_DCHECK(!FindSenderById(sender->id())); auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create( signaling_thread(), - new RtpTransceiver(sender, receiver, channel_manager())); + new RtpTransceiver( + sender, receiver, channel_manager(), + sender->media_type() == cricket::MEDIA_TYPE_AUDIO + ? channel_manager()->GetSupportedAudioRtpHeaderExtensions() + : channel_manager()->GetSupportedVideoRtpHeaderExtensions())); transceivers_.push_back(transceiver); transceiver->internal()->SignalNegotiationNeeded.connect( this, &PeerConnection::OnNegotiationNeeded); @@ -4983,6 +4987,7 @@ void PeerConnection::GetOptionsForPlanBOffer( cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO, RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), false)); + audio_index = session_options->media_description_options.size() - 1; } if (!video_index && offer_new_video_description) { @@ -4991,6 +4996,7 @@ void PeerConnection::GetOptionsForPlanBOffer( cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO, RtpTransceiverDirectionFromSendRecv(send_video, recv_video), false)); + video_index = session_options->media_description_options.size() - 1; } if (!data_index && offer_new_data_description) { diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc index 4237b47e54..a0a999fcc5 100644 --- a/pc/peer_connection_factory.cc +++ b/pc/peer_connection_factory.cc @@ -160,19 +160,17 @@ RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities( switch (kind) { case cricket::MEDIA_TYPE_AUDIO: { cricket::AudioCodecs cricket_codecs; - cricket::RtpHeaderExtensions cricket_extensions; channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs); - channel_manager_->GetSupportedAudioRtpHeaderExtensions( - &cricket_extensions); - return ToRtpCapabilities(cricket_codecs, cricket_extensions); + return ToRtpCapabilities( + cricket_codecs, + channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_VIDEO: { cricket::VideoCodecs cricket_codecs; - cricket::RtpHeaderExtensions cricket_extensions; channel_manager_->GetSupportedVideoCodecs(&cricket_codecs); - channel_manager_->GetSupportedVideoRtpHeaderExtensions( - &cricket_extensions); - return ToRtpCapabilities(cricket_codecs, cricket_extensions); + return ToRtpCapabilities( + cricket_codecs, + channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_DATA: return RtpCapabilities(); @@ -187,19 +185,17 @@ RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities( switch (kind) { case cricket::MEDIA_TYPE_AUDIO: { cricket::AudioCodecs cricket_codecs; - cricket::RtpHeaderExtensions cricket_extensions; channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs); - channel_manager_->GetSupportedAudioRtpHeaderExtensions( - &cricket_extensions); - return ToRtpCapabilities(cricket_codecs, cricket_extensions); + return ToRtpCapabilities( + cricket_codecs, + channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_VIDEO: { cricket::VideoCodecs cricket_codecs; - cricket::RtpHeaderExtensions cricket_extensions; channel_manager_->GetSupportedVideoCodecs(&cricket_codecs); - channel_manager_->GetSupportedVideoRtpHeaderExtensions( - &cricket_extensions); - return ToRtpCapabilities(cricket_codecs, cricket_extensions); + return ToRtpCapabilities( + cricket_codecs, + channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions()); } case cricket::MEDIA_TYPE_DATA: return RtpCapabilities(); diff --git a/pc/peer_connection_header_extension_unittest.cc b/pc/peer_connection_header_extension_unittest.cc new file mode 100644 index 0000000000..3f44d4f877 --- /dev/null +++ b/pc/peer_connection_header_extension_unittest.cc @@ -0,0 +1,144 @@ +/* + * Copyright 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <memory> +#include <tuple> + +#include "api/rtc_event_log/rtc_event_log_factory.h" +#include "api/task_queue/default_task_queue_factory.h" +#include "media/base/fake_media_engine.h" +#include "p2p/base/fake_port_allocator.h" +#include "pc/media_session.h" +#include "pc/peer_connection_wrapper.h" +#include "rtc_base/gunit.h" +#include "rtc_base/strings/string_builder.h" +#include "test/gmock.h" + +namespace webrtc { + +using ::testing::Combine; +using ::testing::ElementsAre; +using ::testing::Field; +using ::testing::Return; +using ::testing::Values; + +class PeerConnectionHeaderExtensionTest + : public ::testing::TestWithParam< + std::tuple<cricket::MediaType, SdpSemantics>> { + protected: + std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection( + cricket::MediaType media_type, + absl::optional<SdpSemantics> semantics, + std::vector<RtpHeaderExtensionCapability> extensions) { + auto voice = std::make_unique<cricket::FakeVoiceEngine>(); + auto video = std::make_unique<cricket::FakeVideoEngine>(); + if (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO) + voice->SetRtpHeaderExtensions(extensions); + else + video->SetRtpHeaderExtensions(extensions); + auto media_engine = std::make_unique<cricket::CompositeMediaEngine>( + std::move(voice), std::move(video)); + PeerConnectionFactoryDependencies factory_dependencies; + factory_dependencies.network_thread = rtc::Thread::Current(); + factory_dependencies.worker_thread = rtc::Thread::Current(); + factory_dependencies.signaling_thread = rtc::Thread::Current(); + factory_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory(); + factory_dependencies.media_engine = std::move(media_engine); + factory_dependencies.call_factory = CreateCallFactory(); + factory_dependencies.event_log_factory = + std::make_unique<RtcEventLogFactory>( + factory_dependencies.task_queue_factory.get()); + + auto pc_factory = + CreateModularPeerConnectionFactory(std::move(factory_dependencies)); + + auto fake_port_allocator = std::make_unique<cricket::FakePortAllocator>( + rtc::Thread::Current(), nullptr); + auto observer = std::make_unique<MockPeerConnectionObserver>(); + PeerConnectionInterface::RTCConfiguration config; + if (semantics) + config.sdp_semantics = *semantics; + auto pc = pc_factory->CreatePeerConnection( + config, std::move(fake_port_allocator), nullptr, observer.get()); + observer->SetPeerConnectionInterface(pc.get()); + return std::make_unique<PeerConnectionWrapper>(pc_factory, pc, + std::move(observer)); + } +}; + +TEST_P(PeerConnectionHeaderExtensionTest, TransceiverOffersHeaderExtensions) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + if (semantics != SdpSemantics::kUnifiedPlan) + return; + std::vector<RtpHeaderExtensionCapability> extensions( + {RtpHeaderExtensionCapability("uri1", 1, + RtpTransceiverDirection::kStopped), + RtpHeaderExtensionCapability("uri2", 2, + RtpTransceiverDirection::kSendOnly), + RtpHeaderExtensionCapability("uri3", 3, + RtpTransceiverDirection::kRecvOnly), + RtpHeaderExtensionCapability("uri4", 4, + RtpTransceiverDirection::kSendRecv)}); + std::unique_ptr<PeerConnectionWrapper> wrapper = + CreatePeerConnection(media_type, semantics, extensions); + auto transceiver = wrapper->AddTransceiver(media_type); + EXPECT_EQ(transceiver->HeaderExtensionsToOffer(), extensions); +} + +TEST_P(PeerConnectionHeaderExtensionTest, + SenderReceiverCapabilitiesReturnNotStoppedExtensions) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = GetParam(); + std::unique_ptr<PeerConnectionWrapper> wrapper = CreatePeerConnection( + media_type, semantics, + std::vector<RtpHeaderExtensionCapability>( + {RtpHeaderExtensionCapability("uri1", 1, + RtpTransceiverDirection::kSendRecv), + RtpHeaderExtensionCapability("uri2", 2, + RtpTransceiverDirection::kStopped), + RtpHeaderExtensionCapability("uri3", 3, + RtpTransceiverDirection::kRecvOnly)})); + EXPECT_THAT(wrapper->pc_factory() + ->GetRtpSenderCapabilities(media_type) + .header_extensions, + ElementsAre(Field(&RtpHeaderExtensionCapability::uri, "uri1"), + Field(&RtpHeaderExtensionCapability::uri, "uri3"))); + EXPECT_EQ(wrapper->pc_factory() + ->GetRtpReceiverCapabilities(media_type) + .header_extensions, + wrapper->pc_factory() + ->GetRtpSenderCapabilities(media_type) + .header_extensions); +} + +INSTANTIATE_TEST_SUITE_P( + , + PeerConnectionHeaderExtensionTest, + Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan), + Values(cricket::MediaType::MEDIA_TYPE_AUDIO, + cricket::MediaType::MEDIA_TYPE_VIDEO)), + [](const testing::TestParamInfo< + PeerConnectionHeaderExtensionTest::ParamType>& info) { + cricket::MediaType media_type; + SdpSemantics semantics; + std::tie(media_type, semantics) = info.param; + return (rtc::StringBuilder("With") + << (semantics == SdpSemantics::kPlanB ? "PlanB" : "UnifiedPlan") + << "And" + << (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO ? "Voice" + : "Video") + << "Engine") + .str(); + }); + +} // namespace webrtc diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index d3281d5e6e..ca57b91142 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -11,8 +11,10 @@ #include "pc/rtp_transceiver.h" #include <string> +#include <utility> #include "absl/algorithm/container.h" +#include "api/rtp_parameters.h" #include "pc/channel_manager.h" #include "pc/rtp_media_utils.h" #include "pc/rtp_parameters_conversion.h" @@ -31,10 +33,12 @@ RtpTransceiver::RtpTransceiver( rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender, rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>> receiver, - cricket::ChannelManager* channel_manager) + cricket::ChannelManager* channel_manager, + std::vector<RtpHeaderExtensionCapability> header_extensions_offered) : unified_plan_(true), media_type_(sender->media_type()), - channel_manager_(channel_manager) { + channel_manager_(channel_manager), + HeaderExtensionsToOffer_(std::move(header_extensions_offered)) { RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO || media_type_ == cricket::MEDIA_TYPE_VIDEO); RTC_DCHECK_EQ(sender->media_type(), receiver->media_type()); @@ -358,4 +362,9 @@ RTCError RtpTransceiver::SetCodecPreferences( return RTCError::OK(); } +std::vector<RtpHeaderExtensionCapability> +RtpTransceiver::HeaderExtensionsToOffer() const { + return HeaderExtensionsToOffer_; +} + } // namespace webrtc diff --git a/pc/rtp_transceiver.h b/pc/rtp_transceiver.h index 7ab9e9849a..0668447b9f 100644 --- a/pc/rtp_transceiver.h +++ b/pc/rtp_transceiver.h @@ -64,11 +64,14 @@ class RtpTransceiver final // Construct a Unified Plan-style RtpTransceiver with the given sender and // receiver. The media type will be derived from the media types of the sender // and receiver. The sender and receiver should have the same media type. + // |HeaderExtensionsToOffer| is used for initializing the return value of + // HeaderExtensionsToOffer(). RtpTransceiver( rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender, rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>> receiver, - cricket::ChannelManager* channel_manager); + cricket::ChannelManager* channel_manager, + std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer); ~RtpTransceiver() override; // Returns the Voice/VideoChannel set for this transceiver. May be null if @@ -190,6 +193,8 @@ class RtpTransceiver final std::vector<RtpCodecCapability> codec_preferences() const override { return codec_preferences_; } + std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer() + const override; private: void OnFirstPacketReceived(cricket::ChannelInterface* channel); @@ -215,6 +220,7 @@ class RtpTransceiver final cricket::ChannelInterface* channel_ = nullptr; cricket::ChannelManager* channel_manager_ = nullptr; std::vector<RtpCodecCapability> codec_preferences_; + std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer_; }; BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver) @@ -233,6 +239,8 @@ PROXY_METHOD1(webrtc::RTCError, SetCodecPreferences, rtc::ArrayView<RtpCodecCapability>) PROXY_CONSTMETHOD0(std::vector<RtpCodecCapability>, codec_preferences) +PROXY_CONSTMETHOD0(std::vector<RtpHeaderExtensionCapability>, + HeaderExtensionsToOffer) END_PROXY_MAP() } // namespace webrtc diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc index 885a5a10c8..5e345739f1 100644 --- a/pc/rtp_transceiver_unittest.cc +++ b/pc/rtp_transceiver_unittest.cc @@ -12,10 +12,19 @@ #include "pc/rtp_transceiver.h" +#include <memory> + +#include "media/base/fake_media_engine.h" #include "pc/test/mock_channel_interface.h" +#include "pc/test/mock_rtp_receiver_internal.h" +#include "pc/test/mock_rtp_sender_internal.h" #include "test/gmock.h" #include "test/gtest.h" +using ::testing::ElementsAre; +using ::testing::Eq; +using ::testing::Field; +using ::testing::Not; using ::testing::Return; using ::testing::ReturnRef; @@ -69,4 +78,27 @@ TEST(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) { EXPECT_EQ(nullptr, transceiver.channel()); } +TEST(RtpTransceiverTest, + InitsWithChannelManagerRtpHeaderExtensionCapabilities) { + cricket::ChannelManager channel_manager( + std::make_unique<cricket::FakeMediaEngine>(), + std::make_unique<cricket::FakeDataEngine>(), rtc::Thread::Current(), + rtc::Thread::Current()); + std::vector<RtpHeaderExtensionCapability> extensions({ + RtpHeaderExtensionCapability("uri1", 1, + RtpTransceiverDirection::kSendRecv), + RtpHeaderExtensionCapability("uri2", 2, + RtpTransceiverDirection::kRecvOnly), + }); + RtpTransceiver transceiver( + RtpSenderProxyWithInternal<RtpSenderInternal>::Create( + rtc::Thread::Current(), + new rtc::RefCountedObject<MockRtpSenderInternal>()), + RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create( + rtc::Thread::Current(), + new rtc::RefCountedObject<MockRtpReceiverInternal>()), + &channel_manager, extensions); + EXPECT_EQ(transceiver.HeaderExtensionsToOffer(), extensions); +} + } // namespace webrtc |