Introduce new way to enable media in PeerConnectionFactory
instead of requiring to pass in call_factory and media_engine
webrtc users should set media_factory member and media dependencies into PeerConnectionFactoryDependencies
Bug: webrtc:15574
Change-Id: I2dc584fe7afa41c9f170bdc51533396155cdcb06
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325320
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41049}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 1eb3876..bd0f52e 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -35,6 +35,20 @@
]
}
+rtc_source_set("enable_media") {
+ visibility = [ "*" ]
+ sources = [
+ "enable_media.cc",
+ "enable_media.h",
+ ]
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../call",
+ "../media:rtc_audio_video",
+ "../pc:media_factory",
+ ]
+}
+
if (!build_with_chromium) {
rtc_library("create_peerconnection_factory") {
visibility = [ "*" ]
@@ -305,6 +319,7 @@
":turn_customizer",
"../call:rtp_interfaces",
"../p2p:rtc_p2p",
+ "../pc:media_factory",
"../rtc_base:copy_on_write_buffer",
"../rtc_base:logging",
"../rtc_base:network",
diff --git a/api/call/call_factory_interface.h b/api/call/call_factory_interface.h
index fde8cba..1c12352 100644
--- a/api/call/call_factory_interface.h
+++ b/api/call/call_factory_interface.h
@@ -24,6 +24,9 @@
// This interface exists to allow webrtc to be optionally built without media
// support (i.e., if only being used for data channels). PeerConnectionFactory
// is constructed with a CallFactoryInterface, which may or may not be null.
+// TODO(bugs.webrtc.org/15574): Delete this interface when
+// `PeerConnectionFactoryDependencies::call_factory` is removed in favor of
+// `PeerConnectionFactoryDependencies::media_factory`.
class CallFactoryInterface {
public:
virtual ~CallFactoryInterface() = default;
diff --git a/api/enable_media.cc b/api/enable_media.cc
new file mode 100644
index 0000000..4c97ace
--- /dev/null
+++ b/api/enable_media.cc
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2023 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 "api/enable_media.h"
+
+#include <memory>
+#include <utility>
+
+#include "api/peer_connection_interface.h"
+#include "call/call_factory.h"
+#include "media/engine/webrtc_media_engine.h"
+#include "media/engine/webrtc_video_engine.h"
+#include "media/engine/webrtc_voice_engine.h"
+#include "pc/media_factory.h"
+
+namespace webrtc {
+namespace {
+
+using ::cricket::CompositeMediaEngine;
+using ::cricket::MediaEngineInterface;
+using ::cricket::WebRtcVideoEngine;
+using ::cricket::WebRtcVoiceEngine;
+
+class MediaFactoryImpl : public MediaFactory {
+ public:
+ MediaFactoryImpl() = default;
+ MediaFactoryImpl(const MediaFactoryImpl&) = delete;
+ MediaFactoryImpl& operator=(const MediaFactoryImpl&) = delete;
+ ~MediaFactoryImpl() override = default;
+
+ std::unique_ptr<Call> CreateCall(const CallConfig& config) override {
+ CallFactory call_factory;
+ return static_cast<CallFactoryInterface&>(call_factory).CreateCall(config);
+ }
+
+ std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
+ PeerConnectionFactoryDependencies& deps) override {
+ std::unique_ptr<FieldTrialsView> fallback_trials;
+ const FieldTrialsView* trials;
+ if (deps.trials) {
+ trials = deps.trials.get();
+ } else {
+ fallback_trials = std::make_unique<FieldTrialBasedConfig>();
+ trials = fallback_trials.get();
+ }
+ auto audio_engine = std::make_unique<WebRtcVoiceEngine>(
+ deps.task_queue_factory.get(), deps.adm.get(),
+ std::move(deps.audio_encoder_factory),
+ std::move(deps.audio_decoder_factory), std::move(deps.audio_mixer),
+ std::move(deps.audio_processing), /*audio_frame_processor=*/nullptr,
+ /*owned_audio_frame_processor=*/std::move(deps.audio_frame_processor),
+ *trials);
+ auto video_engine = std::make_unique<WebRtcVideoEngine>(
+ std::move(deps.video_encoder_factory),
+ std::move(deps.video_decoder_factory), *trials);
+ return std::make_unique<CompositeMediaEngine>(std::move(fallback_trials),
+ std::move(audio_engine),
+ std::move(video_engine));
+ }
+};
+
+} // namespace
+
+void EnableMedia(PeerConnectionFactoryDependencies& deps) {
+ deps.media_factory = std::make_unique<MediaFactoryImpl>();
+}
+
+} // namespace webrtc
diff --git a/api/enable_media.h b/api/enable_media.h
new file mode 100644
index 0000000..8e0b66b
--- /dev/null
+++ b/api/enable_media.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2023 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.
+ */
+
+#ifndef API_ENABLE_MEDIA_H_
+#define API_ENABLE_MEDIA_H_
+
+#include "api/peer_connection_interface.h"
+
+namespace webrtc {
+
+// Enables media support for PeerConnnectionFactory created from `deps`
+// This function is located in its own build target to allow webrtc users that
+// do not need any media to avoid linking media specific code and thus to reduce
+// binary size.
+void EnableMedia(PeerConnectionFactoryDependencies& deps);
+
+} // namespace webrtc
+
+#endif // API_ENABLE_MEDIA_H_
diff --git a/api/peer_connection_interface.cc b/api/peer_connection_interface.cc
index 050b61d..dedfd35 100644
--- a/api/peer_connection_interface.cc
+++ b/api/peer_connection_interface.cc
@@ -12,6 +12,8 @@
#include <utility>
+#include "pc/media_factory.h"
+
namespace webrtc {
PeerConnectionInterface::IceServer::IceServer() = default;
diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h
index 9243190..7c81b16 100644
--- a/api/peer_connection_interface.h
+++ b/api/peer_connection_interface.h
@@ -120,6 +120,8 @@
#include "api/transport/sctp_transport_factory_interface.h"
#include "api/turn_customizer.h"
#include "api/video/video_bitrate_allocator_factory.h"
+#include "api/video_codecs/video_decoder_factory.h"
+#include "api/video_codecs/video_encoder_factory.h"
#include "call/rtp_transport_controller_send_factory_interface.h"
#include "media/base/media_config.h"
#include "media/base/media_engine.h"
@@ -145,6 +147,9 @@
namespace webrtc {
+// MediaFactory class definition is not part of the api.
+class MediaFactory;
+
// MediaStream container interface.
class StreamCollectionInterface : public rtc::RefCountInterface {
public:
@@ -1427,6 +1432,8 @@
// called without a `port_allocator`.
std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory;
std::unique_ptr<TaskQueueFactory> task_queue_factory;
+ // TODO(bugs.webrtc.org/15574): Deprecate `media_engine` and `call_factory`
+ // when chromium and webrtc are updated to use `media_factory` instead.
std::unique_ptr<cricket::MediaEngineInterface> media_engine;
std::unique_ptr<CallFactoryInterface> call_factory;
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory;
@@ -1447,6 +1454,23 @@
std::unique_ptr<RtpTransportControllerSendFactoryInterface>
transport_controller_send_factory;
std::unique_ptr<Metronome> metronome;
+
+ // Media specific dependencies. Unused when `media_factory == nullptr`.
+ rtc::scoped_refptr<AudioDeviceModule> adm;
+ rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory;
+ rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory;
+ rtc::scoped_refptr<AudioMixer> audio_mixer;
+ rtc::scoped_refptr<AudioProcessing> audio_processing;
+ std::unique_ptr<AudioFrameProcessor> audio_frame_processor;
+ std::unique_ptr<VideoEncoderFactory> video_encoder_factory;
+ std::unique_ptr<VideoDecoderFactory> video_decoder_factory;
+
+ // The `media_factory` members allows webrtc to be optionally built without
+ // media support (i.e., if only being used for data channels).
+ // By default media is disabled. To enable media call
+ // `EnableMedia(PeerConnectionFactoryDependencies&)`. Definition of the
+ // `MediaFactory` interface is a webrtc implementation detail.
+ std::unique_ptr<MediaFactory> media_factory;
};
// PeerConnectionFactoryInterface is the factory interface used for creating
diff --git a/media/engine/webrtc_media_engine.h b/media/engine/webrtc_media_engine.h
index 0f6dce3..fa4046b 100644
--- a/media/engine/webrtc_media_engine.h
+++ b/media/engine/webrtc_media_engine.h
@@ -63,6 +63,8 @@
// CreateMediaEngine may be called on any thread, though the engine is
// only expected to be used on one thread, internally called the "worker
// thread". This is the thread Init must be called on.
+// TODO(bugs.webrtc.org/15574): Deprecate this helper in favor of creating
+// media engine with `PeerConnectionFactoryDependencies::media_factory`.
RTC_EXPORT std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
MediaEngineDependencies dependencies);
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index 7c22a26..7952ffd 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -314,6 +314,15 @@
]
}
+rtc_source_set("media_factory") {
+ sources = [ "media_factory.h" ]
+ deps = [
+ "../api:callfactory_api",
+ "../call:call_interfaces",
+ "../media:rtc_media_base",
+ ]
+}
+
rtc_source_set("media_session") {
visibility = [ "*" ] # Used by Chrome
sources = [
@@ -919,6 +928,7 @@
"connection_context.h",
]
deps = [
+ ":media_factory",
"../api:callfactory_api",
"../api:field_trials_view",
"../api:libjingle_peerconnection_api",
@@ -2405,6 +2415,7 @@
"../api:create_peerconnection_factory",
"../api:dtls_transport_interface",
"../api:dtmf_sender_interface",
+ "../api:enable_media",
"../api:fake_frame_decryptor",
"../api:fake_frame_encryptor",
"../api:field_trials_view",
diff --git a/pc/connection_context.cc b/pc/connection_context.cc
index f436e27..1347008 100644
--- a/pc/connection_context.cc
+++ b/pc/connection_context.cc
@@ -17,6 +17,7 @@
#include "api/transport/field_trial_based_config.h"
#include "media/base/media_engine.h"
#include "media/sctp/sctp_transport_factory.h"
+#include "pc/media_factory.h"
#include "rtc_base/helpers.h"
#include "rtc_base/internal/default_socket_server.h"
#include "rtc_base/socket_server.h"
@@ -78,6 +79,13 @@
// Static
rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
PeerConnectionFactoryDependencies* dependencies) {
+ if (dependencies->media_factory != nullptr) {
+ RTC_CHECK(dependencies->media_engine == nullptr)
+ << "media_factory replaces media_engine. Do not set media_engine.";
+ RTC_CHECK(dependencies->call_factory == nullptr)
+ << "media_factory replaces call_factory. Do not set call_factory.";
+ }
+
return rtc::scoped_refptr<ConnectionContext>(
new ConnectionContext(dependencies));
}
@@ -98,11 +106,16 @@
wraps_current_thread_)),
trials_(dependencies->trials ? std::move(dependencies->trials)
: std::make_unique<FieldTrialBasedConfig>()),
- media_engine_(std::move(dependencies->media_engine)),
+ media_engine_(
+ dependencies->media_factory != nullptr
+ ? dependencies->media_factory->CreateMediaEngine(*dependencies)
+ : std::move(dependencies->media_engine)),
network_monitor_factory_(
std::move(dependencies->network_monitor_factory)),
default_network_manager_(std::move(dependencies->network_manager)),
- call_factory_(std::move(dependencies->call_factory)),
+ call_factory_(dependencies->media_factory != nullptr
+ ? std::move(dependencies->media_factory)
+ : std::move(dependencies->call_factory)),
default_socket_factory_(std::move(dependencies->packet_socket_factory)),
sctp_factory_(
MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),
diff --git a/pc/media_factory.h b/pc/media_factory.h
new file mode 100644
index 0000000..323744a
--- /dev/null
+++ b/pc/media_factory.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2023 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.
+ */
+
+#ifndef PC_MEDIA_FACTORY_H_
+#define PC_MEDIA_FACTORY_H_
+
+#include <memory>
+
+#include "api/call/call_factory_interface.h"
+#include "call/call.h"
+#include "call/call_config.h"
+#include "media/base/media_engine.h"
+
+namespace webrtc {
+
+// PeerConnectionFactoryDependencies is forward declared because of circular
+// dependency between MediaFactory and PeerConnectionFactoryDependencies:
+// PeerConnectionFactoryDependencies keeps an instance of MediaFactory and thus
+// needs to know how to destroy it.
+// MediaFactory mentions PeerConnectionFactoryDependencies in api, but does not
+// need its full definition.
+struct PeerConnectionFactoryDependencies;
+
+// Interface repsponsible for constructing media specific classes for
+// PeerConnectionFactory and PeerConnection.
+// TODO(bugs.webrtc.org/15574): Delete CallFactoryInterface inheritance
+// when call_factory is removed from PeerConnectionFactoryDependencies.
+class MediaFactory : public CallFactoryInterface {
+ public:
+ virtual ~MediaFactory() = default;
+
+ std::unique_ptr<Call> CreateCall(const CallConfig& config) override = 0;
+ virtual std::unique_ptr<cricket::MediaEngineInterface> CreateMediaEngine(
+ PeerConnectionFactoryDependencies& dependencies) = 0;
+};
+
+} // namespace webrtc
+
+#endif // PC_MEDIA_FACTORY_H_
diff --git a/pc/peer_connection_factory_unittest.cc b/pc/peer_connection_factory_unittest.cc
index 11e232c..91772ec 100644
--- a/pc/peer_connection_factory_unittest.cc
+++ b/pc/peer_connection_factory_unittest.cc
@@ -20,6 +20,7 @@
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/create_peerconnection_factory.h"
#include "api/data_channel_interface.h"
+#include "api/enable_media.h"
#include "api/jsep.h"
#include "api/media_stream_interface.h"
#include "api/task_queue/default_task_queue_factory.h"
@@ -35,7 +36,6 @@
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
#include "media/base/fake_frame_source.h"
-#include "media/engine/webrtc_media_engine.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "p2p/base/fake_port_allocator.h"
@@ -272,29 +272,20 @@
pcf_dependencies.worker_thread = rtc::Thread::Current();
pcf_dependencies.network_thread = rtc::Thread::Current();
pcf_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
- pcf_dependencies.call_factory = CreateCallFactory();
- pcf_dependencies.trials = std::make_unique<webrtc::FieldTrialBasedConfig>();
+ pcf_dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
- cricket::MediaEngineDependencies media_dependencies;
- media_dependencies.task_queue_factory =
- pcf_dependencies.task_queue_factory.get();
- media_dependencies.adm = rtc::scoped_refptr<webrtc::AudioDeviceModule>(
- FakeAudioCaptureModule::Create());
- media_dependencies.audio_encoder_factory =
- webrtc::CreateBuiltinAudioEncoderFactory();
- media_dependencies.audio_decoder_factory =
- webrtc::CreateBuiltinAudioDecoderFactory();
- media_dependencies.video_encoder_factory =
+ pcf_dependencies.adm = FakeAudioCaptureModule::Create();
+ pcf_dependencies.audio_encoder_factory = CreateBuiltinAudioEncoderFactory();
+ pcf_dependencies.audio_decoder_factory = CreateBuiltinAudioDecoderFactory();
+ pcf_dependencies.video_encoder_factory =
std::make_unique<VideoEncoderFactoryTemplate<
LibvpxVp8EncoderTemplateAdapter, LibvpxVp9EncoderTemplateAdapter,
OpenH264EncoderTemplateAdapter, LibaomAv1EncoderTemplateAdapter>>();
- media_dependencies.video_decoder_factory =
+ pcf_dependencies.video_decoder_factory =
std::make_unique<VideoDecoderFactoryTemplate<
LibvpxVp8DecoderTemplateAdapter, LibvpxVp9DecoderTemplateAdapter,
OpenH264DecoderTemplateAdapter, Dav1dDecoderTemplateAdapter>>(),
- media_dependencies.trials = pcf_dependencies.trials.get();
- pcf_dependencies.media_engine =
- cricket::CreateMediaEngine(std::move(media_dependencies));
+ EnableMedia(pcf_dependencies);
rtc::scoped_refptr<webrtc::ConnectionContext> context =
ConnectionContext::Create(&pcf_dependencies);