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}
This commit is contained in:
Danil Chapovalov 2023-10-31 13:51:16 +01:00 committed by WebRTC LUCI CQ
parent d6bac61b64
commit 082cb56ee7
11 changed files with 227 additions and 19 deletions

View File

@ -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) { if (!build_with_chromium) {
rtc_library("create_peerconnection_factory") { rtc_library("create_peerconnection_factory") {
visibility = [ "*" ] visibility = [ "*" ]
@ -305,6 +319,7 @@ rtc_library("libjingle_peerconnection_api") {
":turn_customizer", ":turn_customizer",
"../call:rtp_interfaces", "../call:rtp_interfaces",
"../p2p:rtc_p2p", "../p2p:rtc_p2p",
"../pc:media_factory",
"../rtc_base:copy_on_write_buffer", "../rtc_base:copy_on_write_buffer",
"../rtc_base:logging", "../rtc_base:logging",
"../rtc_base:network", "../rtc_base:network",

View File

@ -24,6 +24,9 @@ struct CallConfig;
// This interface exists to allow webrtc to be optionally built without media // This interface exists to allow webrtc to be optionally built without media
// support (i.e., if only being used for data channels). PeerConnectionFactory // support (i.e., if only being used for data channels). PeerConnectionFactory
// is constructed with a CallFactoryInterface, which may or may not be null. // 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 { class CallFactoryInterface {
public: public:
virtual ~CallFactoryInterface() = default; virtual ~CallFactoryInterface() = default;

75
api/enable_media.cc Normal file
View File

@ -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

26
api/enable_media.h Normal file
View File

@ -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_

View File

@ -12,6 +12,8 @@
#include <utility> #include <utility>
#include "pc/media_factory.h"
namespace webrtc { namespace webrtc {
PeerConnectionInterface::IceServer::IceServer() = default; PeerConnectionInterface::IceServer::IceServer() = default;

View File

@ -120,6 +120,8 @@
#include "api/transport/sctp_transport_factory_interface.h" #include "api/transport/sctp_transport_factory_interface.h"
#include "api/turn_customizer.h" #include "api/turn_customizer.h"
#include "api/video/video_bitrate_allocator_factory.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 "call/rtp_transport_controller_send_factory_interface.h"
#include "media/base/media_config.h" #include "media/base/media_config.h"
#include "media/base/media_engine.h" #include "media/base/media_engine.h"
@ -145,6 +147,9 @@ class Thread;
namespace webrtc { namespace webrtc {
// MediaFactory class definition is not part of the api.
class MediaFactory;
// MediaStream container interface. // MediaStream container interface.
class StreamCollectionInterface : public rtc::RefCountInterface { class StreamCollectionInterface : public rtc::RefCountInterface {
public: public:
@ -1427,6 +1432,8 @@ struct RTC_EXPORT PeerConnectionFactoryDependencies final {
// called without a `port_allocator`. // called without a `port_allocator`.
std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory; std::unique_ptr<rtc::PacketSocketFactory> packet_socket_factory;
std::unique_ptr<TaskQueueFactory> task_queue_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<cricket::MediaEngineInterface> media_engine;
std::unique_ptr<CallFactoryInterface> call_factory; std::unique_ptr<CallFactoryInterface> call_factory;
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory; std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory;
@ -1447,6 +1454,23 @@ struct RTC_EXPORT PeerConnectionFactoryDependencies final {
std::unique_ptr<RtpTransportControllerSendFactoryInterface> std::unique_ptr<RtpTransportControllerSendFactoryInterface>
transport_controller_send_factory; transport_controller_send_factory;
std::unique_ptr<Metronome> metronome; 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 // PeerConnectionFactoryInterface is the factory interface used for creating

View File

@ -63,6 +63,8 @@ struct MediaEngineDependencies {
// CreateMediaEngine may be called on any thread, though the engine is // CreateMediaEngine may be called on any thread, though the engine is
// only expected to be used on one thread, internally called the "worker // only expected to be used on one thread, internally called the "worker
// thread". This is the thread Init must be called on. // 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( RTC_EXPORT std::unique_ptr<MediaEngineInterface> CreateMediaEngine(
MediaEngineDependencies dependencies); MediaEngineDependencies dependencies);

View File

@ -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") { rtc_source_set("media_session") {
visibility = [ "*" ] # Used by Chrome visibility = [ "*" ] # Used by Chrome
sources = [ sources = [
@ -919,6 +928,7 @@ rtc_library("connection_context") {
"connection_context.h", "connection_context.h",
] ]
deps = [ deps = [
":media_factory",
"../api:callfactory_api", "../api:callfactory_api",
"../api:field_trials_view", "../api:field_trials_view",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
@ -2405,6 +2415,7 @@ if (rtc_include_tests && !build_with_chromium) {
"../api:create_peerconnection_factory", "../api:create_peerconnection_factory",
"../api:dtls_transport_interface", "../api:dtls_transport_interface",
"../api:dtmf_sender_interface", "../api:dtmf_sender_interface",
"../api:enable_media",
"../api:fake_frame_decryptor", "../api:fake_frame_decryptor",
"../api:fake_frame_encryptor", "../api:fake_frame_encryptor",
"../api:field_trials_view", "../api:field_trials_view",

View File

@ -17,6 +17,7 @@
#include "api/transport/field_trial_based_config.h" #include "api/transport/field_trial_based_config.h"
#include "media/base/media_engine.h" #include "media/base/media_engine.h"
#include "media/sctp/sctp_transport_factory.h" #include "media/sctp/sctp_transport_factory.h"
#include "pc/media_factory.h"
#include "rtc_base/helpers.h" #include "rtc_base/helpers.h"
#include "rtc_base/internal/default_socket_server.h" #include "rtc_base/internal/default_socket_server.h"
#include "rtc_base/socket_server.h" #include "rtc_base/socket_server.h"
@ -78,6 +79,13 @@ std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory(
// Static // Static
rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create( rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
PeerConnectionFactoryDependencies* dependencies) { 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>( return rtc::scoped_refptr<ConnectionContext>(
new ConnectionContext(dependencies)); new ConnectionContext(dependencies));
} }
@ -98,11 +106,16 @@ ConnectionContext::ConnectionContext(
wraps_current_thread_)), wraps_current_thread_)),
trials_(dependencies->trials ? std::move(dependencies->trials) trials_(dependencies->trials ? std::move(dependencies->trials)
: std::make_unique<FieldTrialBasedConfig>()), : 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_( network_monitor_factory_(
std::move(dependencies->network_monitor_factory)), std::move(dependencies->network_monitor_factory)),
default_network_manager_(std::move(dependencies->network_manager)), 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)), default_socket_factory_(std::move(dependencies->packet_socket_factory)),
sctp_factory_( sctp_factory_(
MaybeCreateSctpFactory(std::move(dependencies->sctp_factory), MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),

46
pc/media_factory.h Normal file
View File

@ -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_

View File

@ -20,6 +20,7 @@
#include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/create_peerconnection_factory.h" #include "api/create_peerconnection_factory.h"
#include "api/data_channel_interface.h" #include "api/data_channel_interface.h"
#include "api/enable_media.h"
#include "api/jsep.h" #include "api/jsep.h"
#include "api/media_stream_interface.h" #include "api/media_stream_interface.h"
#include "api/task_queue/default_task_queue_factory.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_libvpx_vp9_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h" #include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
#include "media/base/fake_frame_source.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_device/include/audio_device.h"
#include "modules/audio_processing/include/audio_processing.h" #include "modules/audio_processing/include/audio_processing.h"
#include "p2p/base/fake_port_allocator.h" #include "p2p/base/fake_port_allocator.h"
@ -272,29 +272,20 @@ CreatePeerConnectionFactoryWithRtxDisabled() {
pcf_dependencies.worker_thread = rtc::Thread::Current(); pcf_dependencies.worker_thread = rtc::Thread::Current();
pcf_dependencies.network_thread = rtc::Thread::Current(); pcf_dependencies.network_thread = rtc::Thread::Current();
pcf_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory(); pcf_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
pcf_dependencies.call_factory = CreateCallFactory(); pcf_dependencies.trials = std::make_unique<FieldTrialBasedConfig>();
pcf_dependencies.trials = std::make_unique<webrtc::FieldTrialBasedConfig>();
cricket::MediaEngineDependencies media_dependencies; pcf_dependencies.adm = FakeAudioCaptureModule::Create();
media_dependencies.task_queue_factory = pcf_dependencies.audio_encoder_factory = CreateBuiltinAudioEncoderFactory();
pcf_dependencies.task_queue_factory.get(); pcf_dependencies.audio_decoder_factory = CreateBuiltinAudioDecoderFactory();
media_dependencies.adm = rtc::scoped_refptr<webrtc::AudioDeviceModule>( pcf_dependencies.video_encoder_factory =
FakeAudioCaptureModule::Create());
media_dependencies.audio_encoder_factory =
webrtc::CreateBuiltinAudioEncoderFactory();
media_dependencies.audio_decoder_factory =
webrtc::CreateBuiltinAudioDecoderFactory();
media_dependencies.video_encoder_factory =
std::make_unique<VideoEncoderFactoryTemplate< std::make_unique<VideoEncoderFactoryTemplate<
LibvpxVp8EncoderTemplateAdapter, LibvpxVp9EncoderTemplateAdapter, LibvpxVp8EncoderTemplateAdapter, LibvpxVp9EncoderTemplateAdapter,
OpenH264EncoderTemplateAdapter, LibaomAv1EncoderTemplateAdapter>>(); OpenH264EncoderTemplateAdapter, LibaomAv1EncoderTemplateAdapter>>();
media_dependencies.video_decoder_factory = pcf_dependencies.video_decoder_factory =
std::make_unique<VideoDecoderFactoryTemplate< std::make_unique<VideoDecoderFactoryTemplate<
LibvpxVp8DecoderTemplateAdapter, LibvpxVp9DecoderTemplateAdapter, LibvpxVp8DecoderTemplateAdapter, LibvpxVp9DecoderTemplateAdapter,
OpenH264DecoderTemplateAdapter, Dav1dDecoderTemplateAdapter>>(), OpenH264DecoderTemplateAdapter, Dav1dDecoderTemplateAdapter>>(),
media_dependencies.trials = pcf_dependencies.trials.get(); EnableMedia(pcf_dependencies);
pcf_dependencies.media_engine =
cricket::CreateMediaEngine(std::move(media_dependencies));
rtc::scoped_refptr<webrtc::ConnectionContext> context = rtc::scoped_refptr<webrtc::ConnectionContext> context =
ConnectionContext::Create(&pcf_dependencies); ConnectionContext::Create(&pcf_dependencies);