diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/api/voip/BUILD.gn | 85 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/DEPS | 10 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/test/compile_all_headers.cc | 14 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/test/mock_voip_engine.h | 124 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc | 51 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_base.h | 114 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_codec.h | 56 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_dtmf.h | 74 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_engine.h | 99 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_engine_factory.cc | 37 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_engine_factory.h | 68 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_network.h | 46 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_statistics.h | 98 | ||||
-rw-r--r-- | third_party/libwebrtc/api/voip/voip_volume_control.h | 64 |
14 files changed, 940 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/voip/BUILD.gn b/third_party/libwebrtc/api/voip/BUILD.gn new file mode 100644 index 0000000000..714490a526 --- /dev/null +++ b/third_party/libwebrtc/api/voip/BUILD.gn @@ -0,0 +1,85 @@ +# Copyright(c) 2020 The WebRTC project authors.All Rights Reserved. +# +# Use of this source code is governed by a BSD - style license +# that can be found in the LICENSE file in the root of the source +# tree.An additional intellectual property rights grant can be found +# in the file PATENTS.All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("../../webrtc.gni") + +rtc_source_set("voip_api") { + visibility = [ "*" ] + sources = [ + "voip_base.h", + "voip_codec.h", + "voip_dtmf.h", + "voip_engine.h", + "voip_network.h", + "voip_statistics.h", + "voip_volume_control.h", + ] + deps = [ + "..:array_view", + "../audio_codecs:audio_codecs_api", + "../neteq:neteq_api", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("voip_engine_factory") { + visibility = [ "*" ] + sources = [ + "voip_engine_factory.cc", + "voip_engine_factory.h", + ] + deps = [ + ":voip_api", + "..:scoped_refptr", + "../../audio/voip:voip_core", + "../../modules/audio_device:audio_device_api", + "../../modules/audio_processing:api", + "../../rtc_base:logging", + "../audio_codecs:audio_codecs_api", + "../task_queue", + ] +} + +if (rtc_include_tests) { + rtc_source_set("mock_voip_engine") { + testonly = true + visibility = [ "*" ] + sources = [ "test/mock_voip_engine.h" ] + deps = [ + ":voip_api", + "..:array_view", + "../../test:test_support", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + } + + rtc_library("voip_engine_factory_unittests") { + testonly = true + sources = [ "test/voip_engine_factory_unittest.cc" ] + deps = [ + ":voip_engine_factory", + "../../modules/audio_device:mock_audio_device", + "../../modules/audio_processing:mocks", + "../../test:audio_codec_mocks", + "../../test:test_support", + "../task_queue:default_task_queue_factory", + ] + } + + rtc_library("compile_all_headers") { + testonly = true + sources = [ "test/compile_all_headers.cc" ] + deps = [ + ":mock_voip_engine", + "../../test:test_support", + ] + } +} diff --git a/third_party/libwebrtc/api/voip/DEPS b/third_party/libwebrtc/api/voip/DEPS new file mode 100644 index 0000000000..3845dffab0 --- /dev/null +++ b/third_party/libwebrtc/api/voip/DEPS @@ -0,0 +1,10 @@ +specific_include_rules = { + ".*\.h": [ + "+third_party/absl/types/optional.h", + ], + + "voip_engine_factory.h": [ + "+modules/audio_device/include/audio_device.h", + "+modules/audio_processing/include/audio_processing.h", + ], +} diff --git a/third_party/libwebrtc/api/voip/test/compile_all_headers.cc b/third_party/libwebrtc/api/voip/test/compile_all_headers.cc new file mode 100644 index 0000000000..73a0f0d1c4 --- /dev/null +++ b/third_party/libwebrtc/api/voip/test/compile_all_headers.cc @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021 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. + */ + +// This file verifies that all include files in this directory can be +// compiled without errors or other required includes. + +#include "api/voip/test/mock_voip_engine.h" diff --git a/third_party/libwebrtc/api/voip/test/mock_voip_engine.h b/third_party/libwebrtc/api/voip/test/mock_voip_engine.h new file mode 100644 index 0000000000..74b880d652 --- /dev/null +++ b/third_party/libwebrtc/api/voip/test/mock_voip_engine.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021 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_VOIP_TEST_MOCK_VOIP_ENGINE_H_ +#define API_VOIP_TEST_MOCK_VOIP_ENGINE_H_ + +#include <map> + +#include "absl/types/optional.h" +#include "api/array_view.h" +#include "api/voip/voip_base.h" +#include "api/voip/voip_codec.h" +#include "api/voip/voip_dtmf.h" +#include "api/voip/voip_engine.h" +#include "api/voip/voip_network.h" +#include "api/voip/voip_statistics.h" +#include "api/voip/voip_volume_control.h" +#include "test/gmock.h" + +namespace webrtc { + +class MockVoipBase : public VoipBase { + public: + MOCK_METHOD(ChannelId, + CreateChannel, + (Transport*, absl::optional<uint32_t>), + (override)); + MOCK_METHOD(VoipResult, ReleaseChannel, (ChannelId), (override)); + MOCK_METHOD(VoipResult, StartSend, (ChannelId), (override)); + MOCK_METHOD(VoipResult, StopSend, (ChannelId), (override)); + MOCK_METHOD(VoipResult, StartPlayout, (ChannelId), (override)); + MOCK_METHOD(VoipResult, StopPlayout, (ChannelId), (override)); +}; + +class MockVoipCodec : public VoipCodec { + public: + MOCK_METHOD(VoipResult, + SetSendCodec, + (ChannelId, int, const SdpAudioFormat&), + (override)); + MOCK_METHOD(VoipResult, + SetReceiveCodecs, + (ChannelId, (const std::map<int, SdpAudioFormat>&)), + (override)); +}; + +class MockVoipDtmf : public VoipDtmf { + public: + MOCK_METHOD(VoipResult, + RegisterTelephoneEventType, + (ChannelId, int, int), + (override)); + MOCK_METHOD(VoipResult, + SendDtmfEvent, + (ChannelId, DtmfEvent, int), + (override)); +}; + +class MockVoipNetwork : public VoipNetwork { + public: + MOCK_METHOD(VoipResult, + ReceivedRTPPacket, + (ChannelId channel_id, rtc::ArrayView<const uint8_t> rtp_packet), + (override)); + MOCK_METHOD(VoipResult, + ReceivedRTCPPacket, + (ChannelId channel_id, rtc::ArrayView<const uint8_t> rtcp_packet), + (override)); +}; + +class MockVoipStatistics : public VoipStatistics { + public: + MOCK_METHOD(VoipResult, + GetIngressStatistics, + (ChannelId, IngressStatistics&), + (override)); + MOCK_METHOD(VoipResult, + GetChannelStatistics, + (ChannelId channel_id, ChannelStatistics&), + (override)); +}; + +class MockVoipVolumeControl : public VoipVolumeControl { + public: + MOCK_METHOD(VoipResult, SetInputMuted, (ChannelId, bool), (override)); + + MOCK_METHOD(VoipResult, + GetInputVolumeInfo, + (ChannelId, VolumeInfo&), + (override)); + MOCK_METHOD(VoipResult, + GetOutputVolumeInfo, + (ChannelId, VolumeInfo&), + (override)); +}; + +class MockVoipEngine : public VoipEngine { + public: + VoipBase& Base() override { return base_; } + VoipNetwork& Network() override { return network_; } + VoipCodec& Codec() override { return codec_; } + VoipDtmf& Dtmf() override { return dtmf_; } + VoipStatistics& Statistics() override { return statistics_; } + VoipVolumeControl& VolumeControl() override { return volume_; } + + // Direct access to underlying members are required for testing. + MockVoipBase base_; + MockVoipNetwork network_; + MockVoipCodec codec_; + MockVoipDtmf dtmf_; + MockVoipStatistics statistics_; + MockVoipVolumeControl volume_; +}; + +} // namespace webrtc + +#endif // API_VOIP_TEST_MOCK_VOIP_ENGINE_H_ diff --git a/third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc b/third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc new file mode 100644 index 0000000000..f967a0ba8f --- /dev/null +++ b/third_party/libwebrtc/api/voip/test/voip_engine_factory_unittest.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <utility> + +#include "api/task_queue/default_task_queue_factory.h" +#include "api/voip/voip_engine_factory.h" +#include "modules/audio_device/include/mock_audio_device.h" +#include "modules/audio_processing/include/mock_audio_processing.h" +#include "test/gtest.h" +#include "test/mock_audio_decoder_factory.h" +#include "test/mock_audio_encoder_factory.h" + +namespace webrtc { +namespace { + +// Create voip engine with mock modules as normal use case. +TEST(VoipEngineFactoryTest, CreateEngineWithMockModules) { + VoipEngineConfig config; + config.encoder_factory = rtc::make_ref_counted<MockAudioEncoderFactory>(); + config.decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>(); + config.task_queue_factory = CreateDefaultTaskQueueFactory(); + config.audio_processing = + rtc::make_ref_counted<testing::NiceMock<test::MockAudioProcessing>>(); + config.audio_device_module = test::MockAudioDeviceModule::CreateNice(); + + auto voip_engine = CreateVoipEngine(std::move(config)); + EXPECT_NE(voip_engine, nullptr); +} + +// Create voip engine without setting audio processing as optional component. +TEST(VoipEngineFactoryTest, UseNoAudioProcessing) { + VoipEngineConfig config; + config.encoder_factory = rtc::make_ref_counted<MockAudioEncoderFactory>(); + config.decoder_factory = rtc::make_ref_counted<MockAudioDecoderFactory>(); + config.task_queue_factory = CreateDefaultTaskQueueFactory(); + config.audio_device_module = test::MockAudioDeviceModule::CreateNice(); + + auto voip_engine = CreateVoipEngine(std::move(config)); + EXPECT_NE(voip_engine, nullptr); +} + +} // namespace +} // namespace webrtc diff --git a/third_party/libwebrtc/api/voip/voip_base.h b/third_party/libwebrtc/api/voip/voip_base.h new file mode 100644 index 0000000000..8df7bd0571 --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_base.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_BASE_H_ +#define API_VOIP_VOIP_BASE_H_ + +#include "absl/base/attributes.h" +#include "absl/types/optional.h" + +namespace webrtc { + +class Transport; + +// VoipBase interface +// +// VoipBase provides a management interface on a media session using a +// concept called 'channel'. A channel represents an interface handle +// for application to request various media session operations. This +// notion of channel is used throughout other interfaces as well. +// +// Underneath the interface, a channel id is mapped into an audio session +// object that is capable of sending and receiving a single RTP stream with +// another media endpoint. It's possible to create and use multiple active +// channels simultaneously which would mean that particular application +// session has RTP streams with multiple remote endpoints. +// +// A typical example for the usage context is outlined in VoipEngine +// header file. + +enum class ChannelId : int {}; + +enum class ABSL_MUST_USE_RESULT VoipResult { + // kOk indicates the function was successfully invoked with no error. + kOk, + // kInvalidArgument indicates the caller specified an invalid argument, such + // as an invalid ChannelId. + kInvalidArgument, + // kFailedPrecondition indicates that the operation was failed due to not + // satisfying prerequisite such as not setting codec type before sending. + kFailedPrecondition, + // kInternal is used to indicate various internal failures that are not the + // caller's fault. Further detail is commented on each function that uses this + // return value. + kInternal, +}; + +class VoipBase { + public: + // Creates a channel. + // Each channel handle maps into one audio media session where each has + // its own separate module for send/receive rtp packet with one peer. + // Caller must set `transport`, webrtc::Transport callback pointer to + // receive rtp/rtcp packets from corresponding media session in VoIP engine. + // VoipEngine framework expects applications to handle network I/O directly + // and injection for incoming RTP from remote endpoint is handled via + // VoipNetwork interface. `local_ssrc` is optional and when local_ssrc is not + // set, some random value will be used by voip engine. + // Returns a ChannelId created for caller to handle subsequent Channel + // operations. + virtual ChannelId CreateChannel(Transport* transport, + absl::optional<uint32_t> local_ssrc) = 0; + + // Releases `channel_id` that no longer has any use. + // Returns following VoipResult; + // kOk - `channel_id` is released. + // kInvalidArgument - `channel_id` is invalid. + // kInternal - Fails to stop audio output device. + virtual VoipResult ReleaseChannel(ChannelId channel_id) = 0; + + // Starts sending on `channel_id`. This starts microphone if not started yet. + // Returns following VoipResult; + // kOk - Channel successfully started to send. + // kInvalidArgument - `channel_id` is invalid. + // kFailedPrecondition - Missing prerequisite on VoipCodec::SetSendCodec. + // kInternal - initialization has failed on selected microphone. + virtual VoipResult StartSend(ChannelId channel_id) = 0; + + // Stops sending on `channel_id`. If this is the last active channel, it will + // stop microphone input from underlying audio platform layer. + // Returns following VoipResult; + // kOk - Channel successfully stopped to send. + // kInvalidArgument - `channel_id` is invalid. + // kInternal - Failed to stop the active microphone device. + virtual VoipResult StopSend(ChannelId channel_id) = 0; + + // Starts playing on speaker device for `channel_id`. + // This will start underlying platform speaker device if not started. + // Returns following VoipResult; + // kOk - Channel successfully started to play out. + // kInvalidArgument - `channel_id` is invalid. + // kFailedPrecondition - Missing prerequisite on VoipCodec::SetReceiveCodecs. + // kInternal - Failed to initializate the selected speaker device. + virtual VoipResult StartPlayout(ChannelId channel_id) = 0; + + // Stops playing on speaker device for `channel_id`. + // Returns following VoipResult; + // kOk - Channel successfully stopped t play out. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult StopPlayout(ChannelId channel_id) = 0; + + protected: + virtual ~VoipBase() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_BASE_H_ diff --git a/third_party/libwebrtc/api/voip/voip_codec.h b/third_party/libwebrtc/api/voip/voip_codec.h new file mode 100644 index 0000000000..46cddfad6c --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_codec.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_CODEC_H_ +#define API_VOIP_VOIP_CODEC_H_ + +#include <map> + +#include "api/audio_codecs/audio_format.h" +#include "api/voip/voip_base.h" + +namespace webrtc { + +// VoipCodec interface currently provides any codec related interface +// such as setting encoder and decoder types that are negotiated with +// remote endpoint. Typically after SDP offer and answer exchange, +// the local endpoint understands what are the codec payload types that +// are used with negotiated codecs. This interface is subject to expand +// as needed in future. +// +// This interface requires a channel id created via VoipBase interface. +class VoipCodec { + public: + // Set encoder type here along with its payload type to use. + // Returns following VoipResult; + // kOk - sending codec is set as provided. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult SetSendCodec(ChannelId channel_id, + int payload_type, + const SdpAudioFormat& encoder_spec) = 0; + + // Set decoder payload type here. In typical offer and answer model, + // this should be called after payload type has been agreed in media + // session. Note that payload type can differ with same codec in each + // direction. + // Returns following VoipResult; + // kOk - receiving codecs are set as provided. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult SetReceiveCodecs( + ChannelId channel_id, + const std::map<int, SdpAudioFormat>& decoder_specs) = 0; + + protected: + virtual ~VoipCodec() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_CODEC_H_ diff --git a/third_party/libwebrtc/api/voip/voip_dtmf.h b/third_party/libwebrtc/api/voip/voip_dtmf.h new file mode 100644 index 0000000000..ef7ea28c94 --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_dtmf.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_DTMF_H_ +#define API_VOIP_VOIP_DTMF_H_ + +#include "api/voip/voip_base.h" + +namespace webrtc { + +// DTMF events and their event codes as defined in +// https://tools.ietf.org/html/rfc4733#section-7 +enum class DtmfEvent : uint8_t { + kDigitZero = 0, + kDigitOne, + kDigitTwo, + kDigitThree, + kDigitFour, + kDigitFive, + kDigitSix, + kDigitSeven, + kDigitEight, + kDigitNine, + kAsterisk, + kHash, + kLetterA, + kLetterB, + kLetterC, + kLetterD +}; + +// VoipDtmf interface provides DTMF related interfaces such +// as sending DTMF events to the remote endpoint. +class VoipDtmf { + public: + // Register the payload type and sample rate for DTMF (RFC 4733) payload. + // Must be called exactly once prior to calling SendDtmfEvent after payload + // type has been negotiated with remote. + // Returns following VoipResult; + // kOk - telephone event type is registered as provided. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult RegisterTelephoneEventType(ChannelId channel_id, + int rtp_payload_type, + int sample_rate_hz) = 0; + + // Send DTMF named event as specified by + // https://tools.ietf.org/html/rfc4733#section-3.2 + // `duration_ms` specifies the duration of DTMF packets that will be emitted + // in place of real RTP packets instead. + // Must be called after RegisterTelephoneEventType and VoipBase::StartSend + // have been called. + // Returns following VoipResult; + // kOk - requested DTMF event is successfully scheduled. + // kInvalidArgument - `channel_id` is invalid. + // kFailedPrecondition - Missing prerequisite on RegisterTelephoneEventType + // or sending state. + virtual VoipResult SendDtmfEvent(ChannelId channel_id, + DtmfEvent dtmf_event, + int duration_ms) = 0; + + protected: + virtual ~VoipDtmf() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_DTMF_H_ diff --git a/third_party/libwebrtc/api/voip/voip_engine.h b/third_party/libwebrtc/api/voip/voip_engine.h new file mode 100644 index 0000000000..d223f6ad6c --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_engine.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_ENGINE_H_ +#define API_VOIP_VOIP_ENGINE_H_ + +namespace webrtc { + +class VoipBase; +class VoipCodec; +class VoipNetwork; +class VoipDtmf; +class VoipStatistics; +class VoipVolumeControl; + +// VoipEngine is the main interface serving as the entry point for all VoIP +// APIs. A single instance of VoipEngine should suffice the most of the need for +// typical VoIP applications as it handles multiple media sessions including a +// specialized session type like ad-hoc conference. Below example code +// describes the typical sequence of API usage. Each API header contains more +// description on what the methods are used for. +// +// // Caller is responsible of setting desired audio components. +// VoipEngineConfig config; +// config.encoder_factory = CreateBuiltinAudioEncoderFactory(); +// config.decoder_factory = CreateBuiltinAudioDecoderFactory(); +// config.task_queue_factory = CreateDefaultTaskQueueFactory(); +// config.audio_device = +// AudioDeviceModule::Create(AudioDeviceModule::kPlatformDefaultAudio, +// config.task_queue_factory.get()); +// config.audio_processing = AudioProcessingBuilder().Create(); +// +// auto voip_engine = CreateVoipEngine(std::move(config)); +// +// auto& voip_base = voip_engine->Base(); +// auto& voip_codec = voip_engine->Codec(); +// auto& voip_network = voip_engine->Network(); +// +// ChannelId channel = voip_base.CreateChannel(&app_transport_); +// +// // After SDP offer/answer, set payload type and codecs that have been +// // decided through SDP negotiation. +// // VoipResult handling omitted here. +// voip_codec.SetSendCodec(channel, ...); +// voip_codec.SetReceiveCodecs(channel, ...); +// +// // Start sending and playing RTP on voip channel. +// // VoipResult handling omitted here. +// voip_base.StartSend(channel); +// voip_base.StartPlayout(channel); +// +// // Inject received RTP/RTCP through VoipNetwork interface. +// // VoipResult handling omitted here. +// voip_network.ReceivedRTPPacket(channel, ...); +// voip_network.ReceivedRTCPPacket(channel, ...); +// +// // Stop and release voip channel. +// // VoipResult handling omitted here. +// voip_base.StopSend(channel); +// voip_base.StopPlayout(channel); +// voip_base.ReleaseChannel(channel); +// +class VoipEngine { + public: + virtual ~VoipEngine() = default; + + // VoipBase is the audio session management interface that + // creates/releases/starts/stops an one-to-one audio media session. + virtual VoipBase& Base() = 0; + + // VoipNetwork provides injection APIs that would enable application + // to send and receive RTP/RTCP packets. There is no default network module + // that provides RTP transmission and reception. + virtual VoipNetwork& Network() = 0; + + // VoipCodec provides codec configuration APIs for encoder and decoders. + virtual VoipCodec& Codec() = 0; + + // VoipDtmf provides DTMF event APIs to register and send DTMF events. + virtual VoipDtmf& Dtmf() = 0; + + // VoipStatistics provides performance metrics around audio decoding module + // and jitter buffer (NetEq). + virtual VoipStatistics& Statistics() = 0; + + // VoipVolumeControl provides various input/output volume control. + virtual VoipVolumeControl& VolumeControl() = 0; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_ENGINE_H_ diff --git a/third_party/libwebrtc/api/voip/voip_engine_factory.cc b/third_party/libwebrtc/api/voip/voip_engine_factory.cc new file mode 100644 index 0000000000..8da53cef74 --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_engine_factory.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/voip/voip_engine_factory.h" + +#include <utility> + +#include "audio/voip/voip_core.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +std::unique_ptr<VoipEngine> CreateVoipEngine(VoipEngineConfig config) { + RTC_CHECK(config.encoder_factory); + RTC_CHECK(config.decoder_factory); + RTC_CHECK(config.task_queue_factory); + RTC_CHECK(config.audio_device_module); + + if (!config.audio_processing) { + RTC_DLOG(LS_INFO) << "No audio processing functionality provided."; + } + + return std::make_unique<VoipCore>(std::move(config.encoder_factory), + std::move(config.decoder_factory), + std::move(config.task_queue_factory), + std::move(config.audio_device_module), + std::move(config.audio_processing)); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/api/voip/voip_engine_factory.h b/third_party/libwebrtc/api/voip/voip_engine_factory.h new file mode 100644 index 0000000000..62fe8011a6 --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_engine_factory.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_ENGINE_FACTORY_H_ +#define API_VOIP_VOIP_ENGINE_FACTORY_H_ + +#include <memory> + +#include "api/audio_codecs/audio_decoder_factory.h" +#include "api/audio_codecs/audio_encoder_factory.h" +#include "api/scoped_refptr.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/voip/voip_engine.h" +#include "modules/audio_device/include/audio_device.h" +#include "modules/audio_processing/include/audio_processing.h" + +namespace webrtc { + +// VoipEngineConfig is a struct that defines parameters to instantiate a +// VoipEngine instance through CreateVoipEngine factory method. Each member is +// marked with comments as either mandatory or optional and default +// implementations that applications can use. +struct VoipEngineConfig { + // Mandatory (e.g. api/audio_codec/builtin_audio_encoder_factory). + // AudioEncoderFactory provides a set of audio codecs for VoipEngine to encode + // the audio input sample. Application can choose to limit the set to reduce + // application footprint. + rtc::scoped_refptr<AudioEncoderFactory> encoder_factory; + + // Mandatory (e.g. api/audio_codec/builtin_audio_decoder_factory). + // AudioDecoderFactory provides a set of audio codecs for VoipEngine to decode + // the received RTP packets from remote media endpoint. Application can choose + // to limit the set to reduce application footprint. + rtc::scoped_refptr<AudioDecoderFactory> decoder_factory; + + // Mandatory (e.g. api/task_queue/default_task_queue_factory). + // TaskQeueuFactory provided for VoipEngine to work asynchronously on its + // encoding flow. + std::unique_ptr<TaskQueueFactory> task_queue_factory; + + // Mandatory (e.g. modules/audio_device/include). + // AudioDeviceModule that periocally provides audio input samples from + // recording device (e.g. microphone) and requests audio output samples to + // play through its output device (e.g. speaker). + rtc::scoped_refptr<AudioDeviceModule> audio_device_module; + + // Optional (e.g. modules/audio_processing/include). + // AudioProcessing provides audio procesing functionalities (e.g. acoustic + // echo cancellation, noise suppression, gain control, etc) on audio input + // samples for VoipEngine. When optionally not set, VoipEngine will not have + // such functionalities to perform on audio input samples received from + // AudioDeviceModule. + rtc::scoped_refptr<AudioProcessing> audio_processing; +}; + +// Creates a VoipEngine instance with provided VoipEngineConfig. +std::unique_ptr<VoipEngine> CreateVoipEngine(VoipEngineConfig config); + +} // namespace webrtc + +#endif // API_VOIP_VOIP_ENGINE_FACTORY_H_ diff --git a/third_party/libwebrtc/api/voip/voip_network.h b/third_party/libwebrtc/api/voip/voip_network.h new file mode 100644 index 0000000000..0ea16b68de --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_network.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_NETWORK_H_ +#define API_VOIP_VOIP_NETWORK_H_ + +#include "api/array_view.h" +#include "api/voip/voip_base.h" + +namespace webrtc { + +// VoipNetwork interface provides any network related interfaces such as +// processing received RTP/RTCP packet from remote endpoint. This interface +// requires a ChannelId created via VoipBase interface. +class VoipNetwork { + public: + // The data received from the network including RTP header is passed here. + // Returns following VoipResult; + // kOk - received RTP packet is processed. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult ReceivedRTPPacket( + ChannelId channel_id, + rtc::ArrayView<const uint8_t> rtp_packet) = 0; + + // The data received from the network including RTCP header is passed here. + // Returns following VoipResult; + // kOk - received RTCP packet is processed. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult ReceivedRTCPPacket( + ChannelId channel_id, + rtc::ArrayView<const uint8_t> rtcp_packet) = 0; + + protected: + virtual ~VoipNetwork() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_NETWORK_H_ diff --git a/third_party/libwebrtc/api/voip/voip_statistics.h b/third_party/libwebrtc/api/voip/voip_statistics.h new file mode 100644 index 0000000000..2d1ab8d5e8 --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_statistics.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_STATISTICS_H_ +#define API_VOIP_VOIP_STATISTICS_H_ + +#include "api/neteq/neteq.h" +#include "api/voip/voip_base.h" + +namespace webrtc { + +struct IngressStatistics { + // Stats included from api/neteq/neteq.h. + NetEqLifetimeStatistics neteq_stats; + + // Represents the total duration in seconds of all samples that have been + // received. + // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalsamplesduration + double total_duration = 0.0; +}; + +// Remote statistics obtained via remote RTCP SR/RR report received. +struct RemoteRtcpStatistics { + // Jitter as defined in RFC 3550 [6.4.1] expressed in seconds. + double jitter = 0.0; + + // Cumulative packets lost as defined in RFC 3550 [6.4.1] + int64_t packets_lost = 0; + + // Fraction lost as defined in RFC 3550 [6.4.1] expressed as a floating + // pointer number. + double fraction_lost = 0.0; + + // https://w3c.github.io/webrtc-stats/#dom-rtcremoteinboundrtpstreamstats-roundtriptime + absl::optional<double> round_trip_time; + + // Last time (not RTP timestamp) when RTCP report received in milliseconds. + int64_t last_report_received_timestamp_ms; +}; + +struct ChannelStatistics { + // https://w3c.github.io/webrtc-stats/#dom-rtcsentrtpstreamstats-packetssent + uint64_t packets_sent = 0; + + // https://w3c.github.io/webrtc-stats/#dom-rtcsentrtpstreamstats-bytessent + uint64_t bytes_sent = 0; + + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceived + uint64_t packets_received = 0; + + // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-bytesreceived + uint64_t bytes_received = 0; + + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-jitter + double jitter = 0.0; + + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetslost + int64_t packets_lost = 0; + + // SSRC from remote media endpoint as indicated either by RTP header in RFC + // 3550 [5.1] or RTCP SSRC of sender in RFC 3550 [6.4.1]. + absl::optional<uint32_t> remote_ssrc; + + absl::optional<RemoteRtcpStatistics> remote_rtcp; +}; + +// VoipStatistics interface provides the interfaces for querying metrics around +// the jitter buffer (NetEq) performance. +class VoipStatistics { + public: + // Gets the audio ingress statistics by `ingress_stats` reference. + // Returns following VoipResult; + // kOk - successfully set provided IngressStatistics reference. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult GetIngressStatistics(ChannelId channel_id, + IngressStatistics& ingress_stats) = 0; + + // Gets the channel statistics by `channel_stats` reference. + // Returns following VoipResult; + // kOk - successfully set provided ChannelStatistics reference. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult GetChannelStatistics(ChannelId channel_id, + ChannelStatistics& channel_stats) = 0; + + protected: + virtual ~VoipStatistics() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_STATISTICS_H_ diff --git a/third_party/libwebrtc/api/voip/voip_volume_control.h b/third_party/libwebrtc/api/voip/voip_volume_control.h new file mode 100644 index 0000000000..aab14180df --- /dev/null +++ b/third_party/libwebrtc/api/voip/voip_volume_control.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VOIP_VOIP_VOLUME_CONTROL_H_ +#define API_VOIP_VOIP_VOLUME_CONTROL_H_ + +#include "api/voip/voip_base.h" + +namespace webrtc { + +struct VolumeInfo { + // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-audiolevel + double audio_level = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-totalaudioenergy + double total_energy = 0.0; + // https://w3c.github.io/webrtc-stats/#dom-rtcaudiosourcestats-totalsamplesduration + double total_duration = 0.0; +}; + +// VoipVolumeControl interface. +// +// This sub-API supports functions related to the input (microphone) and output +// (speaker) device. +// +// Caller must ensure that ChannelId is valid otherwise it will result in no-op +// with error logging. +class VoipVolumeControl { + public: + // Mute/unmutes the microphone input sample before encoding process. Note that + // mute doesn't affect audio input level and energy values as input sample is + // silenced after the measurement. + // Returns following VoipResult; + // kOk - input source muted or unmuted as provided by `enable`. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult SetInputMuted(ChannelId channel_id, bool enable) = 0; + + // Gets the microphone volume info via `volume_info` reference. + // Returns following VoipResult; + // kOk - successfully set provided input volume info. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult GetInputVolumeInfo(ChannelId channel_id, + VolumeInfo& volume_info) = 0; + + // Gets the speaker volume info via `volume_info` reference. + // Returns following VoipResult; + // kOk - successfully set provided output volume info. + // kInvalidArgument - `channel_id` is invalid. + virtual VoipResult GetOutputVolumeInfo(ChannelId channel_id, + VolumeInfo& volume_info) = 0; + + protected: + virtual ~VoipVolumeControl() = default; +}; + +} // namespace webrtc + +#endif // API_VOIP_VOIP_VOLUME_CONTROL_H_ |