aboutsummaryrefslogtreecommitdiff
path: root/pc
diff options
context:
space:
mode:
Diffstat (limited to 'pc')
-rw-r--r--pc/BUILD.gn1
-rw-r--r--pc/channel_manager.cc44
-rw-r--r--pc/channel_manager.h8
-rw-r--r--pc/media_session.cc6
-rw-r--r--pc/peer_connection.cc8
-rw-r--r--pc/peer_connection_factory.cc28
-rw-r--r--pc/peer_connection_header_extension_unittest.cc144
-rw-r--r--pc/rtp_transceiver.cc13
-rw-r--r--pc/rtp_transceiver.h10
-rw-r--r--pc/rtp_transceiver_unittest.cc32
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