Merge commit 'upstream-main' into master

Bug: 261600888
Test: none, build files to be updated in follow up cl
Change-Id: Ib520938290c6bbdee4a9f73b6419b6c947a96ec4
This commit is contained in:
Jorge E. Moreira
2022-12-06 16:34:41 -08:00
5393 changed files with 541103 additions and 211666 deletions

File diff suppressed because it is too large Load Diff

109
api/DEPS
View File

@ -11,10 +11,13 @@ include_rules = [
"-common_video",
"-data",
"-examples",
"-experiments",
"-g3doc",
"-ios",
"-infra",
"-logging",
"-media",
"-net",
"-modules",
"-out",
"-p2p",
@ -40,12 +43,16 @@ include_rules = [
specific_include_rules = {
# Some internal headers are allowed even in API headers:
"call_factory_interface\.h": [
"+call/rtp_transport_controller_send_factory_interface.h",
],
".*\.h": [
"+rtc_base/checks.h",
"+rtc_base/system/rtc_export.h",
"+rtc_base/system/rtc_export_template.h",
"+rtc_base/units/unit_base.h",
"+rtc_base/deprecation.h",
],
"array_view\.h": [
@ -63,6 +70,10 @@ specific_include_rules = {
"+rtc_base/async_resolver_interface.h",
],
"async_dns_resolver\.h": [
"+rtc_base/socket_address.h",
],
"candidate\.h": [
"+rtc_base/network_constants.h",
"+rtc_base/socket_address.h",
@ -102,14 +113,6 @@ specific_include_rules = {
"+rtc_base/ref_count.h",
],
"jsep_ice_candidate\.h": [
"+rtc_base/constructor_magic.h",
],
"jsep_session_description\.h": [
"+rtc_base/constructor_magic.h",
],
"media_stream_interface\.h": [
"+modules/audio_processing/include/audio_processing_statistics.h",
"+rtc_base/ref_count.h",
@ -120,31 +123,31 @@ specific_include_rules = {
"+rtc_base/async_packet_socket.h",
],
"peer_connection_factory_proxy\.h": [
"+rtc_base/bind.h",
],
"peer_connection_interface\.h": [
"+call/rtp_transport_controller_send_factory_interface.h",
"+media/base/media_config.h",
"+media/base/media_engine.h",
"+p2p/base/port.h",
"+p2p/base/port_allocator.h",
"+rtc_base/network.h",
"+rtc_base/network_constants.h",
"+rtc_base/network_monitor_factory.h",
"+rtc_base/ref_count.h",
"+rtc_base/rtc_certificate.h",
"+rtc_base/rtc_certificate_generator.h",
"+rtc_base/socket_address.h",
"+rtc_base/ssl_certificate.h",
"+rtc_base/ssl_stream_adapter.h",
"+rtc_base/thread.h",
],
"proxy\.h": [
"+rtc_base/event.h",
"+rtc_base/message_handler.h", # Inherits from it.
"+rtc_base/ref_counted_object.h",
"+rtc_base/thread.h",
],
"ref_counted_base\.h": [
"+rtc_base/constructor_magic.h",
"+rtc_base/ref_count.h",
"+rtc_base/ref_counter.h",
],
@ -172,14 +175,15 @@ specific_include_rules = {
"+rtc_base/ref_count.h",
],
"set_local_description_observer_interface\.h": [
"+rtc_base/ref_count.h",
],
"set_remote_description_observer_interface\.h": [
"+rtc_base/ref_count.h",
],
"stats_types\.h": [
"+rtc_base/constructor_magic.h",
"legacy_stats_types\.h": [
"+rtc_base/ref_count.h",
"+rtc_base/string_encode.h",
"+rtc_base/thread_checker.h",
],
@ -187,27 +191,18 @@ specific_include_rules = {
"+rtc_base/ref_count.h",
],
"audio_frame\.h": [
"+rtc_base/constructor_magic.h",
],
"audio_mixer\.h": [
"+rtc_base/ref_count.h",
],
"audio_decoder\.h": [
"+rtc_base/buffer.h",
"+rtc_base/constructor_magic.h",
],
"audio_decoder_factory\.h": [
"+rtc_base/ref_count.h",
],
"audio_decoder_factory_template\.h": [
"+rtc_base/ref_counted_object.h",
],
"audio_encoder\.h": [
"+rtc_base/buffer.h",
],
@ -216,10 +211,6 @@ specific_include_rules = {
"+rtc_base/ref_count.h",
],
"audio_encoder_factory_template\.h": [
"+rtc_base/ref_counted_object.h",
],
"frame_decryptor_interface\.h": [
"+rtc_base/ref_count.h",
],
@ -234,7 +225,6 @@ specific_include_rules = {
"rtc_stats_report\.h": [
"+rtc_base/ref_count.h",
"+rtc_base/ref_counted_object.h",
],
"audioproc_float\.h": [
@ -245,11 +235,14 @@ specific_include_rules = {
"+modules/audio_processing/include/audio_processing.h",
],
"fake_frame_decryptor\.h": [
"+rtc_base/ref_counted_object.h",
"fake_metronome\.h": [
"+rtc_base/synchronization/mutex.h",
"+rtc_base/task_queue.h",
"+rtc_base/task_utils/repeating_task.h",
"+rtc_base/thread_annotations.h",
],
"fake_frame_encryptor\.h": [
"make_ref_counted\.h": [
"+rtc_base/ref_counted_object.h",
],
@ -257,6 +250,18 @@ specific_include_rules = {
"+test/gmock.h",
],
"mock_peerconnectioninterface\.h": [
"+rtc_base/ref_counted_object.h",
],
"mock_video_track\.h": [
"+rtc_base/ref_counted_object.h",
],
"notifier\.h": [
"+rtc_base/system/no_unique_address.h",
],
"simulated_network\.h": [
"+rtc_base/random.h",
"+rtc_base/thread_annotations.h",
@ -278,6 +283,39 @@ specific_include_rules = {
"+rtc_base/ref_count.h",
],
"sequence_checker\.h": [
"+rtc_base/synchronization/sequence_checker_internal.h",
"+rtc_base/thread_annotations.h",
],
"wrapping_async_dns_resolver\.h": [
"+rtc_base/async_resolver.h",
"+rtc_base/async_resolver_interface.h",
"+rtc_base/socket_address.h",
"+rtc_base/third_party/sigslot/sigslot.h",
"+rtc_base/thread_annotations.h",
],
"video_encoder_factory_template.*\.h": [
"+modules/video_coding",
],
"video_decoder_factory_template.*\.h": [
"+modules/video_coding",
],
"field_trials\.h": [
"+rtc_base/containers/flat_map.h",
],
"video_track_source_proxy_factory.h": [
"+rtc_base/thread.h",
],
"field_trials_registry\.h": [
"+rtc_base/containers/flat_set.h",
],
# .cc files in api/ should not be restricted in what they can #include,
# so we re-add all the top-level directories here. (That's because .h
# files leak their #includes to whoever's #including them, but .cc files
@ -288,6 +326,7 @@ specific_include_rules = {
"+common_audio",
"+common_video",
"+examples",
"+experiments",
"+logging",
"+media",
"+modules",

View File

@ -1,14 +1,14 @@
crodbro@webrtc.org
deadbeef@webrtc.org
hta@webrtc.org
juberti@webrtc.org
kwiberg@webrtc.org
magjed@webrtc.org
perkj@webrtc.org
tkchin@webrtc.org
tommi@webrtc.org
# For approvals that absolutely must be done on US Pacific time
deadbeef@webrtc.org
tkchin@webrtc.org
per-file peer_connection*=hbos@webrtc.org
per-file DEPS=mbonadei@webrtc.org
per-file DEPS=kwiberg@webrtc.org
per-file uma_metrics.h=kron@webrtc.org

View File

@ -1,6 +1,6 @@
# How to write code in the `api/` directory
Mostly, just follow the regular [style guide](../style-guide.md), but:
Mostly, just follow the regular [style guide](../g3doc/style-guide.md), but:
* Note that `api/` code is not exempt from the “`.h` and `.cc` files come in
pairs” rule, so if you declare something in `api/path/to/foo.h`, it should be
@ -17,7 +17,7 @@ it from a `.cc` file, so that users of our API headers won’t transitively
For headers in `api/` that need to refer to non-public types, forward
declarations are often a lesser evil than including non-public header files. The
usual [rules](../style-guide.md#forward-declarations) still apply, though.
usual [rules](../g3doc/style-guide.md#forward-declarations) still apply, though.
`.cc` files in `api/` should preferably be kept reasonably small. If a
substantial implementation is needed, consider putting it with our non-public

View File

@ -16,8 +16,8 @@ rtc_source_set("resource_adaptation_api") {
]
deps = [
"../../api:scoped_refptr",
"../../rtc_base:checks",
"../../rtc_base:refcount",
"../../rtc_base:rtc_base_approved",
"../../rtc_base/system:rtc_export",
]
}

View File

@ -1,6 +1,6 @@
specific_include_rules = {
"resource\.h": [
# ref_count.h is a public_deps of rtc_base_approved. Necessary because of
# ref_count.h is a public_deps of rtc_base:refcount. Necessary because of
# rtc::RefCountInterface.
"+rtc_base/ref_count.h",
],

View File

@ -10,6 +10,8 @@
#include "api/adaptation/resource.h"
#include "rtc_base/checks.h"
namespace webrtc {
const char* ResourceUsageStateToString(ResourceUsageState usage_state) {
@ -19,6 +21,7 @@ const char* ResourceUsageStateToString(ResourceUsageState usage_state) {
case ResourceUsageState::kUnderuse:
return "kUnderuse";
}
RTC_CHECK_NOTREACHED();
}
ResourceListener::~ResourceListener() {}

View File

@ -57,7 +57,7 @@ class RTC_EXPORT Resource : public rtc::RefCountInterface {
~Resource() override;
virtual std::string Name() const = 0;
// The |listener| may be informed of resource usage measurements on any task
// The `listener` may be informed of resource usage measurements on any task
// queue, but not after this method is invoked with the null argument.
virtual void SetResourceListener(ResourceListener* listener) = 0;
};

View File

@ -13,6 +13,7 @@
#include <algorithm>
#include <array>
#include <iterator>
#include <type_traits>
#include "rtc_base/checks.h"
@ -83,7 +84,7 @@ namespace rtc {
// a pointer if fix-sized) and trivially copyable, so it's probably cheaper to
// pass it by value than by const reference.
namespace impl {
namespace array_view_internal {
// Magic constant for indicating that the size of an ArrayView is variable
// instead of fixed.
@ -124,7 +125,7 @@ class ArrayViewBase<T, 0> {
// Specialized base class for ArrayViews of variable size.
template <typename T>
class ArrayViewBase<T, impl::kArrayViewVarSize> {
class ArrayViewBase<T, array_view_internal::kArrayViewVarSize> {
public:
ArrayViewBase(T* data, size_t size)
: data_(size == 0 ? nullptr : data), size_(size) {}
@ -141,10 +142,11 @@ class ArrayViewBase<T, impl::kArrayViewVarSize> {
size_t size_;
};
} // namespace impl
} // namespace array_view_internal
template <typename T, std::ptrdiff_t Size = impl::kArrayViewVarSize>
class ArrayView final : public impl::ArrayViewBase<T, Size> {
template <typename T,
std::ptrdiff_t Size = array_view_internal::kArrayViewVarSize>
class ArrayView final : public array_view_internal::ArrayViewBase<T, Size> {
public:
using value_type = T;
using const_iterator = const T*;
@ -152,7 +154,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
// Construct an ArrayView from a pointer and a length.
template <typename U>
ArrayView(U* data, size_t size)
: impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) {
: array_view_internal::ArrayViewBase<T, Size>::ArrayViewBase(data, size) {
RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data());
RTC_DCHECK_EQ(size, this->size());
RTC_DCHECK_EQ(!this->data(),
@ -166,7 +168,8 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
: ArrayView() {}
ArrayView(std::nullptr_t, size_t size)
: ArrayView(static_cast<T*>(nullptr), size) {
static_assert(Size == 0 || Size == impl::kArrayViewVarSize, "");
static_assert(Size == 0 || Size == array_view_internal::kArrayViewVarSize,
"");
RTC_DCHECK_EQ(0, size);
}
@ -174,7 +177,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
template <typename U, size_t N>
ArrayView(U (&array)[N]) // NOLINT
: ArrayView(array, N) {
static_assert(Size == N || Size == impl::kArrayViewVarSize,
static_assert(Size == N || Size == array_view_internal::kArrayViewVarSize,
"Array size must match ArrayView size");
}
@ -207,7 +210,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
// N> when M != N.
template <
typename U,
typename std::enable_if<Size != impl::kArrayViewVarSize &&
typename std::enable_if<Size != array_view_internal::kArrayViewVarSize &&
HasDataAndSize<U, T>::value>::type* = nullptr>
ArrayView(U& u) // NOLINT
: ArrayView(u.data(), u.size()) {
@ -215,7 +218,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
}
template <
typename U,
typename std::enable_if<Size != impl::kArrayViewVarSize &&
typename std::enable_if<Size != array_view_internal::kArrayViewVarSize &&
HasDataAndSize<U, T>::value>::type* = nullptr>
ArrayView(const U& u) // NOLINT(runtime/explicit)
: ArrayView(u.data(), u.size()) {
@ -235,13 +238,13 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
// const rtc::Buffer to ArrayView<const uint8_t>.
template <
typename U,
typename std::enable_if<Size == impl::kArrayViewVarSize &&
typename std::enable_if<Size == array_view_internal::kArrayViewVarSize &&
HasDataAndSize<U, T>::value>::type* = nullptr>
ArrayView(U& u) // NOLINT
: ArrayView(u.data(), u.size()) {}
template <
typename U,
typename std::enable_if<Size == impl::kArrayViewVarSize &&
typename std::enable_if<Size == array_view_internal::kArrayViewVarSize &&
HasDataAndSize<U, T>::value>::type* = nullptr>
ArrayView(const U& u) // NOLINT(runtime/explicit)
: ArrayView(u.data(), u.size()) {}
@ -258,6 +261,18 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
T* end() const { return this->data() + this->size(); }
const T* cbegin() const { return this->data(); }
const T* cend() const { return this->data() + this->size(); }
std::reverse_iterator<T*> rbegin() const {
return std::make_reverse_iterator(end());
}
std::reverse_iterator<T*> rend() const {
return std::make_reverse_iterator(begin());
}
std::reverse_iterator<const T*> crbegin() const {
return std::make_reverse_iterator(cend());
}
std::reverse_iterator<const T*> crend() const {
return std::make_reverse_iterator(cbegin());
}
ArrayView<T> subview(size_t offset, size_t size) const {
return offset < this->size()

View File

@ -451,6 +451,20 @@ TEST(ArrayViewTest, TestIterationEmpty) {
}
}
TEST(ArrayViewTest, TestReverseIterationEmpty) {
// Variable-size.
ArrayView<std::vector<std::vector<std::vector<std::string>>>> av;
EXPECT_EQ(av.rbegin(), av.rend());
EXPECT_EQ(av.crbegin(), av.crend());
EXPECT_TRUE(av.empty());
// Fixed-size.
ArrayView<std::vector<std::vector<std::vector<std::string>>>, 0> af;
EXPECT_EQ(af.begin(), af.end());
EXPECT_EQ(af.cbegin(), af.cend());
EXPECT_TRUE(af.empty());
}
TEST(ArrayViewTest, TestIterationVariable) {
char arr[] = "Arrr!";
ArrayView<char> av(arr);
@ -472,6 +486,25 @@ TEST(ArrayViewTest, TestIterationVariable) {
}
}
TEST(ArrayViewTest, TestReverseIterationVariable) {
char arr[] = "Arrr!";
ArrayView<char> av(arr);
EXPECT_EQ('\0', *av.rbegin());
EXPECT_EQ('\0', *av.crbegin());
EXPECT_EQ('A', *(av.rend() - 1));
EXPECT_EQ('A', *(av.crend() - 1));
const char* cit = av.cend() - 1;
for (auto crit = av.crbegin(); crit != av.crend(); ++crit, --cit) {
EXPECT_EQ(*cit, *crit);
}
char* it = av.end() - 1;
for (auto rit = av.rbegin(); rit != av.rend(); ++rit, --it) {
EXPECT_EQ(*it, *rit);
}
}
TEST(ArrayViewTest, TestIterationFixed) {
char arr[] = "Arrr!";
ArrayView<char, 6> av(arr);
@ -493,6 +526,25 @@ TEST(ArrayViewTest, TestIterationFixed) {
}
}
TEST(ArrayViewTest, TestReverseIterationFixed) {
char arr[] = "Arrr!";
ArrayView<char, 6> av(arr);
EXPECT_EQ('\0', *av.rbegin());
EXPECT_EQ('\0', *av.crbegin());
EXPECT_EQ('A', *(av.rend() - 1));
EXPECT_EQ('A', *(av.crend() - 1));
const char* cit = av.cend() - 1;
for (auto crit = av.crbegin(); crit != av.crend(); ++crit, --cit) {
EXPECT_EQ(*cit, *crit);
}
char* it = av.end() - 1;
for (auto rit = av.rbegin(); rit != av.rend(); ++rit, --it) {
EXPECT_EQ(*it, *rit);
}
}
TEST(ArrayViewTest, TestEmpty) {
EXPECT_TRUE(ArrayView<int>().empty());
const int a[] = {1, 2, 3};

104
api/async_dns_resolver.h Normal file
View File

@ -0,0 +1,104 @@
/*
* Copyright 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_ASYNC_DNS_RESOLVER_H_
#define API_ASYNC_DNS_RESOLVER_H_
#include <functional>
#include <memory>
#include "rtc_base/checks.h"
#include "rtc_base/socket_address.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// This interface defines the methods to resolve a hostname asynchronously.
// The AsyncDnsResolverInterface class encapsulates a single name query.
//
// Usage:
// std::unique_ptr<AsyncDnsResolverInterface> resolver =
// factory->Create(address-to-be-resolved, [r = resolver.get()]() {
// if (r->result.GetResolvedAddress(AF_INET, &addr) {
// // success
// } else {
// // failure
// error = r->result().GetError();
// }
// // Release resolver.
// resolver_list.erase(std::remove_if(resolver_list.begin(),
// resolver_list.end(),
// [](refptr) { refptr.get() == r; });
// });
// resolver_list.push_back(std::move(resolver));
class AsyncDnsResolverResult {
public:
virtual ~AsyncDnsResolverResult() = default;
// Returns true iff the address from `Start` was successfully resolved.
// If the address was successfully resolved, sets `addr` to a copy of the
// address from `Start` with the IP address set to the top most resolved
// address of `family` (`addr` will have both hostname and the resolved ip).
virtual bool GetResolvedAddress(int family,
rtc::SocketAddress* addr) const = 0;
// Returns error from resolver.
virtual int GetError() const = 0;
};
// The API for a single name query.
// The constructor, destructor and all functions must be called from
// the same sequence, and the callback will also be called on that sequence.
// The class guarantees that the callback will not be called if the
// resolver's destructor has been called.
class RTC_EXPORT AsyncDnsResolverInterface {
public:
virtual ~AsyncDnsResolverInterface() = default;
// Start address resolution of the hostname in `addr`.
virtual void Start(const rtc::SocketAddress& addr,
std::function<void()> callback) = 0;
// Start address resolution of the hostname in `addr` matching `family`.
virtual void Start(const rtc::SocketAddress& addr,
int family,
std::function<void()> callback) = 0;
virtual const AsyncDnsResolverResult& result() const = 0;
};
// An abstract factory for creating AsyncDnsResolverInterfaces. This allows
// client applications to provide WebRTC with their own mechanism for
// performing DNS resolution.
class AsyncDnsResolverFactoryInterface {
public:
virtual ~AsyncDnsResolverFactoryInterface() = default;
// Creates an AsyncDnsResolver and starts resolving the name. The callback
// will be called when resolution is finished.
// The callback will be called on the sequence that the caller runs on.
virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAndResolve(
const rtc::SocketAddress& addr,
std::function<void()> callback) = 0;
// Creates an AsyncDnsResolver and starts resolving the name to an address
// matching the specified family. The callback will be called when resolution
// is finished. The callback will be called on the sequence that the caller
// runs on.
virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAndResolve(
const rtc::SocketAddress& addr,
int family,
std::function<void()> callback) = 0;
// Creates an AsyncDnsResolver and does not start it.
// For backwards compatibility, will be deprecated and removed.
// One has to do a separate Start() call on the
// resolver to start name resolution.
virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> Create() = 0;
};
} // namespace webrtc
#endif // API_ASYNC_DNS_RESOLVER_H_

View File

@ -20,17 +20,25 @@ rtc_library("audio_frame_api") {
deps = [
"..:rtp_packet_info",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:logging",
"../../rtc_base:macromagic",
"../../rtc_base:timeutils",
]
}
rtc_source_set("audio_frame_processor") {
visibility = [ "*" ]
sources = [ "audio_frame_processor.h" ]
}
rtc_source_set("audio_mixer_api") {
visibility = [ "*" ]
sources = [ "audio_mixer.h" ]
deps = [
":audio_frame_api",
"../../rtc_base:rtc_base_approved",
"..:make_ref_counted",
"../../rtc_base:refcount",
]
}
@ -42,7 +50,6 @@ rtc_library("aec3_config") {
]
deps = [
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:safe_minmax",
"../../rtc_base/system:rtc_export",
]
@ -58,8 +65,9 @@ rtc_library("aec3_config_json") {
deps = [
":aec3_config",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:logging",
"../../rtc_base:rtc_json",
"../../rtc_base:stringutils",
"../../rtc_base/system:rtc_export",
]
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
@ -77,7 +85,6 @@ rtc_library("aec3_factory") {
":aec3_config",
":echo_control",
"../../modules/audio_processing/aec3",
"../../rtc_base:rtc_base_approved",
"../../rtc_base/system:rtc_export",
]
}
@ -90,14 +97,15 @@ rtc_source_set("echo_control") {
rtc_source_set("echo_detector_creator") {
visibility = [ "*" ]
allow_poison = [ "default_echo_detector" ]
sources = [
"echo_detector_creator.cc",
"echo_detector_creator.h",
]
deps = [
"..:make_ref_counted",
"../../api:scoped_refptr",
"../../modules/audio_processing:api",
"../../modules/audio_processing:audio_processing",
"../../rtc_base:refcount",
"../../modules/audio_processing:residual_echo_detector",
]
}

View File

@ -11,8 +11,6 @@
#include "api/audio/audio_frame.h"
#include <string.h>
#include <algorithm>
#include <utility>
#include "rtc_base/checks.h"
#include "rtc_base/time_utils.h"
@ -24,35 +22,13 @@ AudioFrame::AudioFrame() {
static_assert(sizeof(data_) == kMaxDataSizeBytes, "kMaxDataSizeBytes");
}
void swap(AudioFrame& a, AudioFrame& b) {
using std::swap;
swap(a.timestamp_, b.timestamp_);
swap(a.elapsed_time_ms_, b.elapsed_time_ms_);
swap(a.ntp_time_ms_, b.ntp_time_ms_);
swap(a.samples_per_channel_, b.samples_per_channel_);
swap(a.sample_rate_hz_, b.sample_rate_hz_);
swap(a.num_channels_, b.num_channels_);
swap(a.channel_layout_, b.channel_layout_);
swap(a.speech_type_, b.speech_type_);
swap(a.vad_activity_, b.vad_activity_);
swap(a.profile_timestamp_ms_, b.profile_timestamp_ms_);
swap(a.packet_infos_, b.packet_infos_);
const size_t length_a = a.samples_per_channel_ * a.num_channels_;
const size_t length_b = b.samples_per_channel_ * b.num_channels_;
RTC_DCHECK_LE(length_a, AudioFrame::kMaxDataSizeSamples);
RTC_DCHECK_LE(length_b, AudioFrame::kMaxDataSizeSamples);
std::swap_ranges(a.data_, a.data_ + std::max(length_a, length_b), b.data_);
swap(a.muted_, b.muted_);
swap(a.absolute_capture_timestamp_ms_, b.absolute_capture_timestamp_ms_);
}
void AudioFrame::Reset() {
ResetWithoutMuting();
muted_ = true;
}
void AudioFrame::ResetWithoutMuting() {
// TODO(wu): Zero is a valid value for |timestamp_|. We should initialize
// TODO(wu): Zero is a valid value for `timestamp_`. We should initialize
// to an invalid value, or add a new member to indicate invalidity.
timestamp_ = 0;
elapsed_time_ms_ = -1;

View File

@ -14,11 +14,8 @@
#include <stddef.h>
#include <stdint.h>
#include <utility>
#include "api/audio/channel_layout.h"
#include "api/rtp_packet_infos.h"
#include "rtc_base/constructor_magic.h"
namespace webrtc {
@ -60,7 +57,8 @@ class AudioFrame {
AudioFrame();
friend void swap(AudioFrame& a, AudioFrame& b);
AudioFrame(const AudioFrame&) = delete;
AudioFrame& operator=(const AudioFrame&) = delete;
// Resets all members to their default state.
void Reset();
@ -139,7 +137,7 @@ class AudioFrame {
int64_t profile_timestamp_ms_ = 0;
// Information about packets used to assemble this audio frame. This is needed
// by |SourceTracker| when the frame is delivered to the RTCRtpReceiver's
// by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
// MediaStreamTrack, in order to implement getContributingSources(). See:
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
//
@ -149,7 +147,7 @@ class AudioFrame {
// sync buffer is the small sample-holding buffer located after the audio
// decoder and before where samples are assembled into output frames.
//
// |RtpPacketInfos| may also be empty if the audio samples did not come from
// `RtpPacketInfos` may also be empty if the audio samples did not come from
// RTP packets. E.g. if the audio were locally generated by packet loss
// concealment, comfort noise generation, etc.
RtpPacketInfos packet_infos_;
@ -165,11 +163,9 @@ class AudioFrame {
// Absolute capture timestamp when this audio frame was originally captured.
// This is only valid for audio frames captured on this machine. The absolute
// capture timestamp of a received frame is found in |packet_infos_|.
// capture timestamp of a received frame is found in `packet_infos_`.
// This timestamp MUST be based on the same clock as rtc::TimeMillis().
absl::optional<int64_t> absolute_capture_timestamp_ms_;
RTC_DISALLOW_COPY_AND_ASSIGN(AudioFrame);
};
} // namespace webrtc

View File

@ -0,0 +1,43 @@
/*
* 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_AUDIO_AUDIO_FRAME_PROCESSOR_H_
#define API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
#include <functional>
#include <memory>
namespace webrtc {
class AudioFrame;
// If passed into PeerConnectionFactory, will be used for additional
// processing of captured audio frames, performed before encoding.
// Implementations must be thread-safe.
class AudioFrameProcessor {
public:
using OnAudioFrameCallback = std::function<void(std::unique_ptr<AudioFrame>)>;
virtual ~AudioFrameProcessor() = default;
// Processes the frame received from WebRTC, is called by WebRTC off the
// realtime audio capturing path. AudioFrameProcessor must reply with
// processed frames by calling `sink_callback` if it was provided in SetSink()
// call. `sink_callback` can be called in the context of Process().
virtual void Process(std::unique_ptr<AudioFrame> frame) = 0;
// Atomically replaces the current sink with the new one. Before the
// first call to this function, or if the provided `sink_callback` is nullptr,
// processed frames are simply discarded.
virtual void SetSink(OnAudioFrameCallback sink_callback) = 0;
};
} // namespace webrtc
#endif // API_AUDIO_AUDIO_FRAME_PROCESSOR_H_

View File

@ -35,9 +35,9 @@ class AudioMixer : public rtc::RefCountInterface {
kError, // The audio_frame will not be used.
};
// Overwrites |audio_frame|. The data_ field is overwritten with
// Overwrites `audio_frame`. The data_ field is overwritten with
// 10 ms of new audio (either 1 or 2 interleaved channels) at
// |sample_rate_hz|. All fields in |audio_frame| must be updated.
// `sample_rate_hz`. All fields in `audio_frame` must be updated.
virtual AudioFrameInfo GetAudioFrameWithInfo(int sample_rate_hz,
AudioFrame* audio_frame) = 0;
@ -66,7 +66,7 @@ class AudioMixer : public rtc::RefCountInterface {
// should mix at a rate that doesn't cause quality loss of the
// sources' audio. The mixing rate is one of the rates listed in
// AudioProcessing::NativeRate. All fields in
// |audio_frame_for_mixing| must be updated.
// `audio_frame_for_mixing` must be updated.
virtual void Mix(size_t number_of_channels,
AudioFrame* audio_frame_for_mixing) = 0;

View File

@ -275,7 +275,7 @@ const char* ChannelLayoutToString(ChannelLayout layout) {
case CHANNEL_LAYOUT_BITSTREAM:
return "BITSTREAM";
}
RTC_NOTREACHED() << "Invalid channel layout provided: " << layout;
RTC_DCHECK_NOTREACHED() << "Invalid channel layout provided: " << layout;
return "";
}

View File

@ -153,6 +153,7 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
res = res & Limit(&c->filter.config_change_duration_blocks, 0, 100000);
res = res & Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
res = res & Limit(&c->filter.coarse_reset_hangover_blocks, 0, 250000);
res = res & Limit(&c->erle.min, 1.f, 100000.f);
res = res & Limit(&c->erle.max_l, 1.f, 100000.f);
@ -165,6 +166,7 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
res = res & Limit(&c->ep_strength.default_gain, 0.f, 1000000.f);
res = res & Limit(&c->ep_strength.default_len, -1.f, 1.f);
res = res & Limit(&c->ep_strength.nearend_len, -1.0f, 1.0f);
res =
res & Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
@ -228,6 +230,12 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
res =
res & Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
res = res & Limit(&c->suppressor.last_permanent_lf_smoothing_band, 0, 64);
res = res & Limit(&c->suppressor.last_lf_smoothing_band, 0, 64);
res = res & Limit(&c->suppressor.last_lf_band, 0, 63);
res = res &
Limit(&c->suppressor.first_hf_band, c->suppressor.last_lf_band + 1, 64);
res = res & Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
0.f, 1000000.f);
res = res & Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,

View File

@ -43,6 +43,7 @@ struct RTC_EXPORT EchoCanceller3Config {
size_t hysteresis_limit_blocks = 1;
size_t fixed_capture_delay_samples = 0;
float delay_estimate_smoothing = 0.7f;
float delay_estimate_smoothing_delay_found = 0.7f;
float delay_candidate_detection_threshold = 0.2f;
struct DelaySelectionThresholds {
int initial;
@ -58,6 +59,7 @@ struct RTC_EXPORT EchoCanceller3Config {
};
AlignmentMixing render_alignment_mixing = {false, true, 10000.f, true};
AlignmentMixing capture_alignment_mixing = {false, true, 10000.f, false};
bool detect_pre_echo = true;
} delay;
struct Filter {
@ -86,9 +88,11 @@ struct RTC_EXPORT EchoCanceller3Config {
size_t config_change_duration_blocks = 250;
float initial_state_seconds = 2.5f;
int coarse_reset_hangover_blocks = 25;
bool conservative_initial_phase = false;
bool enable_coarse_filter_output_usage = true;
bool use_linear_filter = true;
bool high_pass_filter_echo_reference = false;
bool export_linear_aec_output = false;
} filter;
@ -105,8 +109,11 @@ struct RTC_EXPORT EchoCanceller3Config {
struct EpStrength {
float default_gain = 1.f;
float default_len = 0.83f;
float nearend_len = 0.83f;
bool echo_can_saturate = true;
bool bounded_erl = false;
bool erle_onset_compensation_in_dominant_nearend = false;
bool use_conservative_tail_frequency_response = true;
} ep_strength;
struct EchoAudibility {
@ -143,6 +150,7 @@ struct RTC_EXPORT EchoCanceller3Config {
float noise_gate_slope = 0.3f;
size_t render_pre_window_size = 1;
size_t render_post_window_size = 1;
bool model_reverb_in_nonlinear_mode = true;
} echo_model;
struct ComfortNoise {
@ -189,6 +197,12 @@ struct RTC_EXPORT EchoCanceller3Config {
2.0f,
0.25f);
bool lf_smoothing_during_initial_phase = true;
int last_permanent_lf_smoothing_band = 0;
int last_lf_smoothing_band = 5;
int last_lf_band = 5;
int first_hf_band = 8;
struct DominantNearendDetection {
float enr_threshold = .25f;
float enr_exit_threshold = 10.f;
@ -196,6 +210,7 @@ struct RTC_EXPORT EchoCanceller3Config {
int hold_duration = 50;
int trigger_threshold = 12;
bool use_during_initial_phase = true;
bool use_unbounded_echo_spectrum = true;
} dominant_nearend_detection;
struct SubbandNearendDetection {
@ -215,12 +230,20 @@ struct RTC_EXPORT EchoCanceller3Config {
struct HighBandsSuppression {
float enr_threshold = 1.f;
float max_gain_during_echo = 1.f;
float anti_howling_activation_threshold = 25.f;
float anti_howling_gain = 0.01f;
float anti_howling_activation_threshold = 400.f;
float anti_howling_gain = 1.f;
} high_bands_suppression;
float floor_first_increase = 0.00001f;
bool conservative_hf_suppression = false;
} suppressor;
struct MultiChannel {
bool detect_stereo_content = true;
float stereo_detection_threshold = 0.0f;
int stereo_detection_timeout_threshold_seconds = 300;
float stereo_detection_hysteresis_seconds = 2.0f;
} multi_channel;
};
} // namespace webrtc

View File

@ -11,6 +11,7 @@
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
@ -156,9 +157,14 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
*parsing_successful = true;
Json::Value root;
bool success = Json::Reader().parse(std::string(json_string), root);
Json::CharReaderBuilder builder;
std::string error_message;
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
bool success =
reader->parse(json_string.data(), json_string.data() + json_string.size(),
&root, &error_message);
if (!success) {
RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << json_string;
RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << error_message;
*parsing_successful = false;
return;
}
@ -191,6 +197,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
&cfg.delay.fixed_capture_delay_samples);
ReadParam(section, "delay_estimate_smoothing",
&cfg.delay.delay_estimate_smoothing);
ReadParam(section, "delay_estimate_smoothing_delay_found",
&cfg.delay.delay_estimate_smoothing_delay_found);
ReadParam(section, "delay_candidate_detection_threshold",
&cfg.delay.delay_candidate_detection_threshold);
@ -212,6 +220,7 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
&cfg.delay.render_alignment_mixing);
ReadParam(section, "capture_alignment_mixing",
&cfg.delay.capture_alignment_mixing);
ReadParam(section, "detect_pre_echo", &cfg.delay.detect_pre_echo);
}
if (rtc::GetValueFromJsonObject(aec3_root, "filter", &section)) {
@ -223,11 +232,15 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
&cfg.filter.config_change_duration_blocks);
ReadParam(section, "initial_state_seconds",
&cfg.filter.initial_state_seconds);
ReadParam(section, "coarse_reset_hangover_blocks",
&cfg.filter.coarse_reset_hangover_blocks);
ReadParam(section, "conservative_initial_phase",
&cfg.filter.conservative_initial_phase);
ReadParam(section, "enable_coarse_filter_output_usage",
&cfg.filter.enable_coarse_filter_output_usage);
ReadParam(section, "use_linear_filter", &cfg.filter.use_linear_filter);
ReadParam(section, "high_pass_filter_echo_reference",
&cfg.filter.high_pass_filter_echo_reference);
ReadParam(section, "export_linear_aec_output",
&cfg.filter.export_linear_aec_output);
}
@ -247,8 +260,13 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
if (rtc::GetValueFromJsonObject(aec3_root, "ep_strength", &section)) {
ReadParam(section, "default_gain", &cfg.ep_strength.default_gain);
ReadParam(section, "default_len", &cfg.ep_strength.default_len);
ReadParam(section, "nearend_len", &cfg.ep_strength.nearend_len);
ReadParam(section, "echo_can_saturate", &cfg.ep_strength.echo_can_saturate);
ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl);
ReadParam(section, "erle_onset_compensation_in_dominant_nearend",
&cfg.ep_strength.erle_onset_compensation_in_dominant_nearend);
ReadParam(section, "use_conservative_tail_frequency_response",
&cfg.ep_strength.use_conservative_tail_frequency_response);
}
if (rtc::GetValueFromJsonObject(aec3_root, "echo_audibility", &section)) {
@ -302,6 +320,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
&cfg.echo_model.render_pre_window_size);
ReadParam(section, "render_post_window_size",
&cfg.echo_model.render_post_window_size);
ReadParam(section, "model_reverb_in_nonlinear_mode",
&cfg.echo_model.model_reverb_in_nonlinear_mode);
}
if (rtc::GetValueFromJsonObject(aec3_root, "comfort_noise", &section)) {
@ -331,6 +351,15 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
&cfg.suppressor.nearend_tuning.max_dec_factor_lf);
}
ReadParam(section, "lf_smoothing_during_initial_phase",
&cfg.suppressor.lf_smoothing_during_initial_phase);
ReadParam(section, "last_permanent_lf_smoothing_band",
&cfg.suppressor.last_permanent_lf_smoothing_band);
ReadParam(section, "last_lf_smoothing_band",
&cfg.suppressor.last_lf_smoothing_band);
ReadParam(section, "last_lf_band", &cfg.suppressor.last_lf_band);
ReadParam(section, "first_hf_band", &cfg.suppressor.first_hf_band);
if (rtc::GetValueFromJsonObject(section, "dominant_nearend_detection",
&subsection)) {
ReadParam(subsection, "enr_threshold",
@ -346,6 +375,9 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
ReadParam(
subsection, "use_during_initial_phase",
&cfg.suppressor.dominant_nearend_detection.use_during_initial_phase);
ReadParam(subsection, "use_unbounded_echo_spectrum",
&cfg.suppressor.dominant_nearend_detection
.use_unbounded_echo_spectrum);
}
if (rtc::GetValueFromJsonObject(section, "subband_nearend_detection",
@ -381,6 +413,19 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
ReadParam(section, "floor_first_increase",
&cfg.suppressor.floor_first_increase);
ReadParam(section, "conservative_hf_suppression",
&cfg.suppressor.conservative_hf_suppression);
}
if (rtc::GetValueFromJsonObject(aec3_root, "multi_channel", &section)) {
ReadParam(section, "detect_stereo_content",
&cfg.multi_channel.detect_stereo_content);
ReadParam(section, "stereo_detection_threshold",
&cfg.multi_channel.stereo_detection_threshold);
ReadParam(section, "stereo_detection_timeout_threshold_seconds",
&cfg.multi_channel.stereo_detection_timeout_threshold_seconds);
ReadParam(section, "stereo_detection_hysteresis_seconds",
&cfg.multi_channel.stereo_detection_hysteresis_seconds);
}
}
@ -415,6 +460,8 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
<< config.delay.fixed_capture_delay_samples << ",";
ost << "\"delay_estimate_smoothing\": "
<< config.delay.delay_estimate_smoothing << ",";
ost << "\"delay_estimate_smoothing_delay_found\": "
<< config.delay.delay_estimate_smoothing_delay_found << ",";
ost << "\"delay_candidate_detection_threshold\": "
<< config.delay.delay_candidate_detection_threshold << ",";
@ -459,7 +506,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
<< (config.delay.capture_alignment_mixing.prefer_first_two_channels
? "true"
: "false");
ost << "}";
ost << "},";
ost << "\"detect_pre_echo\": "
<< (config.delay.detect_pre_echo ? "true" : "false");
ost << "},";
ost << "\"filter\": {";
@ -498,6 +547,8 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
<< config.filter.config_change_duration_blocks << ",";
ost << "\"initial_state_seconds\": " << config.filter.initial_state_seconds
<< ",";
ost << "\"coarse_reset_hangover_blocks\": "
<< config.filter.coarse_reset_hangover_blocks << ",";
ost << "\"conservative_initial_phase\": "
<< (config.filter.conservative_initial_phase ? "true" : "false") << ",";
ost << "\"enable_coarse_filter_output_usage\": "
@ -505,6 +556,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
<< ",";
ost << "\"use_linear_filter\": "
<< (config.filter.use_linear_filter ? "true" : "false") << ",";
ost << "\"high_pass_filter_echo_reference\": "
<< (config.filter.high_pass_filter_echo_reference ? "true" : "false")
<< ",";
ost << "\"export_linear_aec_output\": "
<< (config.filter.export_linear_aec_output ? "true" : "false");
@ -526,11 +580,20 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
ost << "\"ep_strength\": {";
ost << "\"default_gain\": " << config.ep_strength.default_gain << ",";
ost << "\"default_len\": " << config.ep_strength.default_len << ",";
ost << "\"nearend_len\": " << config.ep_strength.nearend_len << ",";
ost << "\"echo_can_saturate\": "
<< (config.ep_strength.echo_can_saturate ? "true" : "false") << ",";
ost << "\"bounded_erl\": "
<< (config.ep_strength.bounded_erl ? "true" : "false");
<< (config.ep_strength.bounded_erl ? "true" : "false") << ",";
ost << "\"erle_onset_compensation_in_dominant_nearend\": "
<< (config.ep_strength.erle_onset_compensation_in_dominant_nearend
? "true"
: "false")
<< ",";
ost << "\"use_conservative_tail_frequency_response\": "
<< (config.ep_strength.use_conservative_tail_frequency_response
? "true"
: "false");
ost << "},";
ost << "\"echo_audibility\": {";
@ -585,7 +648,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
ost << "\"render_pre_window_size\": "
<< config.echo_model.render_pre_window_size << ",";
ost << "\"render_post_window_size\": "
<< config.echo_model.render_post_window_size;
<< config.echo_model.render_post_window_size << ",";
ost << "\"model_reverb_in_nonlinear_mode\": "
<< (config.echo_model.model_reverb_in_nonlinear_mode ? "true" : "false");
ost << "},";
ost << "\"comfort_noise\": {";
@ -627,20 +692,30 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
ost << "\"max_dec_factor_lf\": "
<< config.suppressor.nearend_tuning.max_dec_factor_lf;
ost << "},";
ost << "\"dominant_nearend_detection\": {";
ost << "\"enr_threshold\": "
<< config.suppressor.dominant_nearend_detection.enr_threshold << ",";
ost << "\"enr_exit_threshold\": "
<< config.suppressor.dominant_nearend_detection.enr_exit_threshold << ",";
ost << "\"snr_threshold\": "
<< config.suppressor.dominant_nearend_detection.snr_threshold << ",";
ost << "\"hold_duration\": "
<< config.suppressor.dominant_nearend_detection.hold_duration << ",";
ost << "\"trigger_threshold\": "
<< config.suppressor.dominant_nearend_detection.trigger_threshold << ",";
ost << "\"use_during_initial_phase\": "
<< config.suppressor.dominant_nearend_detection.use_during_initial_phase;
ost << "},";
ost << "\"lf_smoothing_during_initial_phase\": "
<< (config.suppressor.lf_smoothing_during_initial_phase ? "true"
: "false")
<< ",";
ost << "\"last_permanent_lf_smoothing_band\": "
<< config.suppressor.last_permanent_lf_smoothing_band << ",";
ost << "\"last_lf_smoothing_band\": "
<< config.suppressor.last_lf_smoothing_band << ",";
ost << "\"last_lf_band\": " << config.suppressor.last_lf_band << ",";
ost << "\"first_hf_band\": " << config.suppressor.first_hf_band << ",";
{
const auto& dnd = config.suppressor.dominant_nearend_detection;
ost << "\"dominant_nearend_detection\": {";
ost << "\"enr_threshold\": " << dnd.enr_threshold << ",";
ost << "\"enr_exit_threshold\": " << dnd.enr_exit_threshold << ",";
ost << "\"snr_threshold\": " << dnd.snr_threshold << ",";
ost << "\"hold_duration\": " << dnd.hold_duration << ",";
ost << "\"trigger_threshold\": " << dnd.trigger_threshold << ",";
ost << "\"use_during_initial_phase\": " << dnd.use_during_initial_phase
<< ",";
ost << "\"use_unbounded_echo_spectrum\": "
<< dnd.use_unbounded_echo_spectrum;
ost << "},";
}
ost << "\"subband_nearend_detection\": {";
ost << "\"nearend_average_blocks\": "
<< config.suppressor.subband_nearend_detection.nearend_average_blocks
@ -672,8 +747,23 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
ost << "\"anti_howling_gain\": "
<< config.suppressor.high_bands_suppression.anti_howling_gain;
ost << "},";
ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase;
ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase
<< ",";
ost << "\"conservative_hf_suppression\": "
<< config.suppressor.conservative_hf_suppression;
ost << "},";
ost << "\"multi_channel\": {";
ost << "\"detect_stereo_content\": "
<< (config.multi_channel.detect_stereo_content ? "true" : "false") << ",";
ost << "\"stereo_detection_threshold\": "
<< config.multi_channel.stereo_detection_threshold << ",";
ost << "\"stereo_detection_timeout_threshold_seconds\": "
<< config.multi_channel.stereo_detection_timeout_threshold_seconds << ",";
ost << "\"stereo_detection_hysteresis_seconds\": "
<< config.multi_channel.stereo_detection_hysteresis_seconds;
ost << "}";
ost << "}";
ost << "}";

View File

@ -25,7 +25,8 @@ std::unique_ptr<EchoControl> EchoCanceller3Factory::Create(
int num_render_channels,
int num_capture_channels) {
return std::make_unique<EchoCanceller3>(
config_, sample_rate_hz, num_render_channels, num_capture_channels);
config_, /*multichannel_config=*/absl::nullopt, sample_rate_hz,
num_render_channels, num_capture_channels);
}
} // namespace webrtc

View File

@ -48,6 +48,13 @@ class EchoControl {
// Provides an optional external estimate of the audio buffer delay.
virtual void SetAudioBufferDelay(int delay_ms) = 0;
// Specifies whether the capture output will be used. The purpose of this is
// to allow the echo controller to deactivate some of the processing when the
// resulting output is anyway not used, for instance when the endpoint is
// muted.
// TODO(b/177830919): Make pure virtual.
virtual void SetCaptureOutputUsage(bool capture_output_used) {}
// Returns wheter the signal is altered.
virtual bool ActiveProcessing() const = 0;

View File

@ -9,13 +9,13 @@
*/
#include "api/audio/echo_detector_creator.h"
#include "api/make_ref_counted.h"
#include "modules/audio_processing/residual_echo_detector.h"
#include "rtc_base/ref_counted_object.h"
namespace webrtc {
rtc::scoped_refptr<EchoDetector> CreateEchoDetector() {
return new rtc::RefCountedObject<ResidualEchoDetector>();
return rtc::make_ref_counted<ResidualEchoDetector>();
}
} // namespace webrtc

View File

@ -24,7 +24,6 @@ if (rtc_include_tests) {
"..:aec3_config",
"..:aec3_config_json",
"..:audio_frame_api",
"../../../rtc_base:rtc_base_approved",
"../../../test:test_support",
]
}

View File

@ -133,54 +133,4 @@ TEST(AudioFrameTest, CopyFrom) {
EXPECT_EQ(0, memcmp(frame2.data(), frame1.data(), sizeof(samples)));
}
TEST(AudioFrameTest, SwapFrames) {
AudioFrame frame1, frame2;
int16_t samples1[kNumChannelsMono * kSamplesPerChannel];
for (size_t i = 0; i < kNumChannelsMono * kSamplesPerChannel; ++i) {
samples1[i] = i;
}
frame1.UpdateFrame(kTimestamp, samples1, kSamplesPerChannel, kSampleRateHz,
AudioFrame::kPLC, AudioFrame::kVadActive,
kNumChannelsMono);
frame1.set_absolute_capture_timestamp_ms(12345678);
const auto frame1_channel_layout = frame1.channel_layout();
int16_t samples2[(kNumChannelsMono + 1) * (kSamplesPerChannel + 1)];
for (size_t i = 0; i < (kNumChannelsMono + 1) * (kSamplesPerChannel + 1);
++i) {
samples2[i] = 1000 + i;
}
frame2.UpdateFrame(kTimestamp + 1, samples2, kSamplesPerChannel + 1,
kSampleRateHz + 1, AudioFrame::kNormalSpeech,
AudioFrame::kVadPassive, kNumChannelsMono + 1);
const auto frame2_channel_layout = frame2.channel_layout();
swap(frame1, frame2);
EXPECT_EQ(kTimestamp + 1, frame1.timestamp_);
ASSERT_EQ(kSamplesPerChannel + 1, frame1.samples_per_channel_);
EXPECT_EQ(kSampleRateHz + 1, frame1.sample_rate_hz_);
EXPECT_EQ(AudioFrame::kNormalSpeech, frame1.speech_type_);
EXPECT_EQ(AudioFrame::kVadPassive, frame1.vad_activity_);
ASSERT_EQ(kNumChannelsMono + 1, frame1.num_channels_);
for (size_t i = 0; i < (kNumChannelsMono + 1) * (kSamplesPerChannel + 1);
++i) {
EXPECT_EQ(samples2[i], frame1.data()[i]);
}
EXPECT_FALSE(frame1.absolute_capture_timestamp_ms());
EXPECT_EQ(frame2_channel_layout, frame1.channel_layout());
EXPECT_EQ(kTimestamp, frame2.timestamp_);
ASSERT_EQ(kSamplesPerChannel, frame2.samples_per_channel_);
EXPECT_EQ(kSampleRateHz, frame2.sample_rate_hz_);
EXPECT_EQ(AudioFrame::kPLC, frame2.speech_type_);
EXPECT_EQ(AudioFrame::kVadActive, frame2.vad_activity_);
ASSERT_EQ(kNumChannelsMono, frame2.num_channels_);
for (size_t i = 0; i < kNumChannelsMono * kSamplesPerChannel; ++i) {
EXPECT_EQ(samples1[i], frame2.data()[i]);
}
EXPECT_EQ(12345678, frame2.absolute_capture_timestamp_ms());
EXPECT_EQ(frame1_channel_layout, frame2.channel_layout());
}
} // namespace webrtc

View File

@ -21,19 +21,29 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
cfg.delay.log_warning_on_delay_changes = true;
cfg.filter.refined.error_floor = 2.f;
cfg.filter.coarse_initial.length_blocks = 3u;
cfg.filter.high_pass_filter_echo_reference =
!cfg.filter.high_pass_filter_echo_reference;
cfg.comfort_noise.noise_floor_dbfs = 100.f;
cfg.echo_model.model_reverb_in_nonlinear_mode = false;
cfg.suppressor.normal_tuning.mask_hf.enr_suppress = .5f;
cfg.suppressor.subband_nearend_detection.nearend_average_blocks = 3;
cfg.suppressor.subband_nearend_detection.subband1 = {1, 3};
cfg.suppressor.subband_nearend_detection.subband1 = {4, 5};
cfg.suppressor.subband_nearend_detection.nearend_threshold = 2.f;
cfg.suppressor.subband_nearend_detection.snr_threshold = 100.f;
cfg.multi_channel.detect_stereo_content =
!cfg.multi_channel.detect_stereo_content;
cfg.multi_channel.stereo_detection_threshold += 1.0f;
cfg.multi_channel.stereo_detection_timeout_threshold_seconds += 1;
cfg.multi_channel.stereo_detection_hysteresis_seconds += 1;
std::string json_string = Aec3ConfigToJsonString(cfg);
EchoCanceller3Config cfg_transformed = Aec3ConfigFromJsonString(json_string);
// Expect unchanged values to remain default.
EXPECT_EQ(cfg.ep_strength.default_len,
cfg_transformed.ep_strength.default_len);
EXPECT_EQ(cfg.ep_strength.nearend_len,
cfg_transformed.ep_strength.nearend_len);
EXPECT_EQ(cfg.suppressor.normal_tuning.mask_lf.enr_suppress,
cfg_transformed.suppressor.normal_tuning.mask_lf.enr_suppress);
@ -46,8 +56,12 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
cfg_transformed.filter.coarse_initial.length_blocks);
EXPECT_EQ(cfg.filter.refined.error_floor,
cfg_transformed.filter.refined.error_floor);
EXPECT_EQ(cfg.filter.high_pass_filter_echo_reference,
cfg_transformed.filter.high_pass_filter_echo_reference);
EXPECT_EQ(cfg.comfort_noise.noise_floor_dbfs,
cfg_transformed.comfort_noise.noise_floor_dbfs);
EXPECT_EQ(cfg.echo_model.model_reverb_in_nonlinear_mode,
cfg_transformed.echo_model.model_reverb_in_nonlinear_mode);
EXPECT_EQ(cfg.suppressor.normal_tuning.mask_hf.enr_suppress,
cfg_transformed.suppressor.normal_tuning.mask_hf.enr_suppress);
EXPECT_EQ(cfg.suppressor.subband_nearend_detection.nearend_average_blocks,
@ -66,5 +80,14 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
cfg_transformed.suppressor.subband_nearend_detection.nearend_threshold);
EXPECT_EQ(cfg.suppressor.subband_nearend_detection.snr_threshold,
cfg_transformed.suppressor.subband_nearend_detection.snr_threshold);
EXPECT_EQ(cfg.multi_channel.detect_stereo_content,
cfg_transformed.multi_channel.detect_stereo_content);
EXPECT_EQ(cfg.multi_channel.stereo_detection_threshold,
cfg_transformed.multi_channel.stereo_detection_threshold);
EXPECT_EQ(
cfg.multi_channel.stereo_detection_timeout_threshold_seconds,
cfg_transformed.multi_channel.stereo_detection_timeout_threshold_seconds);
EXPECT_EQ(cfg.multi_channel.stereo_detection_hysteresis_seconds,
cfg_transformed.multi_channel.stereo_detection_hysteresis_seconds);
}
} // namespace webrtc

View File

@ -31,15 +31,19 @@ rtc_library("audio_codecs_api") {
deps = [
"..:array_view",
"..:bitrate_allocation",
"..:make_ref_counted",
"..:scoped_refptr",
"../../api:field_trials_view",
"../../rtc_base:buffer",
"../../rtc_base:checks",
"../../rtc_base:deprecation",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:event_tracer",
"../../rtc_base:refcount",
"../../rtc_base:sanitizer",
"../../rtc_base/system:rtc_export",
"../units:time_delta",
]
absl_deps = [
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
@ -55,11 +59,9 @@ rtc_library("builtin_audio_decoder_factory") {
deps = [
":audio_codecs_api",
"..:scoped_refptr",
"../../rtc_base:rtc_base_approved",
"L16:audio_decoder_L16",
"g711:audio_decoder_g711",
"g722:audio_decoder_g722",
"isac:audio_decoder_isac",
]
defines = []
if (rtc_include_ilbc) {
@ -89,11 +91,9 @@ rtc_library("builtin_audio_encoder_factory") {
deps = [
":audio_codecs_api",
"..:scoped_refptr",
"../../rtc_base:rtc_base_approved",
"L16:audio_encoder_L16",
"g711:audio_encoder_g711",
"g722:audio_encoder_g722",
"isac:audio_encoder_isac",
]
defines = []
if (rtc_include_ilbc) {
@ -123,7 +123,6 @@ rtc_library("opus_audio_decoder_factory") {
deps = [
":audio_codecs_api",
"..:scoped_refptr",
"../../rtc_base:rtc_base_approved",
"opus:audio_decoder_multiopus",
"opus:audio_decoder_opus",
]
@ -139,7 +138,6 @@ rtc_library("opus_audio_encoder_factory") {
deps = [
":audio_codecs_api",
"..:scoped_refptr",
"../../rtc_base:rtc_base_approved",
"opus:audio_encoder_multiopus",
"opus:audio_encoder_opus",
]

View File

@ -21,9 +21,11 @@ rtc_library("audio_encoder_L16") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:pcm16b",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base:safe_minmax",
"../../../rtc_base:stringutils",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
@ -41,8 +43,9 @@ rtc_library("audio_decoder_L16") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:pcm16b",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [

View File

@ -24,9 +24,10 @@ absl::optional<AudioDecoderL16::Config> AudioDecoderL16::SdpToConfig(
Config config;
config.sample_rate_hz = format.clockrate_hz;
config.num_channels = rtc::checked_cast<int>(format.num_channels);
return absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()
? absl::optional<Config>(config)
: absl::nullopt;
if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
return config;
}
return absl::nullopt;
}
void AudioDecoderL16::AppendSupportedDecoders(
@ -36,10 +37,13 @@ void AudioDecoderL16::AppendSupportedDecoders(
std::unique_ptr<AudioDecoder> AudioDecoderL16::MakeAudioDecoder(
const Config& config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
return config.IsOk() ? std::make_unique<AudioDecoderPcm16B>(
config.sample_rate_hz, config.num_channels)
: nullptr;
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
return nullptr;
}
return std::make_unique<AudioDecoderPcm16B>(config.sample_rate_hz,
config.num_channels);
}
} // namespace webrtc

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -29,7 +30,8 @@ struct RTC_EXPORT AudioDecoderL16 {
bool IsOk() const {
return (sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
sample_rate_hz == 32000 || sample_rate_hz == 48000) &&
num_channels >= 1;
(num_channels >= 1 &&
num_channels <= AudioDecoder::kMaxNumberOfChannels);
}
int sample_rate_hz = 8000;
int num_channels = 1;
@ -38,7 +40,8 @@ struct RTC_EXPORT AudioDecoderL16 {
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const Config& config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -24,6 +24,7 @@ namespace webrtc {
absl::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
const SdpAudioFormat& format) {
if (!rtc::IsValueInRangeForNumericType<int>(format.num_channels)) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
Config config;
@ -36,9 +37,10 @@ absl::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
config.frame_size_ms = rtc::SafeClamp(10 * (*ptime / 10), 10, 60);
}
}
return absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()
? absl::optional<Config>(config)
: absl::nullopt;
if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
return config;
}
return absl::nullopt;
}
void AudioEncoderL16::AppendSupportedEncoders(
@ -57,13 +59,17 @@ AudioCodecInfo AudioEncoderL16::QueryAudioEncoder(
std::unique_ptr<AudioEncoder> AudioEncoderL16::MakeAudioEncoder(
const AudioEncoderL16::Config& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
AudioEncoderPcm16B::Config c;
c.sample_rate_hz = config.sample_rate_hz;
c.num_channels = config.num_channels;
c.frame_size_ms = config.frame_size_ms;
c.payload_type = payload_type;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioEncoderPcm16B>(c);
}

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -29,7 +30,9 @@ struct RTC_EXPORT AudioEncoderL16 {
bool IsOk() const {
return (sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
sample_rate_hz == 32000 || sample_rate_hz == 48000) &&
num_channels >= 1 && frame_size_ms > 0 && frame_size_ms <= 120 &&
num_channels >= 1 &&
num_channels <= AudioEncoder::kMaxNumberOfChannels &&
frame_size_ms > 0 && frame_size_ms <= 120 &&
frame_size_ms % 10 == 0;
}
int sample_rate_hz = 8000;
@ -42,7 +45,8 @@ struct RTC_EXPORT AudioEncoderL16 {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -1 +1,3 @@
kwiberg@webrtc.org
alessiob@webrtc.org
henrik.lundin@webrtc.org
jakobi@webrtc.org

View File

@ -10,7 +10,6 @@
#include "api/audio_codecs/audio_decoder.h"
#include <assert.h>
#include <memory>
#include <utility>
@ -162,9 +161,10 @@ AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
case 2:
return kComfortNoise;
default:
assert(false);
RTC_DCHECK_NOTREACHED();
return kSpeech;
}
}
constexpr int AudioDecoder::kMaxNumberOfChannels;
} // namespace webrtc

View File

@ -20,7 +20,6 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "rtc_base/buffer.h"
#include "rtc_base/constructor_magic.h"
namespace webrtc {
@ -37,6 +36,9 @@ class AudioDecoder {
AudioDecoder() = default;
virtual ~AudioDecoder() = default;
AudioDecoder(const AudioDecoder&) = delete;
AudioDecoder& operator=(const AudioDecoder&) = delete;
class EncodedAudioFrame {
public:
struct DecodeResult {
@ -53,8 +55,8 @@ class AudioDecoder {
// Returns true if this packet contains DTX.
virtual bool IsDtxPacket() const;
// Decodes this frame of audio and writes the result in |decoded|.
// |decoded| must be large enough to store as many samples as indicated by a
// Decodes this frame of audio and writes the result in `decoded`.
// `decoded` must be large enough to store as many samples as indicated by a
// call to Duration() . On success, returns an absl::optional containing the
// total number of samples across all channels, as well as whether the
// decoder produced comfort noise or speech. On failure, returns an empty
@ -85,8 +87,8 @@ class AudioDecoder {
// Let the decoder parse this payload and prepare zero or more decodable
// frames. Each frame must be between 10 ms and 120 ms long. The caller must
// ensure that the AudioDecoder object outlives any frame objects returned by
// this call. The decoder is free to swap or move the data from the |payload|
// buffer. |timestamp| is the input timestamp, in samples, corresponding to
// this call. The decoder is free to swap or move the data from the `payload`
// buffer. `timestamp` is the input timestamp, in samples, corresponding to
// the start of the payload.
virtual std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
uint32_t timestamp);
@ -95,12 +97,12 @@ class AudioDecoder {
// obsolete; callers should call ParsePayload instead. For now, subclasses
// must still implement DecodeInternal.
// Decodes |encode_len| bytes from |encoded| and writes the result in
// |decoded|. The maximum bytes allowed to be written into |decoded| is
// |max_decoded_bytes|. Returns the total number of samples across all
// channels. If the decoder produced comfort noise, |speech_type|
// Decodes `encode_len` bytes from `encoded` and writes the result in
// `decoded`. The maximum bytes allowed to be written into `decoded` is
// `max_decoded_bytes`. Returns the total number of samples across all
// channels. If the decoder produced comfort noise, `speech_type`
// is set to kComfortNoise, otherwise it is kSpeech. The desired output
// sample rate is provided in |sample_rate_hz|, which must be valid for the
// sample rate is provided in `sample_rate_hz`, which must be valid for the
// codec at hand.
int Decode(const uint8_t* encoded,
size_t encoded_len,
@ -123,11 +125,11 @@ class AudioDecoder {
// Calls the packet-loss concealment of the decoder to update the state after
// one or several lost packets. The caller has to make sure that the
// memory allocated in |decoded| should accommodate |num_frames| frames.
// memory allocated in `decoded` should accommodate `num_frames` frames.
virtual size_t DecodePlc(size_t num_frames, int16_t* decoded);
// Asks the decoder to generate packet-loss concealment and append it to the
// end of |concealment_audio|. The concealment audio should be in
// end of `concealment_audio`. The concealment audio should be in
// channel-interleaved format, with as many channels as the last decoded
// packet produced. The implementation must produce at least
// requested_samples_per_channel, or nothing at all. This is a signal to the
@ -136,7 +138,7 @@ class AudioDecoder {
// with the decoded audio on either side of the concealment.
// Note: The default implementation of GeneratePlc will be deleted soon. All
// implementations must provide their own, which can be a simple as a no-op.
// TODO(bugs.webrtc.org/9676): Remove default impementation.
// TODO(bugs.webrtc.org/9676): Remove default implementation.
virtual void GeneratePlc(size_t requested_samples_per_channel,
rtc::BufferT<int16_t>* concealment_audio);
@ -146,19 +148,19 @@ class AudioDecoder {
// Returns the last error code from the decoder.
virtual int ErrorCode();
// Returns the duration in samples-per-channel of the payload in |encoded|
// which is |encoded_len| bytes long. Returns kNotImplemented if no duration
// Returns the duration in samples-per-channel of the payload in `encoded`
// which is `encoded_len` bytes long. Returns kNotImplemented if no duration
// estimate is available, or -1 in case of an error.
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
// Returns the duration in samples-per-channel of the redandant payload in
// |encoded| which is |encoded_len| bytes long. Returns kNotImplemented if no
// `encoded` which is `encoded_len` bytes long. Returns kNotImplemented if no
// duration estimate is available, or -1 in case of an error.
virtual int PacketDurationRedundant(const uint8_t* encoded,
size_t encoded_len) const;
// Detects whether a packet has forward error correction. The packet is
// comprised of the samples in |encoded| which is |encoded_len| bytes long.
// comprised of the samples in `encoded` which is `encoded_len` bytes long.
// Returns true if the packet has FEC and false otherwise.
virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;
@ -170,6 +172,9 @@ class AudioDecoder {
// during the lifetime of the decoder.
virtual size_t Channels() const = 0;
// The maximum number of audio channels supported by WebRTC decoders.
static constexpr int kMaxNumberOfChannels = 24;
protected:
static SpeechType ConvertSpeechType(int16_t type);
@ -184,9 +189,6 @@ class AudioDecoder {
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
private:
RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoder);
};
} // namespace webrtc

View File

@ -38,6 +38,8 @@ class AudioDecoderFactory : public rtc::RefCountInterface {
// communication between the AudioEncoder and AudioDecoder instances, which is
// needed for some codecs with built-in bandwidth adaptation.)
//
// Returns null if the format isn't supported.
//
// Note: Implementations need to be robust against combinations other than
// one encoder, one decoder getting the same ID; such decoders must still
// work.

View File

@ -15,8 +15,9 @@
#include <vector>
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/field_trials_view.h"
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "rtc_base/ref_counted_object.h"
namespace webrtc {
@ -32,7 +33,8 @@ struct Helper<> {
static bool IsSupportedDecoder(const SdpAudioFormat& format) { return false; }
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id) {
absl::optional<AudioCodecPairId> codec_pair_id,
const FieldTrialsView* field_trials) {
return nullptr;
}
};
@ -55,16 +57,22 @@ struct Helper<T, Ts...> {
}
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id) {
absl::optional<AudioCodecPairId> codec_pair_id,
const FieldTrialsView* field_trials) {
auto opt_config = T::SdpToConfig(format);
return opt_config ? T::MakeAudioDecoder(*opt_config, codec_pair_id)
: Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id);
: Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id,
field_trials);
}
};
template <typename... Ts>
class AudioDecoderFactoryT : public AudioDecoderFactory {
public:
explicit AudioDecoderFactoryT(const FieldTrialsView* field_trials) {
field_trials_ = field_trials;
}
std::vector<AudioCodecSpec> GetSupportedDecoders() override {
std::vector<AudioCodecSpec> specs;
Helper<Ts...>::AppendSupportedDecoders(&specs);
@ -78,8 +86,11 @@ class AudioDecoderFactoryT : public AudioDecoderFactory {
std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id) override {
return Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id);
return Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id,
field_trials_);
}
const FieldTrialsView* field_trials_;
};
} // namespace audio_decoder_factory_template_impl
@ -89,8 +100,8 @@ class AudioDecoderFactoryT : public AudioDecoderFactory {
// Each decoder type is given as a template argument to the function; it should
// be a struct with the following static member functions:
//
// // Converts |audio_format| to a ConfigType instance. Returns an empty
// // optional if |audio_format| doesn't correctly specify a decoder of our
// // Converts `audio_format` to a ConfigType instance. Returns an empty
// // optional if `audio_format` doesn't correctly specify a decoder of our
// // type.
// absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
//
@ -115,7 +126,8 @@ class AudioDecoderFactoryT : public AudioDecoderFactory {
// TODO(kwiberg): Point at CreateBuiltinAudioDecoderFactory() for an example of
// how it is used.
template <typename... Ts>
rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory() {
rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory(
const FieldTrialsView* field_trials = nullptr) {
// There's no technical reason we couldn't allow zero template parameters,
// but such a factory couldn't create any decoders, and callers can do this
// by mistake by simply forgetting the <> altogether. So we forbid it in
@ -123,9 +135,9 @@ rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory() {
static_assert(sizeof...(Ts) >= 1,
"Caller must give at least one template parameter");
return rtc::scoped_refptr<AudioDecoderFactory>(
new rtc::RefCountedObject<
audio_decoder_factory_template_impl::AudioDecoderFactoryT<Ts...>>());
return rtc::make_ref_counted<
audio_decoder_factory_template_impl::AudioDecoderFactoryT<Ts...>>(
field_trials);
}
} // namespace webrtc

View File

@ -83,7 +83,7 @@ void AudioEncoder::OnReceivedUplinkPacketLossFraction(
void AudioEncoder::OnReceivedUplinkRecoverablePacketLossFraction(
float uplink_recoverable_packet_loss_fraction) {
RTC_NOTREACHED();
RTC_DCHECK_NOTREACHED();
}
void AudioEncoder::OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) {
@ -110,4 +110,5 @@ ANAStats AudioEncoder::GetANAStats() const {
return ANAStats();
}
constexpr int AudioEncoder::kMaxNumberOfChannels;
} // namespace webrtc

View File

@ -16,12 +16,12 @@
#include <utility>
#include <vector>
#include "absl/base/attributes.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/call/bitrate_allocation.h"
#include "api/units/time_delta.h"
#include "rtc_base/buffer.h"
#include "rtc_base/deprecation.h"
namespace webrtc {
@ -95,13 +95,13 @@ class AudioEncoder {
// This is the main struct for auxiliary encoding information. Each encoded
// packet should be accompanied by one EncodedInfo struct, containing the
// total number of |encoded_bytes|, the |encoded_timestamp| and the
// |payload_type|. If the packet contains redundant encodings, the |redundant|
// total number of `encoded_bytes`, the `encoded_timestamp` and the
// `payload_type`. If the packet contains redundant encodings, the `redundant`
// vector will be populated with EncodedInfoLeaf structs. Each struct in the
// vector represents one encoding; the order of structs in the vector is the
// same as the order in which the actual payloads are written to the byte
// stream. When EncoderInfoLeaf structs are present in the vector, the main
// struct's |encoded_bytes| will be the sum of all the |encoded_bytes| in the
// struct's `encoded_bytes` will be the sum of all the `encoded_bytes` in the
// vector.
struct EncodedInfo : public EncodedInfoLeaf {
EncodedInfo();
@ -143,7 +143,7 @@ class AudioEncoder {
// Accepts one 10 ms block of input audio (i.e., SampleRateHz() / 100 *
// NumChannels() samples). Multi-channel audio must be sample-interleaved.
// The encoder appends zero or more bytes of output to |encoded| and returns
// The encoder appends zero or more bytes of output to `encoded` and returns
// additional encoding information. Encode() checks some preconditions, calls
// EncodeImpl() which does the actual work, and then checks some
// postconditions.
@ -182,12 +182,11 @@ class AudioEncoder {
// implementation does nothing.
virtual void SetMaxPlaybackRate(int frequency_hz);
// This is to be deprecated. Please use |OnReceivedTargetAudioBitrate|
// instead.
// Tells the encoder what average bitrate we'd like it to produce. The
// encoder is free to adjust or disregard the given bitrate (the default
// implementation does the latter).
RTC_DEPRECATED virtual void SetTargetBitrate(int target_bps);
ABSL_DEPRECATED("Use OnReceivedTargetAudioBitrate instead")
virtual void SetTargetBitrate(int target_bps);
// Causes this encoder to let go of any other encoders it contains, and
// returns a pointer to an array where they are stored (which is required to
@ -206,11 +205,12 @@ class AudioEncoder {
virtual void DisableAudioNetworkAdaptor();
// Provides uplink packet loss fraction to this encoder to allow it to adapt.
// |uplink_packet_loss_fraction| is in the range [0.0, 1.0].
// `uplink_packet_loss_fraction` is in the range [0.0, 1.0].
virtual void OnReceivedUplinkPacketLossFraction(
float uplink_packet_loss_fraction);
RTC_DEPRECATED virtual void OnReceivedUplinkRecoverablePacketLossFraction(
ABSL_DEPRECATED("")
virtual void OnReceivedUplinkRecoverablePacketLossFraction(
float uplink_recoverable_packet_loss_fraction);
// Provides target audio bitrate to this encoder to allow it to adapt.
@ -246,6 +246,9 @@ class AudioEncoder {
virtual absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
const = 0;
// The maximum number of audio channels supported by WebRTC encoders.
static constexpr int kMaxNumberOfChannels = 24;
protected:
// Subclasses implement this to perform the actual encoding. Called by
// Encode().

View File

@ -44,6 +44,8 @@ class AudioEncoderFactory : public rtc::RefCountInterface {
// communication between the AudioEncoder and AudioDecoder instances, which is
// needed for some codecs with built-in bandwidth adaptation.)
//
// Returns null if the format isn't supported.
//
// Note: Implementations need to be robust against combinations other than
// one encoder, one decoder getting the same ID; such encoders must still
// work.

View File

@ -15,8 +15,9 @@
#include <vector>
#include "api/audio_codecs/audio_encoder_factory.h"
#include "api/field_trials_view.h"
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "rtc_base/ref_counted_object.h"
namespace webrtc {
@ -36,7 +37,8 @@ struct Helper<> {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
int payload_type,
const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id) {
absl::optional<AudioCodecPairId> codec_pair_id,
const FieldTrialsView* field_trials) {
return nullptr;
}
};
@ -63,13 +65,14 @@ struct Helper<T, Ts...> {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
int payload_type,
const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id) {
absl::optional<AudioCodecPairId> codec_pair_id,
const FieldTrialsView* field_trials) {
auto opt_config = T::SdpToConfig(format);
if (opt_config) {
return T::MakeAudioEncoder(*opt_config, payload_type, codec_pair_id);
} else {
return Helper<Ts...>::MakeAudioEncoder(payload_type, format,
codec_pair_id);
codec_pair_id, field_trials);
}
}
};
@ -77,6 +80,10 @@ struct Helper<T, Ts...> {
template <typename... Ts>
class AudioEncoderFactoryT : public AudioEncoderFactory {
public:
explicit AudioEncoderFactoryT(const FieldTrialsView* field_trials) {
field_trials_ = field_trials;
}
std::vector<AudioCodecSpec> GetSupportedEncoders() override {
std::vector<AudioCodecSpec> specs;
Helper<Ts...>::AppendSupportedEncoders(&specs);
@ -92,8 +99,11 @@ class AudioEncoderFactoryT : public AudioEncoderFactory {
int payload_type,
const SdpAudioFormat& format,
absl::optional<AudioCodecPairId> codec_pair_id) override {
return Helper<Ts...>::MakeAudioEncoder(payload_type, format, codec_pair_id);
return Helper<Ts...>::MakeAudioEncoder(payload_type, format, codec_pair_id,
field_trials_);
}
const FieldTrialsView* field_trials_;
};
} // namespace audio_encoder_factory_template_impl
@ -103,8 +113,8 @@ class AudioEncoderFactoryT : public AudioEncoderFactory {
// Each encoder type is given as a template argument to the function; it should
// be a struct with the following static member functions:
//
// // Converts |audio_format| to a ConfigType instance. Returns an empty
// // optional if |audio_format| doesn't correctly specify an encoder of our
// // Converts `audio_format` to a ConfigType instance. Returns an empty
// // optional if `audio_format` doesn't correctly specify an encoder of our
// // type.
// absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
//
@ -134,7 +144,8 @@ class AudioEncoderFactoryT : public AudioEncoderFactory {
// TODO(kwiberg): Point at CreateBuiltinAudioEncoderFactory() for an example of
// how it is used.
template <typename... Ts>
rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory() {
rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory(
const FieldTrialsView* field_trials = nullptr) {
// There's no technical reason we couldn't allow zero template parameters,
// but such a factory couldn't create any encoders, and callers can do this
// by mistake by simply forgetting the <> altogether. So we forbid it in
@ -142,9 +153,9 @@ rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory() {
static_assert(sizeof...(Ts) >= 1,
"Caller must give at least one template parameter");
return rtc::scoped_refptr<AudioEncoderFactory>(
new rtc::RefCountedObject<
audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>());
return rtc::make_ref_counted<
audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>(
field_trials);
}
} // namespace webrtc

View File

@ -39,7 +39,7 @@ struct RTC_EXPORT SdpAudioFormat {
Parameters&& param);
~SdpAudioFormat();
// Returns true if this format is compatible with |o|. In SDP terminology:
// Returns true if this format is compatible with `o`. In SDP terminology:
// would it represent the same codec between an offer and an answer? As
// opposed to operator==, this method disregards codec parameters.
bool Matches(const SdpAudioFormat& o) const;

View File

@ -20,7 +20,6 @@
#if WEBRTC_USE_BUILTIN_ILBC
#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h" // nogncheck
#endif
#include "api/audio_codecs/isac/audio_decoder_isac.h"
#if WEBRTC_USE_BUILTIN_OPUS
#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
#include "api/audio_codecs/opus/audio_decoder_opus.h" // nogncheck
@ -57,7 +56,7 @@ rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>,
#endif
AudioDecoderIsac, AudioDecoderG722,
AudioDecoderG722,
#if WEBRTC_USE_BUILTIN_ILBC
AudioDecoderIlbc,

View File

@ -20,7 +20,6 @@
#if WEBRTC_USE_BUILTIN_ILBC
#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h" // nogncheck
#endif
#include "api/audio_codecs/isac/audio_encoder_isac.h"
#if WEBRTC_USE_BUILTIN_OPUS
#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h" // nogncheck
@ -47,8 +46,10 @@ struct NotAdvertised {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
return T::MakeAudioEncoder(config, payload_type, codec_pair_id);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr) {
return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
field_trials);
}
};
@ -61,7 +62,7 @@ rtc::scoped_refptr<AudioEncoderFactory> CreateBuiltinAudioEncoderFactory() {
AudioEncoderOpus, NotAdvertised<AudioEncoderMultiChannelOpus>,
#endif
AudioEncoderIsac, AudioEncoderG722,
AudioEncoderG722,
#if WEBRTC_USE_BUILTIN_ILBC
AudioEncoderIlbc,

View File

@ -21,9 +21,11 @@ rtc_library("audio_encoder_g711") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:g711",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base:safe_minmax",
"../../../rtc_base:stringutils",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
@ -41,8 +43,9 @@ rtc_library("audio_decoder_g711") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:g711",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [

View File

@ -28,7 +28,10 @@ absl::optional<AudioDecoderG711::Config> AudioDecoderG711::SdpToConfig(
Config config;
config.type = is_pcmu ? Config::Type::kPcmU : Config::Type::kPcmA;
config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
RTC_DCHECK(config.IsOk());
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
} else {
return absl::nullopt;
@ -44,14 +47,19 @@ void AudioDecoderG711::AppendSupportedDecoders(
std::unique_ptr<AudioDecoder> AudioDecoderG711::MakeAudioDecoder(
const Config& config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
switch (config.type) {
case Config::Type::kPcmU:
return std::make_unique<AudioDecoderPcmU>(config.num_channels);
case Config::Type::kPcmA:
return std::make_unique<AudioDecoderPcmA>(config.num_channels);
default:
RTC_DCHECK_NOTREACHED();
return nullptr;
}
}

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -28,7 +29,9 @@ struct RTC_EXPORT AudioDecoderG711 {
struct Config {
enum class Type { kPcmU, kPcmA };
bool IsOk() const {
return (type == Type::kPcmU || type == Type::kPcmA) && num_channels >= 1;
return (type == Type::kPcmU || type == Type::kPcmA) &&
num_channels >= 1 &&
num_channels <= AudioDecoder::kMaxNumberOfChannels;
}
Type type;
int num_channels;
@ -37,7 +40,8 @@ struct RTC_EXPORT AudioDecoderG711 {
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const Config& config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -38,7 +38,10 @@ absl::optional<AudioEncoderG711::Config> AudioEncoderG711::SdpToConfig(
config.frame_size_ms = rtc::SafeClamp(10 * (*ptime / 10), 10, 60);
}
}
RTC_DCHECK(config.IsOk());
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
} else {
return absl::nullopt;
@ -61,8 +64,12 @@ AudioCodecInfo AudioEncoderG711::QueryAudioEncoder(const Config& config) {
std::unique_ptr<AudioEncoder> AudioEncoderG711::MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
switch (config.type) {
case Config::Type::kPcmU: {
AudioEncoderPcmU::Config impl_config;
@ -79,6 +86,7 @@ std::unique_ptr<AudioEncoder> AudioEncoderG711::MakeAudioEncoder(
return std::make_unique<AudioEncoderPcmA>(impl_config);
}
default: {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
}

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -29,7 +30,9 @@ struct RTC_EXPORT AudioEncoderG711 {
enum class Type { kPcmU, kPcmA };
bool IsOk() const {
return (type == Type::kPcmU || type == Type::kPcmA) &&
frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1;
frame_size_ms > 0 && frame_size_ms % 10 == 0 &&
num_channels >= 1 &&
num_channels <= AudioEncoder::kMaxNumberOfChannels;
}
Type type = Type::kPcmU;
int num_channels = 1;
@ -42,7 +45,8 @@ struct RTC_EXPORT AudioEncoderG711 {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -15,6 +15,7 @@ if (is_android) {
rtc_source_set("audio_encoder_g722_config") {
visibility = [ "*" ]
sources = [ "audio_encoder_g722_config.h" ]
deps = [ "..:audio_codecs_api" ]
}
rtc_library("audio_encoder_g722") {
@ -27,9 +28,11 @@ rtc_library("audio_encoder_g722") {
deps = [
":audio_encoder_g722_config",
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:g722",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base:safe_minmax",
"../../../rtc_base:stringutils",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
@ -47,8 +50,9 @@ rtc_library("audio_decoder_g722") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:g722",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [

View File

@ -21,12 +21,12 @@ namespace webrtc {
absl::optional<AudioDecoderG722::Config> AudioDecoderG722::SdpToConfig(
const SdpAudioFormat& format) {
return absl::EqualsIgnoreCase(format.name, "G722") &&
format.clockrate_hz == 8000 &&
(format.num_channels == 1 || format.num_channels == 2)
? absl::optional<Config>(
Config{rtc::dchecked_cast<int>(format.num_channels)})
: absl::nullopt;
if (absl::EqualsIgnoreCase(format.name, "G722") &&
format.clockrate_hz == 8000 &&
(format.num_channels == 1 || format.num_channels == 2)) {
return Config{rtc::dchecked_cast<int>(format.num_channels)};
}
return absl::nullopt;
}
void AudioDecoderG722::AppendSupportedDecoders(
@ -36,13 +36,19 @@ void AudioDecoderG722::AppendSupportedDecoders(
std::unique_ptr<AudioDecoder> AudioDecoderG722::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
switch (config.num_channels) {
case 1:
return std::make_unique<AudioDecoderG722Impl>();
case 2:
return std::make_unique<AudioDecoderG722StereoImpl>();
default:
RTC_DCHECK_NOTREACHED();
return nullptr;
}
}

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -33,7 +34,8 @@ struct RTC_EXPORT AudioDecoderG722 {
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -38,8 +38,11 @@ absl::optional<AudioEncoderG722Config> AudioEncoderG722::SdpToConfig(
config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 10, 60);
}
}
return config.IsOk() ? absl::optional<AudioEncoderG722Config>(config)
: absl::nullopt;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
}
void AudioEncoderG722::AppendSupportedEncoders(
@ -59,8 +62,12 @@ AudioCodecInfo AudioEncoderG722::QueryAudioEncoder(
std::unique_ptr<AudioEncoder> AudioEncoderG722::MakeAudioEncoder(
const AudioEncoderG722Config& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioEncoderG722Impl>(config, payload_type);
}

View File

@ -19,6 +19,7 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/audio_codecs/g722/audio_encoder_g722_config.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -34,7 +35,8 @@ struct RTC_EXPORT AudioEncoderG722 {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const AudioEncoderG722Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -11,11 +11,14 @@
#ifndef API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
#define API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
#include "api/audio_codecs/audio_encoder.h"
namespace webrtc {
struct AudioEncoderG722Config {
bool IsOk() const {
return frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1;
return frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1 &&
num_channels <= AudioEncoder::kMaxNumberOfChannels;
}
int frame_size_ms = 20;
int num_channels = 1;

View File

@ -27,9 +27,11 @@ rtc_library("audio_encoder_ilbc") {
deps = [
":audio_encoder_ilbc_config",
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:ilbc",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_conversions",
"../../../rtc_base:safe_minmax",
"../../../rtc_base:stringutils",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
@ -46,8 +48,8 @@ rtc_library("audio_decoder_ilbc") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:ilbc",
"../../../rtc_base:rtc_base_approved",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",

View File

@ -20,10 +20,11 @@ namespace webrtc {
absl::optional<AudioDecoderIlbc::Config> AudioDecoderIlbc::SdpToConfig(
const SdpAudioFormat& format) {
return absl::EqualsIgnoreCase(format.name, "ILBC") &&
format.clockrate_hz == 8000 && format.num_channels == 1
? absl::optional<Config>(Config())
: absl::nullopt;
if (absl::EqualsIgnoreCase(format.name, "ILBC") &&
format.clockrate_hz == 8000 && format.num_channels == 1) {
return Config();
}
return absl::nullopt;
}
void AudioDecoderIlbc::AppendSupportedDecoders(
@ -33,7 +34,8 @@ void AudioDecoderIlbc::AppendSupportedDecoders(
std::unique_ptr<AudioDecoder> AudioDecoderIlbc::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
return std::make_unique<AudioDecoderIlbcImpl>();
}

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
namespace webrtc {
@ -29,7 +30,8 @@ struct AudioDecoderIlbc {
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -32,7 +32,7 @@ int GetIlbcBitrate(int ptime) {
// 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
return 13333;
default:
FATAL();
RTC_CHECK_NOTREACHED();
}
}
} // namespace
@ -53,8 +53,11 @@ absl::optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 20, 60);
}
}
return config.IsOk() ? absl::optional<AudioEncoderIlbcConfig>(config)
: absl::nullopt;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
}
void AudioEncoderIlbc::AppendSupportedEncoders(
@ -73,8 +76,12 @@ AudioCodecInfo AudioEncoderIlbc::QueryAudioEncoder(
std::unique_ptr<AudioEncoder> AudioEncoderIlbc::MakeAudioEncoder(
const AudioEncoderIlbcConfig& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioEncoderIlbcImpl>(config, payload_type);
}

View File

@ -19,6 +19,7 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/audio_codecs/ilbc/audio_encoder_ilbc_config.h"
#include "api/field_trials_view.h"
namespace webrtc {
@ -33,7 +34,8 @@ struct AudioEncoderIlbc {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const AudioEncoderIlbcConfig& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -1,133 +0,0 @@
# Copyright (c) 2017 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")
if (is_android) {
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
}
# The targets with _fix and _float suffixes unconditionally use the
# fixed-point and floating-point iSAC implementations, respectively.
# The targets without suffixes pick one of the implementations based
# on cleverly chosen criteria.
rtc_source_set("audio_encoder_isac") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
public = [ "audio_encoder_isac.h" ]
public_configs = [ ":isac_config" ]
if (current_cpu == "arm") {
deps = [ ":audio_encoder_isac_fix" ]
} else {
deps = [ ":audio_encoder_isac_float" ]
}
}
rtc_source_set("audio_decoder_isac") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
public = [ "audio_decoder_isac.h" ]
public_configs = [ ":isac_config" ]
if (current_cpu == "arm") {
deps = [ ":audio_decoder_isac_fix" ]
} else {
deps = [ ":audio_decoder_isac_float" ]
}
}
config("isac_config") {
visibility = [ ":*" ]
if (current_cpu == "arm") {
defines = [
"WEBRTC_USE_BUILTIN_ISAC_FIX=1",
"WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
]
} else {
defines = [
"WEBRTC_USE_BUILTIN_ISAC_FIX=0",
"WEBRTC_USE_BUILTIN_ISAC_FLOAT=1",
]
}
}
rtc_library("audio_encoder_isac_fix") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_encoder_isac_fix.cc",
"audio_encoder_isac_fix.h",
]
deps = [
"..:audio_codecs_api",
"../../../modules/audio_coding:isac_fix",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("audio_decoder_isac_fix") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_decoder_isac_fix.cc",
"audio_decoder_isac_fix.h",
]
deps = [
"..:audio_codecs_api",
"../../../modules/audio_coding:isac_fix",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("audio_encoder_isac_float") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_encoder_isac_float.cc",
"audio_encoder_isac_float.h",
]
deps = [
"..:audio_codecs_api",
"../../../modules/audio_coding:isac",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("audio_decoder_isac_float") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_decoder_isac_float.cc",
"audio_decoder_isac_float.h",
]
deps = [
"..:audio_codecs_api",
"../../../modules/audio_coding:isac",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2017 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_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
#if WEBRTC_USE_BUILTIN_ISAC_FIX && !WEBRTC_USE_BUILTIN_ISAC_FLOAT
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h" // nogncheck
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT && !WEBRTC_USE_BUILTIN_ISAC_FIX
#include "api/audio_codecs/isac/audio_decoder_isac_float.h" // nogncheck
#else
#error "Must choose either fix or float"
#endif
namespace webrtc {
#if WEBRTC_USE_BUILTIN_ISAC_FIX
using AudioDecoderIsac = AudioDecoderIsacFix;
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
using AudioDecoderIsac = AudioDecoderIsacFloat;
#endif
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2017 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/audio_codecs/isac/audio_decoder_isac_fix.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"
namespace webrtc {
absl::optional<AudioDecoderIsacFix::Config> AudioDecoderIsacFix::SdpToConfig(
const SdpAudioFormat& format) {
return absl::EqualsIgnoreCase(format.name, "ISAC") &&
format.clockrate_hz == 16000 && format.num_channels == 1
? absl::optional<Config>(Config())
: absl::nullopt;
}
void AudioDecoderIsacFix::AppendSupportedDecoders(
std::vector<AudioCodecSpec>* specs) {
specs->push_back({{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}});
}
std::unique_ptr<AudioDecoder> AudioDecoderIsacFix::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
AudioDecoderIsacFixImpl::Config c;
c.sample_rate_hz = 16000;
return std::make_unique<AudioDecoderIsacFixImpl>(c);
}
} // namespace webrtc

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2017 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_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC decoder API (fixed-point implementation) for use as a template
// parameter to CreateAudioDecoderFactory<...>().
struct RTC_EXPORT AudioDecoderIsacFix {
struct Config {}; // Empty---no config values needed!
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_

View File

@ -1,48 +0,0 @@
/*
* Copyright (c) 2017 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/audio_codecs/isac/audio_decoder_isac_float.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"
namespace webrtc {
absl::optional<AudioDecoderIsacFloat::Config>
AudioDecoderIsacFloat::SdpToConfig(const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
(format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
format.num_channels == 1) {
Config config;
config.sample_rate_hz = format.clockrate_hz;
return config;
} else {
return absl::nullopt;
}
}
void AudioDecoderIsacFloat::AppendSupportedDecoders(
std::vector<AudioCodecSpec>* specs) {
specs->push_back({{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}});
specs->push_back({{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}});
}
std::unique_ptr<AudioDecoder> AudioDecoderIsacFloat::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
AudioDecoderIsacFloatImpl::Config c;
c.sample_rate_hz = config.sample_rate_hz;
return std::make_unique<AudioDecoderIsacFloatImpl>(c);
}
} // namespace webrtc

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2017 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_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC decoder API (floating-point implementation) for use as a template
// parameter to CreateAudioDecoderFactory<...>().
struct RTC_EXPORT AudioDecoderIsacFloat {
struct Config {
bool IsOk() const {
return sample_rate_hz == 16000 || sample_rate_hz == 32000;
}
int sample_rate_hz = 16000;
};
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2017 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_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
#if WEBRTC_USE_BUILTIN_ISAC_FIX && !WEBRTC_USE_BUILTIN_ISAC_FLOAT
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h" // nogncheck
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT && !WEBRTC_USE_BUILTIN_ISAC_FIX
#include "api/audio_codecs/isac/audio_encoder_isac_float.h" // nogncheck
#else
#error "Must choose either fix or float"
#endif
namespace webrtc {
#if WEBRTC_USE_BUILTIN_ISAC_FIX
using AudioEncoderIsac = AudioEncoderIsacFix;
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
using AudioEncoderIsac = AudioEncoderIsacFloat;
#endif
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_

View File

@ -1,64 +0,0 @@
/*
* Copyright (c) 2017 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/audio_codecs/isac/audio_encoder_isac_fix.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"
#include "rtc_base/string_to_number.h"
namespace webrtc {
absl::optional<AudioEncoderIsacFix::Config> AudioEncoderIsacFix::SdpToConfig(
const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
format.clockrate_hz == 16000 && format.num_channels == 1) {
Config config;
const auto ptime_iter = format.parameters.find("ptime");
if (ptime_iter != format.parameters.end()) {
const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
if (ptime && *ptime >= 60) {
config.frame_size_ms = 60;
}
}
return config;
} else {
return absl::nullopt;
}
}
void AudioEncoderIsacFix::AppendSupportedEncoders(
std::vector<AudioCodecSpec>* specs) {
const SdpAudioFormat fmt = {"ISAC", 16000, 1};
const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
specs->push_back({fmt, info});
}
AudioCodecInfo AudioEncoderIsacFix::QueryAudioEncoder(
AudioEncoderIsacFix::Config config) {
RTC_DCHECK(config.IsOk());
return {16000, 1, 32000, 10000, 32000};
}
std::unique_ptr<AudioEncoder> AudioEncoderIsacFix::MakeAudioEncoder(
AudioEncoderIsacFix::Config config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
AudioEncoderIsacFixImpl::Config c;
c.frame_size_ms = config.frame_size_ms;
c.bit_rate = config.bit_rate;
c.payload_type = payload_type;
return std::make_unique<AudioEncoderIsacFixImpl>(c);
}
} // namespace webrtc

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 2017 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_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC encoder API (fixed-point implementation) for use as a template
// parameter to CreateAudioEncoderFactory<...>().
struct RTC_EXPORT AudioEncoderIsacFix {
struct Config {
bool IsOk() const {
if (frame_size_ms != 30 && frame_size_ms != 60) {
return false;
}
if (bit_rate < 10000 || bit_rate > 32000) {
return false;
}
return true;
}
int frame_size_ms = 30;
int bit_rate = 32000; // Limit on short-term average bit rate, in bits/s.
};
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
static AudioCodecInfo QueryAudioEncoder(Config config);
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
Config config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_

View File

@ -1,77 +0,0 @@
/*
* Copyright (c) 2017 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/audio_codecs/isac/audio_encoder_isac_float.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"
#include "rtc_base/string_to_number.h"
namespace webrtc {
absl::optional<AudioEncoderIsacFloat::Config>
AudioEncoderIsacFloat::SdpToConfig(const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
(format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
format.num_channels == 1) {
Config config;
config.sample_rate_hz = format.clockrate_hz;
config.bit_rate = format.clockrate_hz == 16000 ? 32000 : 56000;
if (config.sample_rate_hz == 16000) {
// For sample rate 16 kHz, optionally use 60 ms frames, instead of the
// default 30 ms.
const auto ptime_iter = format.parameters.find("ptime");
if (ptime_iter != format.parameters.end()) {
const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
if (ptime && *ptime >= 60) {
config.frame_size_ms = 60;
}
}
}
return config;
} else {
return absl::nullopt;
}
}
void AudioEncoderIsacFloat::AppendSupportedEncoders(
std::vector<AudioCodecSpec>* specs) {
for (int sample_rate_hz : {16000, 32000}) {
const SdpAudioFormat fmt = {"ISAC", sample_rate_hz, 1};
const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
specs->push_back({fmt, info});
}
}
AudioCodecInfo AudioEncoderIsacFloat::QueryAudioEncoder(
const AudioEncoderIsacFloat::Config& config) {
RTC_DCHECK(config.IsOk());
constexpr int min_bitrate = 10000;
const int max_bitrate = config.sample_rate_hz == 16000 ? 32000 : 56000;
const int default_bitrate = max_bitrate;
return {config.sample_rate_hz, 1, default_bitrate, min_bitrate, max_bitrate};
}
std::unique_ptr<AudioEncoder> AudioEncoderIsacFloat::MakeAudioEncoder(
const AudioEncoderIsacFloat::Config& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
AudioEncoderIsacFloatImpl::Config c;
c.payload_type = payload_type;
c.sample_rate_hz = config.sample_rate_hz;
c.frame_size_ms = config.frame_size_ms;
c.bit_rate = config.bit_rate;
return std::make_unique<AudioEncoderIsacFloatImpl>(c);
}
} // namespace webrtc

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2017 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_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC encoder API (floating-point implementation) for use as a template
// parameter to CreateAudioEncoderFactory<...>().
struct RTC_EXPORT AudioEncoderIsacFloat {
struct Config {
bool IsOk() const {
switch (sample_rate_hz) {
case 16000:
if (frame_size_ms != 30 && frame_size_ms != 60) {
return false;
}
if (bit_rate < 10000 || bit_rate > 32000) {
return false;
}
return true;
case 32000:
if (frame_size_ms != 30) {
return false;
}
if (bit_rate < 10000 || bit_rate > 56000) {
return false;
}
return true;
default:
return false;
}
}
int sample_rate_hz = 16000;
int frame_size_ms = 30;
int bit_rate = 32000; // Limit on short-term average bit rate, in bits/s.
};
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
static AudioCodecInfo QueryAudioEncoder(const Config& config);
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_

View File

@ -20,10 +20,7 @@ rtc_library("audio_encoder_opus_config") {
"audio_encoder_opus_config.cc",
"audio_encoder_opus_config.h",
]
deps = [
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
deps = [ "../../../rtc_base/system:rtc_export" ]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
defines = []
if (rtc_opus_variable_complexity) {
@ -36,6 +33,7 @@ rtc_library("audio_encoder_opus_config") {
rtc_source_set("audio_decoder_opus_config") {
visibility = [ "*" ]
sources = [ "audio_decoder_multi_channel_opus_config.h" ]
deps = [ "..:audio_codecs_api" ]
}
rtc_library("audio_encoder_opus") {
@ -46,8 +44,8 @@ rtc_library("audio_encoder_opus") {
deps = [
":audio_encoder_opus_config",
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:webrtc_opus",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
@ -65,8 +63,8 @@ rtc_library("audio_decoder_opus") {
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:webrtc_opus",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
@ -82,8 +80,8 @@ rtc_library("audio_encoder_multiopus") {
sources = [ "audio_encoder_multi_channel_opus.cc" ]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:webrtc_multiopus",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
"../opus:audio_encoder_opus_config",
]
@ -100,8 +98,8 @@ rtc_library("audio_decoder_multiopus") {
deps = [
":audio_decoder_opus_config",
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:webrtc_multiopus",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [

View File

@ -64,7 +64,8 @@ void AudioDecoderMultiChannelOpus::AppendSupportedDecoders(
std::unique_ptr<AudioDecoder> AudioDecoderMultiChannelOpus::MakeAudioDecoder(
AudioDecoderMultiChannelOpusConfig config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
return AudioDecoderMultiChannelOpusImpl::MakeAudioDecoder(config);
}
} // namespace webrtc

View File

@ -19,6 +19,7 @@
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -32,7 +33,8 @@ struct RTC_EXPORT AudioDecoderMultiChannelOpus {
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
AudioDecoderMultiChannelOpusConfig config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -13,6 +13,8 @@
#include <vector>
#include "api/audio_codecs/audio_decoder.h"
namespace webrtc {
struct AudioDecoderMultiChannelOpusConfig {
// The number of channels that the decoder will output.
@ -30,7 +32,8 @@ struct AudioDecoderMultiChannelOpusConfig {
std::vector<unsigned char> channel_mapping;
bool IsOk() const {
if (num_channels < 0 || num_streams < 0 || coupled_streams < 0) {
if (num_channels < 1 || num_channels > AudioDecoder::kMaxNumberOfChannels ||
num_streams < 0 || coupled_streams < 0) {
return false;
}
if (num_streams < coupled_streams) {

View File

@ -51,7 +51,10 @@ absl::optional<AudioDecoderOpus::Config> AudioDecoderOpus::SdpToConfig(
num_channels) {
Config config;
config.num_channels = *num_channels;
RTC_DCHECK(config.IsOk());
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
} else {
return absl::nullopt;
@ -70,8 +73,12 @@ void AudioDecoderOpus::AppendSupportedDecoders(
std::unique_ptr<AudioDecoder> AudioDecoderOpus::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
RTC_DCHECK(config.IsOk());
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioDecoderOpusImpl>(config.num_channels,
config.sample_rate_hz);
}

View File

@ -18,6 +18,7 @@
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -34,7 +35,8 @@ struct RTC_EXPORT AudioDecoderOpus {
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -66,7 +66,8 @@ AudioCodecInfo AudioEncoderMultiChannelOpus::QueryAudioEncoder(
std::unique_ptr<AudioEncoder> AudioEncoderMultiChannelOpus::MakeAudioEncoder(
const AudioEncoderMultiChannelOpusConfig& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
return AudioEncoderMultiChannelOpusImpl::MakeAudioEncoder(config,
payload_type);
}

View File

@ -19,6 +19,7 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -33,7 +34,8 @@ struct RTC_EXPORT AudioEncoderMultiChannelOpus {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -38,7 +38,7 @@ operator=(const AudioEncoderMultiChannelOpusConfig&) = default;
bool AudioEncoderMultiChannelOpusConfig::IsOk() const {
if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
return false;
if (num_channels < 0 || num_channels >= 255) {
if (num_channels >= 255) {
return false;
}
if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps)
@ -47,7 +47,7 @@ bool AudioEncoderMultiChannelOpusConfig::IsOk() const {
return false;
// Check the lengths:
if (num_channels < 0 || num_streams < 0 || coupled_streams < 0) {
if (num_streams < 0 || coupled_streams < 0) {
return false;
}
if (num_streams < coupled_streams) {

View File

@ -32,7 +32,12 @@ AudioCodecInfo AudioEncoderOpus::QueryAudioEncoder(
std::unique_ptr<AudioEncoder> AudioEncoderOpus::MakeAudioEncoder(
const AudioEncoderOpusConfig& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return AudioEncoderOpusImpl::MakeAudioEncoder(config, payload_type);
}

View File

@ -19,6 +19,7 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/audio_codecs/opus/audio_encoder_opus_config.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
@ -34,7 +35,8 @@ struct RTC_EXPORT AudioEncoderOpus {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const AudioEncoderOpusConfig& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc

View File

@ -61,7 +61,7 @@ bool AudioEncoderOpusConfig::IsOk() const {
// well; we can add support for them when needed.)
return false;
}
if (num_channels < 0 || num_channels >= 255) {
if (num_channels >= 255) {
return false;
}
if (!bitrate_bps)

View File

@ -49,10 +49,10 @@ struct RTC_EXPORT AudioEncoderOpusConfig {
bool cbr_enabled;
int max_playback_rate_hz;
// |complexity| is used when the bitrate goes above
// |complexity_threshold_bps| + |complexity_threshold_window_bps|;
// |low_rate_complexity| is used when the bitrate falls below
// |complexity_threshold_bps| - |complexity_threshold_window_bps|. In the
// `complexity` is used when the bitrate goes above
// `complexity_threshold_bps` + `complexity_threshold_window_bps`;
// `low_rate_complexity` is used when the bitrate falls below
// `complexity_threshold_bps` - `complexity_threshold_window_bps`. In the
// interval in the middle, we keep using the most recent of the two
// complexity settings.
int complexity;

View File

@ -37,8 +37,10 @@ struct NotAdvertised {
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
return T::MakeAudioEncoder(config, payload_type, codec_pair_id);
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr) {
return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
field_trials);
}
};

View File

@ -21,8 +21,8 @@ if (rtc_include_tests) {
]
deps = [
"..:audio_codecs_api",
"../../../rtc_base:rtc_base_approved",
"../../../test:audio_codec_mocks",
"../../../test:scoped_key_value_config",
"../../../test:test_support",
"../L16:audio_decoder_L16",
"../L16:audio_encoder_L16",
@ -32,10 +32,6 @@ if (rtc_include_tests) {
"../g722:audio_encoder_g722",
"../ilbc:audio_decoder_ilbc",
"../ilbc:audio_encoder_ilbc",
"../isac:audio_decoder_isac_fix",
"../isac:audio_decoder_isac_float",
"../isac:audio_encoder_isac_fix",
"../isac:audio_encoder_isac_float",
"../opus:audio_decoder_opus",
"../opus:audio_encoder_opus",
]

View File

@ -16,12 +16,11 @@
#include "api/audio_codecs/g711/audio_decoder_g711.h"
#include "api/audio_codecs/g722/audio_decoder_g722.h"
#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h"
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h"
#include "api/audio_codecs/isac/audio_decoder_isac_float.h"
#include "api/audio_codecs/opus/audio_decoder_opus.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder.h"
#include "test/scoped_key_value_config.h"
namespace webrtc {
@ -77,9 +76,11 @@ struct AudioDecoderFakeApi {
} // namespace
TEST(AudioDecoderFactoryTemplateTest, NoDecoderTypes) {
test::ScopedKeyValueConfig field_trials;
rtc::scoped_refptr<AudioDecoderFactory> factory(
new rtc::RefCountedObject<
audio_decoder_factory_template_impl::AudioDecoderFactoryT<>>());
rtc::make_ref_counted<
audio_decoder_factory_template_impl::AudioDecoderFactoryT<>>(
&field_trials));
EXPECT_THAT(factory->GetSupportedDecoders(), ::testing::IsEmpty());
EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
EXPECT_EQ(nullptr,
@ -179,41 +180,6 @@ TEST(AudioDecoderFactoryTemplateTest, Ilbc) {
EXPECT_EQ(8000, dec->SampleRateHz());
}
TEST(AudioDecoderFactoryTemplateTest, IsacFix) {
auto factory = CreateAudioDecoderFactory<AudioDecoderIsacFix>();
EXPECT_THAT(factory->GetSupportedDecoders(),
::testing::ElementsAre(AudioCodecSpec{
{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}}));
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 16000, 2}));
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 16000, 1}));
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioDecoder({"isac", 8000, 1}, absl::nullopt));
auto dec = factory->MakeAudioDecoder({"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, dec);
EXPECT_EQ(16000, dec->SampleRateHz());
}
TEST(AudioDecoderFactoryTemplateTest, IsacFloat) {
auto factory = CreateAudioDecoderFactory<AudioDecoderIsacFloat>();
EXPECT_THAT(
factory->GetSupportedDecoders(),
::testing::ElementsAre(
AudioCodecSpec{{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}},
AudioCodecSpec{{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}}));
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 16000, 2}));
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 16000, 1}));
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioDecoder({"isac", 8000, 1}, absl::nullopt));
auto dec1 = factory->MakeAudioDecoder({"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, dec1);
EXPECT_EQ(16000, dec1->SampleRateHz());
auto dec2 = factory->MakeAudioDecoder({"isac", 32000, 1}, absl::nullopt);
ASSERT_NE(nullptr, dec2);
EXPECT_EQ(32000, dec2->SampleRateHz());
}
TEST(AudioDecoderFactoryTemplateTest, L16) {
auto factory = CreateAudioDecoderFactory<AudioDecoderL16>();
EXPECT_THAT(

View File

@ -16,12 +16,11 @@
#include "api/audio_codecs/g711/audio_encoder_g711.h"
#include "api/audio_codecs/g722/audio_encoder_g722.h"
#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h"
#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_audio_encoder.h"
#include "test/scoped_key_value_config.h"
namespace webrtc {
@ -77,9 +76,11 @@ struct AudioEncoderFakeApi {
} // namespace
TEST(AudioEncoderFactoryTemplateTest, NoEncoderTypes) {
test::ScopedKeyValueConfig field_trials;
rtc::scoped_refptr<AudioEncoderFactory> factory(
new rtc::RefCountedObject<
audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>());
rtc::make_ref_counted<
audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>(
&field_trials));
EXPECT_THAT(factory->GetSupportedEncoders(), ::testing::IsEmpty());
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
EXPECT_EQ(nullptr,
@ -177,49 +178,6 @@ TEST(AudioEncoderFactoryTemplateTest, Ilbc) {
EXPECT_EQ(8000, enc->SampleRateHz());
}
TEST(AudioEncoderFactoryTemplateTest, IsacFix) {
auto factory = CreateAudioEncoderFactory<AudioEncoderIsacFix>();
EXPECT_THAT(factory->GetSupportedEncoders(),
::testing::ElementsAre(AudioCodecSpec{
{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}}));
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 16000, 2}));
EXPECT_EQ(AudioCodecInfo(16000, 1, 32000, 10000, 32000),
factory->QueryAudioEncoder({"isac", 16000, 1}));
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioEncoder(17, {"isac", 8000, 1}, absl::nullopt));
auto enc1 = factory->MakeAudioEncoder(17, {"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, enc1);
EXPECT_EQ(16000, enc1->SampleRateHz());
EXPECT_EQ(3u, enc1->Num10MsFramesInNextPacket());
auto enc2 = factory->MakeAudioEncoder(
17, {"isac", 16000, 1, {{"ptime", "60"}}}, absl::nullopt);
ASSERT_NE(nullptr, enc2);
EXPECT_EQ(6u, enc2->Num10MsFramesInNextPacket());
}
TEST(AudioEncoderFactoryTemplateTest, IsacFloat) {
auto factory = CreateAudioEncoderFactory<AudioEncoderIsacFloat>();
EXPECT_THAT(
factory->GetSupportedEncoders(),
::testing::ElementsAre(
AudioCodecSpec{{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}},
AudioCodecSpec{{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}}));
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 16000, 2}));
EXPECT_EQ(AudioCodecInfo(16000, 1, 32000, 10000, 32000),
factory->QueryAudioEncoder({"isac", 16000, 1}));
EXPECT_EQ(AudioCodecInfo(32000, 1, 56000, 10000, 56000),
factory->QueryAudioEncoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioEncoder(17, {"isac", 8000, 1}, absl::nullopt));
auto enc1 = factory->MakeAudioEncoder(17, {"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, enc1);
EXPECT_EQ(16000, enc1->SampleRateHz());
auto enc2 = factory->MakeAudioEncoder(17, {"isac", 32000, 1}, absl::nullopt);
ASSERT_NE(nullptr, enc2);
EXPECT_EQ(32000, enc2->SampleRateHz());
}
TEST(AudioEncoderFactoryTemplateTest, L16) {
auto factory = CreateAudioEncoderFactory<AudioEncoderL16>();
EXPECT_THAT(

View File

@ -52,19 +52,10 @@ void AudioOptions::SetAll(const AudioOptions& change) {
change.audio_jitter_buffer_fast_accelerate);
SetFrom(&audio_jitter_buffer_min_delay_ms,
change.audio_jitter_buffer_min_delay_ms);
SetFrom(&audio_jitter_buffer_enable_rtx_handling,
change.audio_jitter_buffer_enable_rtx_handling);
SetFrom(&typing_detection, change.typing_detection);
SetFrom(&experimental_agc, change.experimental_agc);
SetFrom(&experimental_ns, change.experimental_ns);
SetFrom(&residual_echo_detector, change.residual_echo_detector);
SetFrom(&tx_agc_target_dbov, change.tx_agc_target_dbov);
SetFrom(&tx_agc_digital_compression_gain,
change.tx_agc_digital_compression_gain);
SetFrom(&tx_agc_limiter, change.tx_agc_limiter);
SetFrom(&combined_audio_video_bwe, change.combined_audio_video_bwe);
SetFrom(&audio_network_adaptor, change.audio_network_adaptor);
SetFrom(&audio_network_adaptor_config, change.audio_network_adaptor_config);
SetFrom(&init_recording_on_send, change.init_recording_on_send);
}
bool AudioOptions::operator==(const AudioOptions& o) const {
@ -81,18 +72,10 @@ bool AudioOptions::operator==(const AudioOptions& o) const {
o.audio_jitter_buffer_fast_accelerate &&
audio_jitter_buffer_min_delay_ms ==
o.audio_jitter_buffer_min_delay_ms &&
audio_jitter_buffer_enable_rtx_handling ==
o.audio_jitter_buffer_enable_rtx_handling &&
typing_detection == o.typing_detection &&
experimental_agc == o.experimental_agc &&
experimental_ns == o.experimental_ns &&
residual_echo_detector == o.residual_echo_detector &&
tx_agc_target_dbov == o.tx_agc_target_dbov &&
tx_agc_digital_compression_gain == o.tx_agc_digital_compression_gain &&
tx_agc_limiter == o.tx_agc_limiter &&
combined_audio_video_bwe == o.combined_audio_video_bwe &&
audio_network_adaptor == o.audio_network_adaptor &&
audio_network_adaptor_config == o.audio_network_adaptor_config;
audio_network_adaptor_config == o.audio_network_adaptor_config &&
init_recording_on_send == o.init_recording_on_send;
}
std::string AudioOptions::ToString() const {
@ -114,18 +97,9 @@ std::string AudioOptions::ToString() const {
audio_jitter_buffer_fast_accelerate);
ToStringIfSet(&result, "audio_jitter_buffer_min_delay_ms",
audio_jitter_buffer_min_delay_ms);
ToStringIfSet(&result, "audio_jitter_buffer_enable_rtx_handling",
audio_jitter_buffer_enable_rtx_handling);
ToStringIfSet(&result, "typing", typing_detection);
ToStringIfSet(&result, "experimental_agc", experimental_agc);
ToStringIfSet(&result, "experimental_ns", experimental_ns);
ToStringIfSet(&result, "residual_echo_detector", residual_echo_detector);
ToStringIfSet(&result, "tx_agc_target_dbov", tx_agc_target_dbov);
ToStringIfSet(&result, "tx_agc_digital_compression_gain",
tx_agc_digital_compression_gain);
ToStringIfSet(&result, "tx_agc_limiter", tx_agc_limiter);
ToStringIfSet(&result, "combined_audio_video_bwe", combined_audio_video_bwe);
ToStringIfSet(&result, "audio_network_adaptor", audio_network_adaptor);
ToStringIfSet(&result, "init_recording_on_send", init_recording_on_send);
result << "}";
return result.str();
}

View File

@ -58,17 +58,6 @@ struct RTC_EXPORT AudioOptions {
absl::optional<bool> audio_jitter_buffer_fast_accelerate;
// Audio receiver jitter buffer (NetEq) minimum target delay in milliseconds.
absl::optional<int> audio_jitter_buffer_min_delay_ms;
// Audio receiver jitter buffer (NetEq) should handle retransmitted packets.
absl::optional<bool> audio_jitter_buffer_enable_rtx_handling;
// Audio processing to detect typing.
absl::optional<bool> typing_detection;
absl::optional<bool> experimental_agc;
absl::optional<bool> experimental_ns;
// Note that tx_agc_* only applies to non-experimental AGC.
absl::optional<bool> residual_echo_detector;
absl::optional<uint16_t> tx_agc_target_dbov;
absl::optional<uint16_t> tx_agc_digital_compression_gain;
absl::optional<bool> tx_agc_limiter;
// Enable combined audio+bandwidth BWE.
// TODO(pthatcher): This flag is set from the
// "googCombinedAudioVideoBwe", but not used anywhere. So delete it,
@ -80,6 +69,10 @@ struct RTC_EXPORT AudioOptions {
absl::optional<bool> audio_network_adaptor;
// Config string for audio network adaptor.
absl::optional<std::string> audio_network_adaptor_config;
// Pre-initialize the ADM for recording when starting to send. Default to
// true.
// TODO(webrtc:13566): Remove this option. See issue for details.
absl::optional<bool> init_recording_on_send;
};
} // namespace cricket

View File

@ -11,13 +11,8 @@
#ifndef API_CALL_AUDIO_SINK_H_
#define API_CALL_AUDIO_SINK_H_
#if defined(WEBRTC_POSIX) && !defined(__STDC_FORMAT_MACROS)
// Avoid conflict with format_macros.h.
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
namespace webrtc {

View File

@ -32,7 +32,7 @@ struct BitrateAllocationUpdate {
double packet_loss_ratio = 0;
// Predicted round trip time.
TimeDelta round_trip_time = TimeDelta::PlusInfinity();
// |bwe_period| is deprecated, use |stable_target_bitrate| allocation instead.
// `bwe_period` is deprecated, use `stable_target_bitrate` allocation instead.
TimeDelta bwe_period = TimeDelta::PlusInfinity();
// Congestion window pushback bitrate reduction fraction. Used in
// VideoStreamEncoder to reduce the bitrate by the given fraction

View File

@ -14,7 +14,8 @@
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "api/ref_counted_base.h"
#include "api/scoped_refptr.h"
namespace webrtc {
@ -30,7 +31,7 @@ struct PacketOptions {
int packet_id = -1;
// Additional data bound to the RTP packet for use in application code,
// outside of WebRTC.
std::vector<uint8_t> application_data;
rtc::scoped_refptr<rtc::RefCountedBase> additional_data;
// Whether this is a retransmission of an earlier packet.
bool is_retransmit = false;
bool included_in_feedback = false;

View File

@ -12,6 +12,7 @@
#include "rtc_base/helpers.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
namespace cricket {
@ -21,19 +22,20 @@ Candidate::Candidate()
component_(0),
priority_(0),
network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
generation_(0),
network_id_(0),
network_cost_(0) {}
Candidate::Candidate(int component,
const std::string& protocol,
absl::string_view protocol,
const rtc::SocketAddress& address,
uint32_t priority,
const std::string& username,
const std::string& password,
const std::string& type,
absl::string_view username,
absl::string_view password,
absl::string_view type,
uint32_t generation,
const std::string& foundation,
absl::string_view foundation,
uint16_t network_id,
uint16_t network_cost)
: id_(rtc::CreateRandomString(8)),
@ -45,6 +47,7 @@ Candidate::Candidate(int component,
password_(password),
type_(type),
network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
generation_(generation),
foundation_(foundation),
network_id_(network_id),
@ -91,7 +94,7 @@ uint32_t Candidate::GetPriority(uint32_t type_preference,
// (2^8)*(local preference) +
// (2^0)*(256 - component ID)
// |local_preference| length is 2 bytes, 0-65535 inclusive.
// `local_preference` length is 2 bytes, 0-65535 inclusive.
// In our implemenation we will partion local_preference into
// 0 1
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
@ -100,7 +103,9 @@ uint32_t Candidate::GetPriority(uint32_t type_preference,
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired.
// Addr Pref - Address preference value as per RFC 3484.
// local preference = (NIC Type << 8 | Addr_Pref) - relay preference.
// local preference = (NIC Type << 8 | Addr_Pref) + relay preference.
// The relay preference is based on the number of TURN servers, the
// first TURN server gets the highest preference.
int addr_pref = IPAddressPrecedence(address_.ipaddr());
int local_preference =
@ -129,9 +134,21 @@ Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
bool filter_related_address) const {
Candidate copy(*this);
if (use_hostname_address) {
rtc::SocketAddress hostname_only_addr(address().hostname(),
address().port());
copy.set_address(hostname_only_addr);
rtc::IPAddress ip;
if (address().hostname().empty()) {
// IP needs to be redacted, but no hostname available.
rtc::SocketAddress redacted_addr("redacted-ip.invalid", address().port());
copy.set_address(redacted_addr);
} else if (IPFromString(address().hostname(), &ip)) {
// The hostname is an IP literal, and needs to be redacted too.
rtc::SocketAddress redacted_addr("redacted-literal.invalid",
address().port());
copy.set_address(redacted_addr);
} else {
rtc::SocketAddress hostname_only_addr(address().hostname(),
address().port());
copy.set_address(hostname_only_addr);
}
}
if (filter_related_address) {
copy.set_related_address(
@ -140,4 +157,11 @@ Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
return copy;
}
void Candidate::Assign(std::string& s, absl::string_view view) {
// Assigning via a temporary object, like s = std::string(view), results in
// binary size bloat. To avoid that, extract pointer and size from the
// string view, and use std::string::assign method.
s.assign(view.data(), view.size());
}
} // namespace cricket

View File

@ -17,6 +17,7 @@
#include <algorithm>
#include <string>
#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/network_constants.h"
#include "rtc_base/socket_address.h"
@ -24,6 +25,10 @@
namespace cricket {
// TURN servers are limited to 32 in accordance with
// https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers
static constexpr size_t kMaxTurnServers = 32;
// Candidate for ICE based connection discovery.
// TODO(phoglund): remove things in here that are not needed in the public API.
@ -33,32 +38,32 @@ class RTC_EXPORT Candidate {
// TODO(pthatcher): Match the ordering and param list as per RFC 5245
// candidate-attribute syntax. http://tools.ietf.org/html/rfc5245#section-15.1
Candidate(int component,
const std::string& protocol,
absl::string_view protocol,
const rtc::SocketAddress& address,
uint32_t priority,
const std::string& username,
const std::string& password,
const std::string& type,
absl::string_view username,
absl::string_view password,
absl::string_view type,
uint32_t generation,
const std::string& foundation,
absl::string_view foundation,
uint16_t network_id = 0,
uint16_t network_cost = 0);
Candidate(const Candidate&);
~Candidate();
const std::string& id() const { return id_; }
void set_id(const std::string& id) { id_ = id; }
void set_id(absl::string_view id) { Assign(id_, id); }
int component() const { return component_; }
void set_component(int component) { component_ = component; }
const std::string& protocol() const { return protocol_; }
void set_protocol(const std::string& protocol) { protocol_ = protocol; }
void set_protocol(absl::string_view protocol) { Assign(protocol_, protocol); }
// The protocol used to talk to relay.
const std::string& relay_protocol() const { return relay_protocol_; }
void set_relay_protocol(const std::string& protocol) {
relay_protocol_ = protocol;
void set_relay_protocol(absl::string_view protocol) {
Assign(relay_protocol_, protocol);
}
const rtc::SocketAddress& address() const { return address_; }
@ -90,17 +95,17 @@ class RTC_EXPORT Candidate {
// TODO(honghaiz): Change to usernameFragment or ufrag.
const std::string& username() const { return username_; }
void set_username(const std::string& username) { username_ = username; }
void set_username(absl::string_view username) { Assign(username_, username); }
const std::string& password() const { return password_; }
void set_password(const std::string& password) { password_ = password; }
void set_password(absl::string_view password) { Assign(password_, password); }
const std::string& type() const { return type_; }
void set_type(const std::string& type) { type_ = type; }
void set_type(absl::string_view type) { Assign(type_, type); }
const std::string& network_name() const { return network_name_; }
void set_network_name(const std::string& network_name) {
network_name_ = network_name;
void set_network_name(absl::string_view network_name) {
Assign(network_name_, network_name);
}
rtc::AdapterType network_type() const { return network_type_; }
@ -108,11 +113,18 @@ class RTC_EXPORT Candidate {
network_type_ = network_type;
}
rtc::AdapterType underlying_type_for_vpn() const {
return underlying_type_for_vpn_;
}
void set_underlying_type_for_vpn(rtc::AdapterType network_type) {
underlying_type_for_vpn_ = network_type;
}
// Candidates in a new generation replace those in the old generation.
uint32_t generation() const { return generation_; }
void set_generation(uint32_t generation) { generation_ = generation; }
// |network_cost| measures the cost/penalty of using this candidate. A network
// `network_cost` measures the cost/penalty of using this candidate. A network
// cost of 0 indicates this candidate can be used freely. A value of
// rtc::kNetworkCostMax indicates it should be used only as the last resort.
void set_network_cost(uint16_t network_cost) {
@ -126,8 +138,8 @@ class RTC_EXPORT Candidate {
void set_network_id(uint16_t network_id) { network_id_ = network_id; }
const std::string& foundation() const { return foundation_; }
void set_foundation(const std::string& foundation) {
foundation_ = foundation;
void set_foundation(absl::string_view foundation) {
Assign(foundation_, foundation);
}
const rtc::SocketAddress& related_address() const { return related_address_; }
@ -135,18 +147,18 @@ class RTC_EXPORT Candidate {
related_address_ = related_address;
}
const std::string& tcptype() const { return tcptype_; }
void set_tcptype(const std::string& tcptype) { tcptype_ = tcptype; }
void set_tcptype(absl::string_view tcptype) { Assign(tcptype_, tcptype); }
// The name of the transport channel of this candidate.
// TODO(phoglund): remove.
const std::string& transport_name() const { return transport_name_; }
void set_transport_name(const std::string& transport_name) {
transport_name_ = transport_name;
void set_transport_name(absl::string_view transport_name) {
Assign(transport_name_, transport_name);
}
// The URL of the ICE server which this candidate is gathered from.
const std::string& url() const { return url_; }
void set_url(const std::string& url) { url_ = url; }
void set_url(absl::string_view url) { Assign(url_, url); }
// Determines whether this candidate is equivalent to the given one.
bool IsEquivalent(const Candidate& c) const;
@ -167,9 +179,9 @@ class RTC_EXPORT Candidate {
bool operator!=(const Candidate& o) const;
// Returns a sanitized copy configured by the given booleans. If
// |use_host_address| is true, the returned copy has its IP removed from
// |address()|, which leads |address()| to be a hostname address. If
// |filter_related_address|, the returned copy has its related address reset
// `use_host_address` is true, the returned copy has its IP removed from
// `address()`, which leads `address()` to be a hostname address. If
// `filter_related_address`, the returned copy has its related address reset
// to the wildcard address (i.e. 0.0.0.0 for IPv4 and :: for IPv6). Note that
// setting both booleans to false returns an identical copy to the original
// candidate.
@ -177,6 +189,10 @@ class RTC_EXPORT Candidate {
bool filter_related_address) const;
private:
// TODO(bugs.webrtc.org/13220): With C++17, we get a std::string assignment
// operator accepting any object implicitly convertible to std::string_view,
// and then we don't need this workaround.
static void Assign(std::string& s, absl::string_view view);
std::string ToStringInternal(bool sensitive) const;
std::string id_;
@ -190,6 +206,7 @@ class RTC_EXPORT Candidate {
std::string type_;
std::string network_name_;
rtc::AdapterType network_type_;
rtc::AdapterType underlying_type_for_vpn_;
uint32_t generation_;
std::string foundation_;
rtc::SocketAddress related_address_;

View File

@ -18,6 +18,7 @@
#include "api/rtc_event_log/rtc_event_log_factory.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/transport/field_trial_based_config.h"
#include "media/base/media_engine.h"
#include "media/engine/webrtc_media_engine.h"
#include "modules/audio_device/include/audio_device.h"
@ -36,21 +37,34 @@ rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
rtc::scoped_refptr<AudioMixer> audio_mixer,
rtc::scoped_refptr<AudioProcessing> audio_processing) {
rtc::scoped_refptr<AudioProcessing> audio_processing,
AudioFrameProcessor* audio_frame_processor,
std::unique_ptr<FieldTrialsView> field_trials) {
if (!field_trials) {
field_trials = std::make_unique<webrtc::FieldTrialBasedConfig>();
}
PeerConnectionFactoryDependencies dependencies;
dependencies.network_thread = network_thread;
dependencies.worker_thread = worker_thread;
dependencies.signaling_thread = signaling_thread;
dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
dependencies.task_queue_factory =
CreateDefaultTaskQueueFactory(field_trials.get());
dependencies.call_factory = CreateCallFactory();
dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>(
dependencies.task_queue_factory.get());
dependencies.trials = std::move(field_trials);
if (network_thread) {
// TODO(bugs.webrtc.org/13145): Add an rtc::SocketFactory* argument.
dependencies.socket_factory = network_thread->socketserver();
}
cricket::MediaEngineDependencies media_dependencies;
media_dependencies.task_queue_factory = dependencies.task_queue_factory.get();
media_dependencies.adm = std::move(default_adm);
media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory);
media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory);
media_dependencies.audio_frame_processor = audio_frame_processor;
if (audio_processing) {
media_dependencies.audio_processing = std::move(audio_processing);
} else {
@ -59,6 +73,7 @@ rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
media_dependencies.audio_mixer = std::move(audio_mixer);
media_dependencies.video_encoder_factory = std::move(video_encoder_factory);
media_dependencies.video_decoder_factory = std::move(video_decoder_factory);
media_dependencies.trials = dependencies.trials.get();
dependencies.media_engine =
cricket::CreateMediaEngine(std::move(media_dependencies));

View File

@ -31,6 +31,7 @@ class Thread;
namespace webrtc {
class AudioDeviceModule;
class AudioFrameProcessor;
class AudioProcessing;
// Create a new instance of PeerConnectionFactoryInterface with optional video
@ -47,7 +48,9 @@ CreatePeerConnectionFactory(
std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
rtc::scoped_refptr<AudioMixer> audio_mixer,
rtc::scoped_refptr<AudioProcessing> audio_processing);
rtc::scoped_refptr<AudioProcessing> audio_processing,
AudioFrameProcessor* audio_frame_processor = nullptr,
std::unique_ptr<FieldTrialsView> field_trials = nullptr);
} // namespace webrtc

View File

@ -32,24 +32,24 @@ CryptoOptions CryptoOptions::NoGcm() {
std::vector<int> CryptoOptions::GetSupportedDtlsSrtpCryptoSuites() const {
std::vector<int> crypto_suites;
// Note: SRTP_AES128_CM_SHA1_80 is what is required to be supported (by
// draft-ietf-rtcweb-security-arch), but SRTP_AES128_CM_SHA1_32 is allowed as
// Note: kSrtpAes128CmSha1_80 is what is required to be supported (by
// draft-ietf-rtcweb-security-arch), but kSrtpAes128CmSha1_32 is allowed as
// well, and saves a few bytes per packet if it ends up selected.
// As the cipher suite is potentially insecure, it will only be used if
// enabled by both peers.
if (srtp.enable_aes128_sha1_32_crypto_cipher) {
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_32);
crypto_suites.push_back(rtc::kSrtpAes128CmSha1_32);
}
if (srtp.enable_aes128_sha1_80_crypto_cipher) {
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_80);
crypto_suites.push_back(rtc::kSrtpAes128CmSha1_80);
}
// Note: GCM cipher suites are not the top choice since they increase the
// packet size. In order to negotiate them the other side must not support
// SRTP_AES128_CM_SHA1_80.
// kSrtpAes128CmSha1_80.
if (srtp.enable_gcm_crypto_suites) {
crypto_suites.push_back(rtc::SRTP_AEAD_AES_256_GCM);
crypto_suites.push_back(rtc::SRTP_AEAD_AES_128_GCM);
crypto_suites.push_back(rtc::kSrtpAeadAes256Gcm);
crypto_suites.push_back(rtc::kSrtpAeadAes128Gcm);
}
RTC_CHECK(!crypto_suites.empty());
return crypto_suites;

View File

@ -44,7 +44,7 @@ struct RTC_EXPORT CryptoOptions {
bool enable_gcm_crypto_suites = false;
// If set to true, the (potentially insecure) crypto cipher
// SRTP_AES128_CM_SHA1_32 will be included in the list of supported ciphers
// kSrtpAes128CmSha1_32 will be included in the list of supported ciphers
// during negotiation. It will only be used if both peers support it and no
// other ciphers get preferred.
bool enable_aes128_sha1_32_crypto_cipher = false;

View File

@ -27,7 +27,6 @@ namespace webrtc {
// without it. You may assume that this interface will have the same lifetime
// as the RTPReceiver it is attached to. It must only be attached to one
// RTPReceiver. Additional data may be null.
// Note: This interface is not ready for production use.
class FrameDecryptorInterface : public rtc::RefCountInterface {
public:
// The Status enum represents all possible states that can be

Some files were not shown because too many files have changed in this diff Show More