Don't create channel_manager when media_engine is not set
Also remove a bunch of functions in ChannelManager that were just
forwarding to MediaEngineInterface.
Bug: webrtc:13931
Change-Id: Ia38591fd22c665cace16d032f5c1e384e413cded
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/261304
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36801}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 1edbd24..4796de3 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -377,6 +377,7 @@
"../rtc_base:checks",
"../rtc_base:logging",
"../rtc_base:stringutils",
+ "../rtc_base/memory:always_valid_pointer",
"../rtc_base/third_party/base64",
]
absl_deps = [
diff --git a/pc/channel_manager.cc b/pc/channel_manager.cc
index e13db54..9ee2bca 100644
--- a/pc/channel_manager.cc
+++ b/pc/channel_manager.cc
@@ -31,6 +31,7 @@
bool enable_rtx,
rtc::Thread* worker_thread,
rtc::Thread* network_thread) {
+ RTC_CHECK(media_engine);
RTC_DCHECK(network_thread);
RTC_DCHECK(worker_thread);
@@ -51,12 +52,11 @@
RTC_DCHECK_RUN_ON(signaling_thread_);
RTC_DCHECK(worker_thread_);
RTC_DCHECK(network_thread_);
+ RTC_CHECK(media_engine_);
- if (media_engine_) {
- // TODO(tommi): Change VoiceEngine to do ctor time initialization so that
- // this isn't necessary.
- worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] { media_engine_->Init(); });
- }
+ // TODO(tommi): Change VoiceEngine to do ctor time initialization so that
+ // this isn't necessary.
+ worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] { media_engine_->Init(); });
}
ChannelManager::~ChannelManager() {
@@ -71,27 +71,8 @@
});
}
-void ChannelManager::GetSupportedAudioSendCodecs(
- std::vector<AudioCodec>* codecs) const {
- if (!media_engine_) {
- return;
- }
- *codecs = media_engine_->voice().send_codecs();
-}
-
-void ChannelManager::GetSupportedAudioReceiveCodecs(
- std::vector<AudioCodec>* codecs) const {
- if (!media_engine_) {
- return;
- }
- *codecs = media_engine_->voice().recv_codecs();
-}
-
void ChannelManager::GetSupportedVideoSendCodecs(
std::vector<VideoCodec>* codecs) const {
- if (!media_engine_) {
- return;
- }
codecs->clear();
std::vector<VideoCodec> video_codecs = media_engine_->video().send_codecs();
@@ -106,9 +87,6 @@
void ChannelManager::GetSupportedVideoReceiveCodecs(
std::vector<VideoCodec>* codecs) const {
- if (!media_engine_) {
- return;
- }
codecs->clear();
std::vector<VideoCodec> video_codecs = media_engine_->video().recv_codecs();
@@ -123,32 +101,14 @@
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();
-}
-
std::unique_ptr<VoiceChannel> ChannelManager::CreateVoiceChannel(
webrtc::Call* call,
const MediaConfig& media_config,
diff --git a/pc/channel_manager.h b/pc/channel_manager.h
index 8d1ec28..23adac3 100644
--- a/pc/channel_manager.h
+++ b/pc/channel_manager.h
@@ -47,7 +47,7 @@
class ChannelManager : public ChannelFactoryInterface {
public:
// Returns an initialized instance of ChannelManager.
- // If media_engine is non-nullptr, then the returned ChannelManager instance
+ // `media_engine` cannot be null. The returned ChannelManager instance
// will own that reference and media engine initialization
static std::unique_ptr<ChannelManager> Create(
std::unique_ptr<MediaEngineInterface> media_engine,
@@ -63,18 +63,11 @@
MediaEngineInterface* media_engine() { return media_engine_.get(); }
rtc::UniqueRandomIdGenerator& ssrc_generator() { return ssrc_generator_; }
- // Retrieves the list of supported audio & video codec types.
- // Can be called before starting the media engine.
- void GetSupportedAudioSendCodecs(std::vector<AudioCodec>* codecs) const;
- void GetSupportedAudioReceiveCodecs(std::vector<AudioCodec>* codecs) const;
+ // Retrieves the list of supported video codec types.
void GetSupportedVideoSendCodecs(std::vector<VideoCodec>* codecs) const;
void GetSupportedVideoReceiveCodecs(std::vector<VideoCodec>* codecs) const;
RtpHeaderExtensions GetDefaultEnabledAudioRtpHeaderExtensions() const;
- std::vector<webrtc::RtpHeaderExtensionCapability>
- GetSupportedAudioRtpHeaderExtensions() const;
RtpHeaderExtensions GetDefaultEnabledVideoRtpHeaderExtensions() const;
- std::vector<webrtc::RtpHeaderExtensionCapability>
- GetSupportedVideoRtpHeaderExtensions() const;
// The operations below all occur on the worker thread.
// The caller is responsible for ensuring that destruction happens
@@ -123,7 +116,7 @@
void DestroyVideoChannel(VideoChannel* video_channel);
private:
- const std::unique_ptr<MediaEngineInterface> media_engine_; // Nullable.
+ const std::unique_ptr<MediaEngineInterface> media_engine_;
rtc::Thread* const signaling_thread_;
rtc::Thread* const worker_thread_;
rtc::Thread* const network_thread_;
diff --git a/pc/connection_context.cc b/pc/connection_context.cc
index 818283d..e2e0666 100644
--- a/pc/connection_context.cc
+++ b/pc/connection_context.cc
@@ -144,9 +144,11 @@
default_socket_factory_ =
std::make_unique<rtc::BasicPacketSocketFactory>(socket_factory);
- channel_manager_ = cricket::ChannelManager::Create(
- std::move(dependencies->media_engine),
- /*enable_rtx=*/true, worker_thread(), network_thread());
+ if (dependencies->media_engine) {
+ channel_manager_ = cricket::ChannelManager::Create(
+ std::move(dependencies->media_engine),
+ /*enable_rtx=*/true, worker_thread(), network_thread());
+ }
// Set warning levels on the threads, to give warnings when response
// may be slower than is expected of the thread.
diff --git a/pc/media_session.cc b/pc/media_session.cc
index 71a6d0a..91a0b88 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -1557,21 +1557,22 @@
const TransportDescriptionFactory* transport_desc_factory,
rtc::UniqueRandomIdGenerator* ssrc_generator)
: ssrc_generator_(ssrc_generator),
- transport_desc_factory_(transport_desc_factory) {
- RTC_DCHECK(ssrc_generator_);
-}
+ transport_desc_factory_(transport_desc_factory) {}
MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
ChannelManager* channel_manager,
const TransportDescriptionFactory* transport_desc_factory)
- : MediaSessionDescriptionFactory(transport_desc_factory,
- &channel_manager->ssrc_generator()) {
- channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_);
- channel_manager->GetSupportedAudioReceiveCodecs(&audio_recv_codecs_);
- channel_manager->GetSupportedVideoSendCodecs(&video_send_codecs_);
- channel_manager->GetSupportedVideoReceiveCodecs(&video_recv_codecs_);
- ComputeAudioCodecsIntersectionAndUnion();
- ComputeVideoCodecsIntersectionAndUnion();
+ : MediaSessionDescriptionFactory(
+ transport_desc_factory,
+ channel_manager ? &channel_manager->ssrc_generator() : nullptr) {
+ if (channel_manager) {
+ audio_send_codecs_ = channel_manager->media_engine()->voice().send_codecs();
+ audio_recv_codecs_ = channel_manager->media_engine()->voice().recv_codecs();
+ channel_manager->GetSupportedVideoSendCodecs(&video_send_codecs_);
+ channel_manager->GetSupportedVideoReceiveCodecs(&video_recv_codecs_);
+ ComputeAudioCodecsIntersectionAndUnion();
+ ComputeVideoCodecsIntersectionAndUnion();
+ }
}
const AudioCodecs& MediaSessionDescriptionFactory::audio_sendrecv_codecs()
@@ -2354,7 +2355,7 @@
if (!CreateMediaContentOffer(
media_description_options, session_options, filtered_codecs,
sdes_policy, GetCryptos(current_content), crypto_suites,
- audio_rtp_extensions, ssrc_generator_, current_streams, audio.get(),
+ audio_rtp_extensions, ssrc_generator(), current_streams, audio.get(),
transport_desc_factory_->trials())) {
return false;
}
@@ -2466,7 +2467,7 @@
if (!CreateMediaContentOffer(
media_description_options, session_options, filtered_codecs,
sdes_policy, GetCryptos(current_content), crypto_suites,
- video_rtp_extensions, ssrc_generator_, current_streams, video.get(),
+ video_rtp_extensions, ssrc_generator(), current_streams, video.get(),
transport_desc_factory_->trials())) {
return false;
}
@@ -2519,8 +2520,8 @@
if (!CreateContentOffer(media_description_options, session_options,
sdes_policy, GetCryptos(current_content),
- crypto_suites, RtpHeaderExtensions(), ssrc_generator_,
- current_streams, data.get())) {
+ crypto_suites, RtpHeaderExtensions(),
+ ssrc_generator(), current_streams, data.get())) {
return false;
}
@@ -2654,7 +2655,7 @@
audio_transport->secure() ? cricket::SEC_DISABLED : secure();
if (!SetCodecsInAnswer(offer_audio_description, filtered_codecs,
media_description_options, session_options,
- ssrc_generator_, current_streams, audio_answer.get(),
+ ssrc_generator(), current_streams, audio_answer.get(),
transport_desc_factory_->trials())) {
return false;
}
@@ -2662,7 +2663,7 @@
offer_audio_description, media_description_options, session_options,
sdes_policy, GetCryptos(current_content),
filtered_rtp_header_extensions(default_audio_rtp_header_extensions),
- ssrc_generator_, enable_encrypted_rtp_header_extensions_,
+ ssrc_generator(), enable_encrypted_rtp_header_extensions_,
current_streams, bundle_enabled, audio_answer.get())) {
return false; // Fails the session setup.
}
@@ -2783,7 +2784,7 @@
video_transport->secure() ? cricket::SEC_DISABLED : secure();
if (!SetCodecsInAnswer(offer_video_description, filtered_codecs,
media_description_options, session_options,
- ssrc_generator_, current_streams, video_answer.get(),
+ ssrc_generator(), current_streams, video_answer.get(),
transport_desc_factory_->trials())) {
return false;
}
@@ -2791,7 +2792,7 @@
offer_video_description, media_description_options, session_options,
sdes_policy, GetCryptos(current_content),
filtered_rtp_header_extensions(default_video_rtp_header_extensions),
- ssrc_generator_, enable_encrypted_rtp_header_extensions_,
+ ssrc_generator(), enable_encrypted_rtp_header_extensions_,
current_streams, bundle_enabled, video_answer.get())) {
return false; // Failed the sessin setup.
}
@@ -2864,7 +2865,7 @@
if (!CreateMediaContentAnswer(
offer_data_description, media_description_options, session_options,
sdes_policy, GetCryptos(current_content), RtpHeaderExtensions(),
- ssrc_generator_, enable_encrypted_rtp_header_extensions_,
+ ssrc_generator(), enable_encrypted_rtp_header_extensions_,
current_streams, bundle_enabled, data_answer.get())) {
return false; // Fails the session setup.
}
diff --git a/pc/media_session.h b/pc/media_session.h
index 9a67ad1..8f97538 100644
--- a/pc/media_session.h
+++ b/pc/media_session.h
@@ -34,6 +34,7 @@
#include "pc/media_protocol_names.h"
#include "pc/session_description.h"
#include "pc/simulcast_description.h"
+#include "rtc_base/memory/always_valid_pointer.h"
#include "rtc_base/unique_id_generator.h"
namespace webrtc {
@@ -328,6 +329,10 @@
void ComputeVideoCodecsIntersectionAndUnion();
+ rtc::UniqueRandomIdGenerator* ssrc_generator() const {
+ return ssrc_generator_.get();
+ }
+
bool is_unified_plan_ = false;
AudioCodecs audio_send_codecs_;
AudioCodecs audio_recv_codecs_;
@@ -341,8 +346,9 @@
VideoCodecs video_sendrecv_codecs_;
// Union of send and recv.
VideoCodecs all_video_codecs_;
- // This object is not owned by the channel so it must outlive it.
- rtc::UniqueRandomIdGenerator* const ssrc_generator_;
+ // This object may or may not be owned by this class.
+ webrtc::AlwaysValidPointer<rtc::UniqueRandomIdGenerator> const
+ ssrc_generator_;
bool enable_encrypted_rtp_header_extensions_ = false;
// TODO(zhihuang): Rename secure_ to sdec_policy_; rename the related getter
// and setter.
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index f914fc8..c139d0a 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -646,25 +646,27 @@
sdp_handler_ = SdpOfferAnswerHandler::Create(this, configuration,
dependencies, context_.get());
- rtp_manager_ = std::make_unique<RtpTransmissionManager>(
- IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
- &usage_pattern_, observer_, stats_.get(), [this]() {
- RTC_DCHECK_RUN_ON(signaling_thread());
- sdp_handler_->UpdateNegotiationNeeded();
- });
+ if (ConfiguredForMedia()) {
+ rtp_manager_ = std::make_unique<RtpTransmissionManager>(
+ IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
+ &usage_pattern_, observer_, stats_.get(), [this]() {
+ RTC_DCHECK_RUN_ON(signaling_thread());
+ sdp_handler_->UpdateNegotiationNeeded();
+ });
- // Add default audio/video transceivers for Plan B SDP.
- if (!IsUnifiedPlan()) {
- rtp_manager()->transceivers()->Add(
- RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
- signaling_thread(),
- rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_AUDIO,
- channel_manager())));
- rtp_manager()->transceivers()->Add(
- RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
- signaling_thread(),
- rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_VIDEO,
- channel_manager())));
+ // Add default audio/video transceivers for Plan B SDP.
+ if (!IsUnifiedPlan()) {
+ rtp_manager()->transceivers()->Add(
+ RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
+ signaling_thread(),
+ rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_AUDIO,
+ channel_manager())));
+ rtp_manager()->transceivers()->Add(
+ RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
+ signaling_thread(),
+ rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_VIDEO,
+ channel_manager())));
+ }
}
int delay_ms = configuration.report_usage_pattern_delay_ms
@@ -1178,8 +1180,10 @@
const {
RTC_DCHECK_RUN_ON(signaling_thread());
std::vector<rtc::scoped_refptr<RtpSenderInterface>> ret;
- for (const auto& sender : rtp_manager()->GetSendersInternal()) {
- ret.push_back(sender);
+ if (ConfiguredForMedia()) {
+ for (const auto& sender : rtp_manager()->GetSendersInternal()) {
+ ret.push_back(sender);
+ }
}
return ret;
}
@@ -1188,8 +1192,10 @@
PeerConnection::GetReceivers() const {
RTC_DCHECK_RUN_ON(signaling_thread());
std::vector<rtc::scoped_refptr<RtpReceiverInterface>> ret;
- for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
- ret.push_back(receiver);
+ if (ConfiguredForMedia()) {
+ for (const auto& receiver : rtp_manager()->GetReceiversInternal()) {
+ ret.push_back(receiver);
+ }
}
return ret;
}
@@ -1200,8 +1206,10 @@
RTC_CHECK(IsUnifiedPlan())
<< "GetTransceivers is only supported with Unified Plan SdpSemantics.";
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> all_transceivers;
- for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
- all_transceivers.push_back(transceiver);
+ if (ConfiguredForMedia()) {
+ for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
+ all_transceivers.push_back(transceiver);
+ }
}
return all_transceivers;
}
@@ -1680,8 +1688,7 @@
RTC_FROM_HERE, [this, playout] { SetAudioPlayout(playout); });
return;
}
- auto audio_state =
- context_->channel_manager()->media_engine()->voice().GetAudioState();
+ auto audio_state = media_engine()->voice().GetAudioState();
audio_state->SetPlayout(playout);
}
@@ -1691,8 +1698,7 @@
RTC_FROM_HERE, [this, recording] { SetAudioRecording(recording); });
return;
}
- auto audio_state =
- context_->channel_manager()->media_engine()->voice().GetAudioState();
+ auto audio_state = media_engine()->voice().GetAudioState();
audio_state->SetRecording(recording);
}
@@ -1712,7 +1718,7 @@
}
bool PeerConnection::ConfiguredForMedia() const {
- return context_->channel_manager()->media_engine();
+ return context_->channel_manager();
}
bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
@@ -1822,12 +1828,13 @@
NoteUsageEvent(UsageEvent::CLOSE_CALLED);
- for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
- transceiver->internal()->SetPeerConnectionClosed();
- if (!transceiver->stopped())
- transceiver->StopInternal();
+ if (ConfiguredForMedia()) {
+ for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
+ transceiver->internal()->SetPeerConnectionClosed();
+ if (!transceiver->stopped())
+ transceiver->StopInternal();
+ }
}
-
// Ensure that all asynchronous stats requests are completed before destroying
// the transport controller below.
if (stats_collector_) {
@@ -1844,7 +1851,9 @@
// WebRTC session description factory, the session description factory would
// call the transport controller.
sdp_handler_->ResetSessionDescFactory();
- rtp_manager_->Close();
+ if (ConfiguredForMedia()) {
+ rtp_manager_->Close();
+ }
network_thread()->Invoke<void>(RTC_FROM_HERE, [this] {
// Data channels will already have been unset via the DestroyAllChannels()
@@ -2735,12 +2744,15 @@
rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
std::map<std::string, std::set<cricket::MediaType>>
media_types_by_transport_name;
- for (const auto& transceiver : rtp_manager()->transceivers()->UnsafeList()) {
- if (transceiver->internal()->channel()) {
- std::string transport_name(
- transceiver->internal()->channel()->transport_name());
- media_types_by_transport_name[transport_name].insert(
- transceiver->media_type());
+ if (ConfiguredForMedia()) {
+ for (const auto& transceiver :
+ rtp_manager()->transceivers()->UnsafeList()) {
+ if (transceiver->internal()->channel()) {
+ std::string transport_name(
+ transceiver->internal()->channel()->transport_name());
+ media_types_by_transport_name[transport_name].insert(
+ transceiver->media_type());
+ }
}
}
@@ -2888,10 +2900,13 @@
DataChannelTransportInterface* data_channel_transport) {
RTC_DCHECK_RUN_ON(network_thread());
bool ret = true;
- for (const auto& transceiver : rtp_manager()->transceivers()->UnsafeList()) {
- cricket::ChannelInterface* channel = transceiver->internal()->channel();
- if (channel && channel->mid() == mid) {
- ret = channel->SetRtpTransport(rtp_transport);
+ if (ConfiguredForMedia()) {
+ for (const auto& transceiver :
+ rtp_manager()->transceivers()->UnsafeList()) {
+ cricket::ChannelInterface* channel = transceiver->internal()->channel();
+ if (channel && channel->mid() == mid) {
+ ret = channel->SetRtpTransport(rtp_transport);
+ }
}
}
@@ -2976,4 +2991,10 @@
};
}
+cricket::MediaEngineInterface* PeerConnection::media_engine() {
+ RTC_DCHECK(context_);
+ RTC_DCHECK(context_->channel_manager());
+ return context_->channel_manager()->media_engine();
+}
+
} // namespace webrtc
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index 2907cb5..8c578d5 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -273,6 +273,9 @@
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
GetTransceiversInternal() const override {
RTC_DCHECK_RUN_ON(signaling_thread());
+ if (!ConfiguredForMedia()) {
+ return {};
+ }
return rtp_manager()->transceivers()->List();
}
@@ -596,6 +599,7 @@
cricket::ChannelManager* channel_manager() {
return context_->channel_manager();
}
+ cricket::MediaEngineInterface* media_engine();
const rtc::scoped_refptr<ConnectionContext> context_;
// Field trials active for this PeerConnection is the first of:
diff --git a/pc/peer_connection_factory.cc b/pc/peer_connection_factory.cc
index 6e6a72c..3380358 100644
--- a/pc/peer_connection_factory.cc
+++ b/pc/peer_connection_factory.cc
@@ -129,14 +129,14 @@
switch (kind) {
case cricket::MEDIA_TYPE_AUDIO: {
cricket::AudioCodecs cricket_codecs;
- channel_manager()->GetSupportedAudioSendCodecs(&cricket_codecs);
+ cricket_codecs = media_engine()->voice().send_codecs();
return ToRtpCapabilities(
cricket_codecs,
channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions());
}
case cricket::MEDIA_TYPE_VIDEO: {
cricket::VideoCodecs cricket_codecs;
- channel_manager()->GetSupportedVideoSendCodecs(&cricket_codecs);
+ cricket_codecs = media_engine()->video().send_codecs();
return ToRtpCapabilities(
cricket_codecs,
channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions());
@@ -156,7 +156,7 @@
switch (kind) {
case cricket::MEDIA_TYPE_AUDIO: {
cricket::AudioCodecs cricket_codecs;
- channel_manager()->GetSupportedAudioReceiveCodecs(&cricket_codecs);
+ cricket_codecs = media_engine()->voice().recv_codecs();
return ToRtpCapabilities(
cricket_codecs,
channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions());
@@ -195,6 +195,12 @@
channel_manager()->StopAecDump();
}
+cricket::MediaEngineInterface* PeerConnectionFactory::media_engine() const {
+ RTC_DCHECK(context_);
+ RTC_DCHECK(context_->channel_manager());
+ return context_->channel_manager()->media_engine();
+}
+
RTCErrorOr<rtc::scoped_refptr<PeerConnectionInterface>>
PeerConnectionFactory::CreatePeerConnectionOrError(
const PeerConnectionInterface::RTCConfiguration& configuration,
@@ -312,7 +318,7 @@
RTC_DCHECK_RUN_ON(worker_thread());
webrtc::Call::Config call_config(event_log, network_thread());
- if (!channel_manager()->media_engine() || !context_->call_factory()) {
+ if (!channel_manager() || !context_->call_factory()) {
return nullptr;
}
call_config.audio_state =
diff --git a/pc/peer_connection_factory.h b/pc/peer_connection_factory.h
index ff3d515..917f054 100644
--- a/pc/peer_connection_factory.h
+++ b/pc/peer_connection_factory.h
@@ -120,6 +120,8 @@
return context_->field_trials();
}
+ cricket::MediaEngineInterface* media_engine() const;
+
protected:
// Constructor used by the static Create() method. Modifies the dependencies.
PeerConnectionFactory(rtc::scoped_refptr<ConnectionContext> context,
diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc
index caa9ba5..1f6f879 100644
--- a/pc/rtp_transceiver.cc
+++ b/pc/rtp_transceiver.cc
@@ -22,6 +22,7 @@
#include "api/sequence_checker.h"
#include "media/base/codec.h"
#include "media/base/media_constants.h"
+#include "media/base/media_engine.h"
#include "pc/channel.h"
#include "pc/channel_manager.h"
#include "pc/rtp_media_utils.h"
@@ -562,7 +563,6 @@
RTCError RtpTransceiver::SetCodecPreferences(
rtc::ArrayView<RtpCodecCapability> codec_capabilities) {
RTC_DCHECK(unified_plan_);
-
// 3. If codecs is an empty list, set transceiver's [[PreferredCodecs]] slot
// to codecs and abort these steps.
if (codec_capabilities.empty()) {
@@ -581,15 +581,14 @@
RTCError result;
if (media_type_ == cricket::MEDIA_TYPE_AUDIO) {
std::vector<cricket::AudioCodec> recv_codecs, send_codecs;
- channel_manager_->GetSupportedAudioReceiveCodecs(&recv_codecs);
- channel_manager_->GetSupportedAudioSendCodecs(&send_codecs);
+ recv_codecs = media_engine()->voice().recv_codecs();
+ send_codecs = media_engine()->voice().send_codecs();
result = VerifyCodecPreferences(codecs, send_codecs, recv_codecs);
} else if (media_type_ == cricket::MEDIA_TYPE_VIDEO) {
std::vector<cricket::VideoCodec> recv_codecs, send_codecs;
channel_manager_->GetSupportedVideoReceiveCodecs(&recv_codecs);
channel_manager_->GetSupportedVideoSendCodecs(&send_codecs);
-
result = VerifyCodecPreferences(codecs, send_codecs, recv_codecs);
}
@@ -672,4 +671,8 @@
is_pc_closed_ = true;
}
+cricket::MediaEngineInterface* RtpTransceiver::media_engine() const {
+ return channel_manager_->media_engine();
+}
+
} // namespace webrtc
diff --git a/pc/rtp_transceiver.h b/pc/rtp_transceiver.h
index b61ca75..bbcbf23 100644
--- a/pc/rtp_transceiver.h
+++ b/pc/rtp_transceiver.h
@@ -47,6 +47,7 @@
namespace cricket {
class ChannelManager;
+class MediaEngineInterface;
}
namespace webrtc {
@@ -338,6 +339,7 @@
RTC_GUARDED_BY(thread_);
const std::function<void()> on_negotiation_needed_;
+ cricket::MediaEngineInterface* media_engine() const;
};
BEGIN_PRIMARY_PROXY_MAP(RtpTransceiver)
diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc
index ce2eefc..3c4b2c9 100644
--- a/pc/rtp_transceiver_unittest.cc
+++ b/pc/rtp_transceiver_unittest.cc
@@ -126,7 +126,7 @@
rtc::Thread::Current(),
receiver_),
&channel_manager_,
- channel_manager_.GetSupportedAudioRtpHeaderExtensions(),
+ channel_manager_.media_engine()->voice().GetRtpHeaderExtensions(),
/* on_negotiation_needed= */ [] {})) {}
static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
diff --git a/pc/rtp_transmission_manager.cc b/pc/rtp_transmission_manager.cc
index 6939a07..b2520d5 100644
--- a/pc/rtp_transmission_manager.cc
+++ b/pc/rtp_transmission_manager.cc
@@ -273,8 +273,8 @@
rtc::make_ref_counted<RtpTransceiver>(
sender, receiver, channel_manager(),
sender->media_type() == cricket::MEDIA_TYPE_AUDIO
- ? channel_manager()->GetSupportedAudioRtpHeaderExtensions()
- : channel_manager()->GetSupportedVideoRtpHeaderExtensions(),
+ ? media_engine()->voice().GetRtpHeaderExtensions()
+ : media_engine()->video().GetRtpHeaderExtensions(),
[this_weak_ptr = weak_ptr_factory_.GetWeakPtr()]() {
if (this_weak_ptr) {
this_weak_ptr->OnNegotiationNeeded();
@@ -690,4 +690,8 @@
return nullptr;
}
+cricket::MediaEngineInterface* RtpTransmissionManager::media_engine() const {
+ return channel_manager()->media_engine();
+}
+
} // namespace webrtc
diff --git a/pc/rtp_transmission_manager.h b/pc/rtp_transmission_manager.h
index 6e25f2d..532adcf 100644
--- a/pc/rtp_transmission_manager.h
+++ b/pc/rtp_transmission_manager.h
@@ -244,6 +244,8 @@
PeerConnectionObserver* Observer() const;
void OnNegotiationNeeded();
+ cricket::MediaEngineInterface* media_engine() const;
+
TransceiverList transceivers_;
// These lists store sender info seen in local/remote descriptions.
diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc
index 1d34081..95f22b7 100644
--- a/pc/sdp_offer_answer.cc
+++ b/pc/sdp_offer_answer.cc
@@ -1258,10 +1258,17 @@
}
// ==================================================================
-// Access to pc_ variables
+// Access to pc_ and context_ variables
cricket::ChannelManager* SdpOfferAnswerHandler::channel_manager() const {
return context_->channel_manager();
}
+
+cricket::MediaEngineInterface* SdpOfferAnswerHandler::media_engine() const {
+ RTC_DCHECK(context_);
+ RTC_DCHECK(context_->channel_manager());
+ return context_->channel_manager()->media_engine();
+}
+
TransceiverList* SdpOfferAnswerHandler::transceivers() {
if (!pc_->rtp_manager()) {
return nullptr;
@@ -1557,56 +1564,60 @@
<< ")";
return error;
}
- std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
- std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
- for (const auto& transceiver_ext : transceivers()->List()) {
- auto transceiver = transceiver_ext->internal();
- if (transceiver->stopped()) {
- continue;
- }
-
- // 2.2.7.1.1.(6-9): Set sender and receiver's transport slots.
- // Note that code paths that don't set MID won't be able to use
- // information about DTLS transports.
- if (transceiver->mid()) {
- auto dtls_transport = LookupDtlsTransportByMid(
- context_->network_thread(), transport_controller_s(),
- *transceiver->mid());
- transceiver->sender_internal()->set_transport(dtls_transport);
- transceiver->receiver_internal()->set_transport(dtls_transport);
- }
-
- const ContentInfo* content =
- FindMediaSectionForTransceiver(transceiver, local_description());
- if (!content) {
- continue;
- }
- const MediaContentDescription* media_desc = content->media_description();
- // 2.2.7.1.6: If description is of type "answer" or "pranswer", then run
- // the following steps:
- if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
- // 2.2.7.1.6.1: If direction is "sendonly" or "inactive", and
- // transceiver's [[FiredDirection]] slot is either "sendrecv" or
- // "recvonly", process the removal of a remote track for the media
- // description, given transceiver, removeList, and muteTracks.
- if (!RtpTransceiverDirectionHasRecv(media_desc->direction()) &&
- (transceiver->fired_direction() &&
- RtpTransceiverDirectionHasRecv(*transceiver->fired_direction()))) {
- ProcessRemovalOfRemoteTrack(transceiver_ext, &remove_list,
- &removed_streams);
+ if (ConfiguredForMedia()) {
+ std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
+ std::vector<rtc::scoped_refptr<MediaStreamInterface>> removed_streams;
+ for (const auto& transceiver_ext : transceivers()->List()) {
+ auto transceiver = transceiver_ext->internal();
+ if (transceiver->stopped()) {
+ continue;
}
- // 2.2.7.1.6.2: Set transceiver's [[CurrentDirection]] and
- // [[FiredDirection]] slots to direction.
- transceiver->set_current_direction(media_desc->direction());
- transceiver->set_fired_direction(media_desc->direction());
+
+ // 2.2.7.1.1.(6-9): Set sender and receiver's transport slots.
+ // Note that code paths that don't set MID won't be able to use
+ // information about DTLS transports.
+ if (transceiver->mid()) {
+ auto dtls_transport = LookupDtlsTransportByMid(
+ context_->network_thread(), transport_controller_s(),
+ *transceiver->mid());
+ transceiver->sender_internal()->set_transport(dtls_transport);
+ transceiver->receiver_internal()->set_transport(dtls_transport);
+ }
+
+ const ContentInfo* content =
+ FindMediaSectionForTransceiver(transceiver, local_description());
+ if (!content) {
+ continue;
+ }
+ const MediaContentDescription* media_desc =
+ content->media_description();
+ // 2.2.7.1.6: If description is of type "answer" or "pranswer", then run
+ // the following steps:
+ if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
+ // 2.2.7.1.6.1: If direction is "sendonly" or "inactive", and
+ // transceiver's [[FiredDirection]] slot is either "sendrecv" or
+ // "recvonly", process the removal of a remote track for the media
+ // description, given transceiver, removeList, and muteTracks.
+ if (!RtpTransceiverDirectionHasRecv(media_desc->direction()) &&
+ (transceiver->fired_direction() &&
+ RtpTransceiverDirectionHasRecv(
+ *transceiver->fired_direction()))) {
+ ProcessRemovalOfRemoteTrack(transceiver_ext, &remove_list,
+ &removed_streams);
+ }
+ // 2.2.7.1.6.2: Set transceiver's [[CurrentDirection]] and
+ // [[FiredDirection]] slots to direction.
+ transceiver->set_current_direction(media_desc->direction());
+ transceiver->set_fired_direction(media_desc->direction());
+ }
}
- }
- auto observer = pc_->Observer();
- for (const auto& transceiver : remove_list) {
- observer->OnRemoveTrack(transceiver->receiver());
- }
- for (const auto& stream : removed_streams) {
- observer->OnRemoveStream(stream);
+ auto observer = pc_->Observer();
+ for (const auto& transceiver : remove_list) {
+ observer->OnRemoveTrack(transceiver->receiver());
+ }
+ for (const auto& stream : removed_streams) {
+ observer->OnRemoveStream(stream);
+ }
}
} else {
// Media channels will be created only when offer is set. These may use new
@@ -1650,35 +1661,39 @@
}
if (IsUnifiedPlan()) {
- // We must use List and not ListInternal here because
- // transceivers()->StableState() is indexed by the non-internal refptr.
- for (const auto& transceiver_ext : transceivers()->List()) {
- auto transceiver = transceiver_ext->internal();
- if (transceiver->stopped()) {
- continue;
- }
- const ContentInfo* content =
- FindMediaSectionForTransceiver(transceiver, local_description());
- if (!content) {
- continue;
- }
- cricket::ChannelInterface* channel = transceiver->channel();
- if (content->rejected || !channel || channel->local_streams().empty()) {
- // 0 is a special value meaning "this sender has no associated send
- // stream". Need to call this so the sender won't attempt to configure
- // a no longer existing stream and run into DCHECKs in the lower
- // layers.
- transceiver->sender_internal()->SetSsrc(0);
- } else {
- // Get the StreamParams from the channel which could generate SSRCs.
- const std::vector<StreamParams>& streams = channel->local_streams();
- transceiver->sender_internal()->set_stream_ids(streams[0].stream_ids());
- auto encodings = transceiver->sender_internal()->init_send_encodings();
- transceiver->sender_internal()->SetSsrc(streams[0].first_ssrc());
- if (!encodings.empty()) {
- transceivers()
- ->StableState(transceiver_ext)
- ->SetInitSendEncodings(encodings);
+ if (ConfiguredForMedia()) {
+ // We must use List and not ListInternal here because
+ // transceivers()->StableState() is indexed by the non-internal refptr.
+ for (const auto& transceiver_ext : transceivers()->List()) {
+ auto transceiver = transceiver_ext->internal();
+ if (transceiver->stopped()) {
+ continue;
+ }
+ const ContentInfo* content =
+ FindMediaSectionForTransceiver(transceiver, local_description());
+ if (!content) {
+ continue;
+ }
+ cricket::ChannelInterface* channel = transceiver->channel();
+ if (content->rejected || !channel || channel->local_streams().empty()) {
+ // 0 is a special value meaning "this sender has no associated send
+ // stream". Need to call this so the sender won't attempt to configure
+ // a no longer existing stream and run into DCHECKs in the lower
+ // layers.
+ transceiver->sender_internal()->SetSsrc(0);
+ } else {
+ // Get the StreamParams from the channel which could generate SSRCs.
+ const std::vector<StreamParams>& streams = channel->local_streams();
+ transceiver->sender_internal()->set_stream_ids(
+ streams[0].stream_ids());
+ auto encodings =
+ transceiver->sender_internal()->init_send_encodings();
+ transceiver->sender_internal()->SetSsrc(streams[0].first_ssrc());
+ if (!encodings.empty()) {
+ transceivers()
+ ->StableState(transceiver_ext)
+ ->SetInitSendEncodings(encodings);
+ }
}
}
}
@@ -1938,6 +1953,9 @@
SdpType sdp_type) {
RTC_DCHECK_RUN_ON(signaling_thread());
RTC_DCHECK(IsUnifiedPlan());
+ if (!ConfiguredForMedia()) {
+ return;
+ }
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
now_receiving_transceivers;
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remove_list;
@@ -2725,7 +2743,9 @@
} else {
RTC_DCHECK(type == SdpType::kAnswer);
ChangeSignalingState(PeerConnectionInterface::kStable);
- transceivers()->DiscardStableStates();
+ if (ConfiguredForMedia()) {
+ transceivers()->DiscardStableStates();
+ }
}
// Update internal objects according to the session description's media
@@ -3151,6 +3171,9 @@
if (!cricket::GetFirstDataContent(description->description()->contents()))
return true;
}
+ if (!ConfiguredForMedia()) {
+ return false;
+ }
// 5. For each transceiver in connection's set of transceivers, perform the
// following checks:
@@ -3262,7 +3285,6 @@
}
}
}
-
// If all the preceding checks were performed and true was not returned,
// nothing remains to be negotiated; return false.
return false;
@@ -3841,38 +3863,43 @@
void SdpOfferAnswerHandler::GetOptionsForPlanBOffer(
const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options,
cricket::MediaSessionOptions* session_options) {
- // Figure out transceiver directional preferences.
- bool send_audio =
- !rtp_manager()->GetAudioTransceiver()->internal()->senders().empty();
- bool send_video =
- !rtp_manager()->GetVideoTransceiver()->internal()->senders().empty();
+ bool offer_new_data_description =
+ data_channel_controller()->HasDataChannels();
+ bool send_audio = false;
+ bool send_video = false;
+ bool recv_audio = false;
+ bool recv_video = false;
+ if (ConfiguredForMedia()) {
+ // Figure out transceiver directional preferences.
+ send_audio =
+ !rtp_manager()->GetAudioTransceiver()->internal()->senders().empty();
+ send_video =
+ !rtp_manager()->GetVideoTransceiver()->internal()->senders().empty();
- // By default, generate sendrecv/recvonly m= sections.
- bool recv_audio = true;
- bool recv_video = true;
-
+ // By default, generate sendrecv/recvonly m= sections.
+ recv_audio = true;
+ recv_video = true;
+ }
// By default, only offer a new m= section if we have media to send with it.
bool offer_new_audio_description = send_audio;
bool offer_new_video_description = send_video;
- bool offer_new_data_description =
- data_channel_controller()->HasDataChannels();
-
- // The "offer_to_receive_X" options allow those defaults to be overridden.
- if (offer_answer_options.offer_to_receive_audio !=
- PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined) {
- recv_audio = (offer_answer_options.offer_to_receive_audio > 0);
- offer_new_audio_description =
- offer_new_audio_description ||
- (offer_answer_options.offer_to_receive_audio > 0);
+ if (ConfiguredForMedia()) {
+ // The "offer_to_receive_X" options allow those defaults to be overridden.
+ if (offer_answer_options.offer_to_receive_audio !=
+ PeerConnectionInterface::RTCOfferAnswerOptions::kUndefined) {
+ recv_audio = (offer_answer_options.offer_to_receive_audio > 0);
+ offer_new_audio_description =
+ offer_new_audio_description ||
+ (offer_answer_options.offer_to_receive_audio > 0);
+ }
+ if (offer_answer_options.offer_to_receive_video !=
+ RTCOfferAnswerOptions::kUndefined) {
+ recv_video = (offer_answer_options.offer_to_receive_video > 0);
+ offer_new_video_description =
+ offer_new_video_description ||
+ (offer_answer_options.offer_to_receive_video > 0);
+ }
}
- if (offer_answer_options.offer_to_receive_video !=
- RTCOfferAnswerOptions::kUndefined) {
- recv_video = (offer_answer_options.offer_to_receive_video > 0);
- offer_new_video_description =
- offer_new_video_description ||
- (offer_answer_options.offer_to_receive_video > 0);
- }
-
absl::optional<size_t> audio_index;
absl::optional<size_t> video_index;
absl::optional<size_t> data_index;
@@ -3887,42 +3914,44 @@
&audio_index, &video_index, &data_index, session_options);
}
- // Add audio/video/data m= sections to the end if needed.
- if (!audio_index && offer_new_audio_description) {
- cricket::MediaDescriptionOptions options(
- cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO,
- RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), false);
- options.header_extensions =
- channel_manager()->GetSupportedAudioRtpHeaderExtensions();
- session_options->media_description_options.push_back(options);
- audio_index = session_options->media_description_options.size() - 1;
- }
- if (!video_index && offer_new_video_description) {
- cricket::MediaDescriptionOptions options(
- cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO,
- RtpTransceiverDirectionFromSendRecv(send_video, recv_video), false);
- options.header_extensions =
- channel_manager()->GetSupportedVideoRtpHeaderExtensions();
- session_options->media_description_options.push_back(options);
- video_index = session_options->media_description_options.size() - 1;
+ if (ConfiguredForMedia()) {
+ // Add audio/video/data m= sections to the end if needed.
+ if (!audio_index && offer_new_audio_description) {
+ cricket::MediaDescriptionOptions options(
+ cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO,
+ RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio), false);
+ options.header_extensions =
+ media_engine()->voice().GetRtpHeaderExtensions();
+ session_options->media_description_options.push_back(options);
+ audio_index = session_options->media_description_options.size() - 1;
+ }
+ if (!video_index && offer_new_video_description) {
+ cricket::MediaDescriptionOptions options(
+ cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO,
+ RtpTransceiverDirectionFromSendRecv(send_video, recv_video), false);
+ options.header_extensions =
+ media_engine()->video().GetRtpHeaderExtensions();
+ session_options->media_description_options.push_back(options);
+ video_index = session_options->media_description_options.size() - 1;
+ }
+ cricket::MediaDescriptionOptions* audio_media_description_options =
+ !audio_index
+ ? nullptr
+ : &session_options->media_description_options[*audio_index];
+ cricket::MediaDescriptionOptions* video_media_description_options =
+ !video_index
+ ? nullptr
+ : &session_options->media_description_options[*video_index];
+
+ AddPlanBRtpSenderOptions(rtp_manager()->GetSendersInternal(),
+ audio_media_description_options,
+ video_media_description_options,
+ offer_answer_options.num_simulcast_layers);
}
if (!data_index && offer_new_data_description) {
session_options->media_description_options.push_back(
GetMediaDescriptionOptionsForActiveData(cricket::CN_DATA));
- data_index = session_options->media_description_options.size() - 1;
}
-
- cricket::MediaDescriptionOptions* audio_media_description_options =
- !audio_index ? nullptr
- : &session_options->media_description_options[*audio_index];
- cricket::MediaDescriptionOptions* video_media_description_options =
- !video_index ? nullptr
- : &session_options->media_description_options[*video_index];
-
- AddPlanBRtpSenderOptions(rtp_manager()->GetSendersInternal(),
- audio_media_description_options,
- video_media_description_options,
- offer_answer_options.num_simulcast_layers);
}
void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer(
@@ -4028,27 +4057,29 @@
// and not associated). Reuse media sections marked as recyclable first,
// otherwise append to the end of the offer. New media sections should be
// added in the order they were added to the PeerConnection.
- for (const auto& transceiver : transceivers()->ListInternal()) {
- if (transceiver->mid() || transceiver->stopping()) {
- continue;
+ if (ConfiguredForMedia()) {
+ for (const auto& transceiver : transceivers()->ListInternal()) {
+ if (transceiver->mid() || transceiver->stopping()) {
+ continue;
+ }
+ size_t mline_index;
+ if (!recycleable_mline_indices.empty()) {
+ mline_index = recycleable_mline_indices.front();
+ recycleable_mline_indices.pop();
+ session_options->media_description_options[mline_index] =
+ GetMediaDescriptionOptionsForTransceiver(
+ transceiver, mid_generator_.GenerateString(),
+ /*is_create_offer=*/true);
+ } else {
+ mline_index = session_options->media_description_options.size();
+ session_options->media_description_options.push_back(
+ GetMediaDescriptionOptionsForTransceiver(
+ transceiver, mid_generator_.GenerateString(),
+ /*is_create_offer=*/true));
+ }
+ // See comment above for why CreateOffer changes the transceiver's state.
+ transceiver->set_mline_index(mline_index);
}
- size_t mline_index;
- if (!recycleable_mline_indices.empty()) {
- mline_index = recycleable_mline_indices.front();
- recycleable_mline_indices.pop();
- session_options->media_description_options[mline_index] =
- GetMediaDescriptionOptionsForTransceiver(
- transceiver, mid_generator_.GenerateString(),
- /*is_create_offer=*/true);
- } else {
- mline_index = session_options->media_description_options.size();
- session_options->media_description_options.push_back(
- GetMediaDescriptionOptionsForTransceiver(
- transceiver, mid_generator_.GenerateString(),
- /*is_create_offer=*/true));
- }
- // See comment above for why CreateOffer changes the transceiver's state.
- transceiver->set_mline_index(mline_index);
}
// Lastly, add a m-section if we have local data channels and an m section
// does not already exist.
@@ -4088,25 +4119,32 @@
void SdpOfferAnswerHandler::GetOptionsForPlanBAnswer(
const PeerConnectionInterface::RTCOfferAnswerOptions& offer_answer_options,
cricket::MediaSessionOptions* session_options) {
- // Figure out transceiver directional preferences.
- bool send_audio =
- !rtp_manager()->GetAudioTransceiver()->internal()->senders().empty();
- bool send_video =
- !rtp_manager()->GetVideoTransceiver()->internal()->senders().empty();
+ bool send_audio = false;
+ bool recv_audio = false;
+ bool send_video = false;
+ bool recv_video = false;
- // By default, generate sendrecv/recvonly m= sections. The direction is also
- // restricted by the direction in the offer.
- bool recv_audio = true;
- bool recv_video = true;
+ if (ConfiguredForMedia()) {
+ // Figure out transceiver directional preferences.
+ send_audio =
+ !rtp_manager()->GetAudioTransceiver()->internal()->senders().empty();
+ send_video =
+ !rtp_manager()->GetVideoTransceiver()->internal()->senders().empty();
- // The "offer_to_receive_X" options allow those defaults to be overridden.
- if (offer_answer_options.offer_to_receive_audio !=
- RTCOfferAnswerOptions::kUndefined) {
- recv_audio = (offer_answer_options.offer_to_receive_audio > 0);
- }
- if (offer_answer_options.offer_to_receive_video !=
- RTCOfferAnswerOptions::kUndefined) {
- recv_video = (offer_answer_options.offer_to_receive_video > 0);
+ // By default, generate sendrecv/recvonly m= sections. The direction is also
+ // restricted by the direction in the offer.
+ recv_audio = true;
+ recv_video = true;
+
+ // The "offer_to_receive_X" options allow those defaults to be overridden.
+ if (offer_answer_options.offer_to_receive_audio !=
+ RTCOfferAnswerOptions::kUndefined) {
+ recv_audio = (offer_answer_options.offer_to_receive_audio > 0);
+ }
+ if (offer_answer_options.offer_to_receive_video !=
+ RTCOfferAnswerOptions::kUndefined) {
+ recv_video = (offer_answer_options.offer_to_receive_video > 0);
+ }
}
absl::optional<size_t> audio_index;
@@ -4129,10 +4167,12 @@
!video_index ? nullptr
: &session_options->media_description_options[*video_index];
- AddPlanBRtpSenderOptions(rtp_manager()->GetSendersInternal(),
- audio_media_description_options,
- video_media_description_options,
- offer_answer_options.num_simulcast_layers);
+ if (ConfiguredForMedia()) {
+ AddPlanBRtpSenderOptions(rtp_manager()->GetSendersInternal(),
+ audio_media_description_options,
+ video_media_description_options,
+ offer_answer_options.num_simulcast_layers);
+ }
}
void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanAnswer(
@@ -4477,6 +4517,9 @@
void SdpOfferAnswerHandler::EnableSending() {
TRACE_EVENT0("webrtc", "SdpOfferAnswerHandler::EnableSending");
RTC_DCHECK_RUN_ON(signaling_thread());
+ if (!ConfiguredForMedia()) {
+ return;
+ }
for (const auto& transceiver : transceivers()->ListInternal()) {
cricket::ChannelInterface* channel = transceiver->channel();
if (channel) {
@@ -4497,60 +4540,63 @@
RTC_DCHECK_RUN_ON(signaling_thread());
RTC_DCHECK(sdesc);
- // Note: This will perform an Invoke over to the worker thread, which we'll
- // also do in a loop below.
- if (!UpdatePayloadTypeDemuxingState(source, bundle_groups_by_mid)) {
- // Note that this is never expected to fail, since RtpDemuxer doesn't return
- // an error when changing payload type demux criteria, which is all this
- // does.
- return RTCError(RTCErrorType::INTERNAL_ERROR,
- "Failed to update payload type demuxing state.");
- }
-
- // Push down the new SDP media section for each audio/video transceiver.
- auto rtp_transceivers = transceivers()->ListInternal();
- std::vector<
- std::pair<cricket::ChannelInterface*, const MediaContentDescription*>>
- channels;
- for (const auto& transceiver : rtp_transceivers) {
- const ContentInfo* content_info =
- FindMediaSectionForTransceiver(transceiver, sdesc);
- cricket::ChannelInterface* channel = transceiver->channel();
- if (!channel || !content_info || content_info->rejected) {
- continue;
- }
- const MediaContentDescription* content_desc =
- content_info->media_description();
- if (!content_desc) {
- continue;
+ if (ConfiguredForMedia()) {
+ // Note: This will perform an Invoke over to the worker thread, which we'll
+ // also do in a loop below.
+ if (!UpdatePayloadTypeDemuxingState(source, bundle_groups_by_mid)) {
+ // Note that this is never expected to fail, since RtpDemuxer doesn't
+ // return an error when changing payload type demux criteria, which is all
+ // this does.
+ return RTCError(RTCErrorType::INTERNAL_ERROR,
+ "Failed to update payload type demuxing state.");
}
- transceiver->OnNegotiationUpdate(type, content_desc);
- channels.push_back(std::make_pair(channel, content_desc));
- }
+ // Push down the new SDP media section for each audio/video transceiver.
+ auto rtp_transceivers = transceivers()->ListInternal();
+ std::vector<
+ std::pair<cricket::ChannelInterface*, const MediaContentDescription*>>
+ channels;
+ for (const auto& transceiver : rtp_transceivers) {
+ const ContentInfo* content_info =
+ FindMediaSectionForTransceiver(transceiver, sdesc);
+ cricket::ChannelInterface* channel = transceiver->channel();
+ if (!channel || !content_info || content_info->rejected) {
+ continue;
+ }
+ const MediaContentDescription* content_desc =
+ content_info->media_description();
+ if (!content_desc) {
+ continue;
+ }
- // This for-loop of invokes helps audio impairment during re-negotiations.
- // One of the causes is that downstairs decoder creation is synchronous at the
- // moment, and that a decoder is created for each codec listed in the SDP.
- //
- // TODO(bugs.webrtc.org/12840): consider merging the invokes again after
- // these projects have shipped:
- // - bugs.webrtc.org/12462
- // - crbug.com/1157227
- // - crbug.com/1187289
- for (const auto& entry : channels) {
- std::string error;
- bool success =
- context_->worker_thread()->Invoke<bool>(RTC_FROM_HERE, [&]() {
- return (source == cricket::CS_LOCAL)
- ? entry.first->SetLocalContent(entry.second, type, error)
- : entry.first->SetRemoteContent(entry.second, type, error);
- });
- if (!success) {
- return RTCError(RTCErrorType::INVALID_PARAMETER, error);
+ transceiver->OnNegotiationUpdate(type, content_desc);
+ channels.push_back(std::make_pair(channel, content_desc));
+ }
+
+ // This for-loop of invokes helps audio impairment during re-negotiations.
+ // One of the causes is that downstairs decoder creation is synchronous at
+ // the moment, and that a decoder is created for each codec listed in the
+ // SDP.
+ //
+ // TODO(bugs.webrtc.org/12840): consider merging the invokes again after
+ // these projects have shipped:
+ // - bugs.webrtc.org/12462
+ // - crbug.com/1157227
+ // - crbug.com/1187289
+ for (const auto& entry : channels) {
+ std::string error;
+ bool success =
+ context_->worker_thread()->Invoke<bool>(RTC_FROM_HERE, [&]() {
+ return (source == cricket::CS_LOCAL)
+ ? entry.first->SetLocalContent(entry.second, type, error)
+ : entry.first->SetRemoteContent(entry.second, type,
+ error);
+ });
+ if (!success) {
+ return RTCError(RTCErrorType::INVALID_PARAMETER, error);
+ }
}
}
-
// Need complete offer/answer with an SCTP m= section before starting SCTP,
// according to https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-19
if (pc_->sctp_mid() && local_description() && remote_description()) {
@@ -4604,6 +4650,9 @@
// run the following steps:
if (!IsUnifiedPlan())
return;
+ if (!ConfiguredForMedia()) {
+ return;
+ }
// Traverse a copy of the transceiver list.
auto transceiver_list = transceivers()->List();
for (auto transceiver : transceiver_list) {
@@ -4638,18 +4687,21 @@
void SdpOfferAnswerHandler::RemoveUnusedChannels(
const SessionDescription* desc) {
RTC_DCHECK_RUN_ON(signaling_thread());
- // Destroy video channel first since it may have a pointer to the
- // voice channel.
- const cricket::ContentInfo* video_info = cricket::GetFirstVideoContent(desc);
- if (!video_info || video_info->rejected) {
- rtp_manager()->GetVideoTransceiver()->internal()->ClearChannel();
- }
+ if (ConfiguredForMedia()) {
+ // Destroy video channel first since it may have a pointer to the
+ // voice channel.
+ const cricket::ContentInfo* video_info =
+ cricket::GetFirstVideoContent(desc);
+ if (!video_info || video_info->rejected) {
+ rtp_manager()->GetVideoTransceiver()->internal()->ClearChannel();
+ }
- const cricket::ContentInfo* audio_info = cricket::GetFirstAudioContent(desc);
- if (!audio_info || audio_info->rejected) {
- rtp_manager()->GetAudioTransceiver()->internal()->ClearChannel();
+ const cricket::ContentInfo* audio_info =
+ cricket::GetFirstAudioContent(desc);
+ if (!audio_info || audio_info->rejected) {
+ rtp_manager()->GetAudioTransceiver()->internal()->ClearChannel();
+ }
}
-
const cricket::ContentInfo* data_info = cricket::GetFirstDataContent(desc);
if (!data_info) {
RTCError error(RTCErrorType::OPERATION_ERROR_WITH_DATA,
@@ -4967,7 +5019,7 @@
*audio_index = session_options->media_description_options.size() - 1;
}
session_options->media_description_options.back().header_extensions =
- channel_manager()->GetSupportedAudioRtpHeaderExtensions();
+ media_engine()->voice().GetRtpHeaderExtensions();
} else if (IsVideoContent(&content)) {
// If we already have an video m= section, reject this extra one.
if (*video_index) {
@@ -4984,7 +5036,7 @@
*video_index = session_options->media_description_options.size() - 1;
}
session_options->media_description_options.back().header_extensions =
- channel_manager()->GetSupportedVideoRtpHeaderExtensions();
+ media_engine()->video().GetRtpHeaderExtensions();
} else if (IsUnsupportedContent(&content)) {
session_options->media_description_options.push_back(
cricket::MediaDescriptionOptions(cricket::MEDIA_TYPE_UNSUPPORTED,
@@ -5208,4 +5260,8 @@
});
}
+bool SdpOfferAnswerHandler::ConfiguredForMedia() const {
+ return context_->channel_manager();
+}
+
} // namespace webrtc
diff --git a/pc/sdp_offer_answer.h b/pc/sdp_offer_answer.h
index de814ec..6a0aaaa 100644
--- a/pc/sdp_offer_answer.h
+++ b/pc/sdp_offer_answer.h
@@ -478,7 +478,7 @@
// This enables media to flow on all configured audio/video channels.
void EnableSending();
// Push the media parts of the local or remote session description
- // down to all of the channels.
+ // down to all of the channels, and start SCTP if needed.
RTCError PushdownMediaDescription(
SdpType type,
cricket::ContentSource source,
@@ -576,6 +576,7 @@
// ==================================================================
// Access to pc_ variables
cricket::ChannelManager* channel_manager() const;
+ cricket::MediaEngineInterface* media_engine() const;
TransceiverList* transceivers();
const TransceiverList* transceivers() const;
DataChannelController* data_channel_controller();
@@ -595,6 +596,7 @@
// ===================================================================
const cricket::AudioOptions& audio_options() { return audio_options_; }
const cricket::VideoOptions& video_options() { return video_options_; }
+ bool ConfiguredForMedia() const;
PeerConnectionSdpMethods* const pc_;
ConnectionContext* const context_;
diff --git a/pc/test/fake_peer_connection_for_stats.h b/pc/test/fake_peer_connection_for_stats.h
index e612f0d..e7ed804 100644
--- a/pc/test/fake_peer_connection_for_stats.h
+++ b/pc/test/fake_peer_connection_for_stats.h
@@ -415,7 +415,10 @@
class TestChannelManager : public cricket::ChannelManager {
public:
TestChannelManager(rtc::Thread* worker, rtc::Thread* network)
- : cricket::ChannelManager(nullptr, true, worker, network) {}
+ : cricket::ChannelManager(std::make_unique<cricket::FakeMediaEngine>(),
+ true,
+ worker,
+ network) {}
};
rtc::Thread* const network_thread_;