diff --git a/api/BUILD.gn b/api/BUILD.gn index 1eb38760d0..bd0f52e0d6 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -35,6 +35,20 @@ rtc_source_set("callfactory_api") { ] } +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 @@ rtc_library("libjingle_peerconnection_api") { ":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 fde8cba66e..1c12352aac 100644 --- a/api/call/call_factory_interface.h +++ b/api/call/call_factory_interface.h @@ -24,6 +24,9 @@ struct CallConfig; // 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 0000000000..4c97acef56 --- /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 +#include + +#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 CreateCall(const CallConfig& config) override { + CallFactory call_factory; + return static_cast(call_factory).CreateCall(config); + } + + std::unique_ptr CreateMediaEngine( + PeerConnectionFactoryDependencies& deps) override { + std::unique_ptr fallback_trials; + const FieldTrialsView* trials; + if (deps.trials) { + trials = deps.trials.get(); + } else { + fallback_trials = std::make_unique(); + trials = fallback_trials.get(); + } + auto audio_engine = std::make_unique( + 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( + std::move(deps.video_encoder_factory), + std::move(deps.video_decoder_factory), *trials); + return std::make_unique(std::move(fallback_trials), + std::move(audio_engine), + std::move(video_engine)); + } +}; + +} // namespace + +void EnableMedia(PeerConnectionFactoryDependencies& deps) { + deps.media_factory = std::make_unique(); +} + +} // namespace webrtc diff --git a/api/enable_media.h b/api/enable_media.h new file mode 100644 index 0000000000..8e0b66b2ea --- /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 050b61da95..dedfd355d6 100644 --- a/api/peer_connection_interface.cc +++ b/api/peer_connection_interface.cc @@ -12,6 +12,8 @@ #include +#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 9243190c10..7c81b162e3 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 @@ class Thread; 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 @@ struct RTC_EXPORT PeerConnectionFactoryDependencies final { // called without a `port_allocator`. std::unique_ptr packet_socket_factory; std::unique_ptr 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 media_engine; std::unique_ptr call_factory; std::unique_ptr event_log_factory; @@ -1447,6 +1454,23 @@ struct RTC_EXPORT PeerConnectionFactoryDependencies final { std::unique_ptr transport_controller_send_factory; std::unique_ptr metronome; + + // Media specific dependencies. Unused when `media_factory == nullptr`. + rtc::scoped_refptr adm; + rtc::scoped_refptr audio_encoder_factory; + rtc::scoped_refptr audio_decoder_factory; + rtc::scoped_refptr audio_mixer; + rtc::scoped_refptr audio_processing; + std::unique_ptr audio_frame_processor; + std::unique_ptr video_encoder_factory; + std::unique_ptr 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 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 0f6dce35b5..fa4046bca8 100644 --- a/media/engine/webrtc_media_engine.h +++ b/media/engine/webrtc_media_engine.h @@ -63,6 +63,8 @@ struct MediaEngineDependencies { // 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 CreateMediaEngine( MediaEngineDependencies dependencies); diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 7c22a26d12..7952ffd408 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -314,6 +314,15 @@ rtc_source_set("jsep_transport_controller") { ] } +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 @@ rtc_library("connection_context") { "connection_context.h", ] deps = [ + ":media_factory", "../api:callfactory_api", "../api:field_trials_view", "../api:libjingle_peerconnection_api", @@ -2405,6 +2415,7 @@ if (rtc_include_tests && !build_with_chromium) { "../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 f436e27c0a..1347008f5a 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 @@ std::unique_ptr MaybeCreateSctpFactory( // Static rtc::scoped_refptr 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( new ConnectionContext(dependencies)); } @@ -98,11 +106,16 @@ ConnectionContext::ConnectionContext( wraps_current_thread_)), trials_(dependencies->trials ? std::move(dependencies->trials) : std::make_unique()), - 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 0000000000..323744a3e2 --- /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 + +#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 CreateCall(const CallConfig& config) override = 0; + virtual std::unique_ptr 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 11e232c01f..91772ec601 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 @@ CreatePeerConnectionFactoryWithRtxDisabled() { 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(); + pcf_dependencies.trials = std::make_unique(); - cricket::MediaEngineDependencies media_dependencies; - media_dependencies.task_queue_factory = - pcf_dependencies.task_queue_factory.get(); - media_dependencies.adm = rtc::scoped_refptr( - 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>(); - media_dependencies.video_decoder_factory = + pcf_dependencies.video_decoder_factory = std::make_unique>(), - media_dependencies.trials = pcf_dependencies.trials.get(); - pcf_dependencies.media_engine = - cricket::CreateMediaEngine(std::move(media_dependencies)); + EnableMedia(pcf_dependencies); rtc::scoped_refptr context = ConnectionContext::Create(&pcf_dependencies);