Sync to webrtc ToT
Update to commit "AEC3: Parametrize the shadow filter output usage".
https://webrtc.googlesource.com/src/+/240215431ee21e85e415484d1d80f437850f2f8e
This update includes all parameters and codes for tuning
APM performance with CRAS.
BUG=chromium:874787
TEST=Apply all config files and test on nocturne
CQ-DEPEND=CL:1196304
Change-Id: Idf6da0c70ac1569d2567c2ab15f436731edb3f35
Reviewed-on: https://chromium-review.googlesource.com/1194561
Commit-Ready: Hsinyu Chao <hychao@chromium.org>
Tested-by: Hsinyu Chao <hychao@chromium.org>
Reviewed-by: Hsinyu Chao <hychao@chromium.org>
diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel
index 439addb..edd0274 100644
--- a/absl/BUILD.bazel
+++ b/absl/BUILD.bazel
@@ -18,11 +18,10 @@
licenses(["notice"]) # Apache 2.0
-config_setting(
+load(":compiler_config_setting.bzl", "create_llvm_config")
+
+create_llvm_config(
name = "llvm_compiler",
- values = {
- "compiler": "llvm",
- },
visibility = [":__subpackages__"],
)
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index acddec4..6af8c09 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -314,7 +314,7 @@
// c_mismatch()
//
-// Container-based version of the <algorithm> `std::mismatchf()` function to
+// Container-based version of the <algorithm> `std::mismatch()` function to
// return the first element where two ordered containers differ.
template <typename C1, typename C2>
container_algorithm_internal::ContainerIterPairType<C1, C2>
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 35414a2..06d092e 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -362,6 +362,7 @@
copts = ABSL_TEST_COPTS,
deps = [
":base",
+ "//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 303533e..01d2af0 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -310,7 +310,7 @@
# test raw_logging_test
set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc")
-set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base)
+set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings)
absl_test(
TARGET
diff --git a/absl/base/config.h b/absl/base/config.h
index 2f5f159..6890e31 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -268,7 +268,7 @@
#error ABSL_HAVE_MMAP cannot be directly set
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \
defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \
- defined(__wasm__) || defined(__Fuchsia__)
+ defined(__wasm__) || defined(__Fuchsia__) || defined(__sun)
#define ABSL_HAVE_MMAP 1
#endif
diff --git a/absl/base/internal/endian_test.cc b/absl/base/internal/endian_test.cc
index f3ff4b3..e276915 100644
--- a/absl/base/internal/endian_test.cc
+++ b/absl/base/internal/endian_test.cc
@@ -33,32 +33,16 @@
const int kNumValuesToTest = 1000000;
const int kRandomSeed = 12345;
-#ifdef ABSL_IS_BIG_ENDIAN
+#if defined(ABSL_IS_BIG_ENDIAN)
const uint64_t kInitialInNetworkOrder{kInitialNumber};
const uint64_t k64ValueLE{0xefcdab8967452301};
const uint32_t k32ValueLE{0x67452301};
const uint16_t k16ValueLE{0x2301};
-const uint8_t k8ValueLE{k8Value};
-const uint64_t k64IValueLE{0xefcdab89674523a1};
-const uint32_t k32IValueLE{0x67452391};
-const uint16_t k16IValueLE{0x85ff};
-const uint8_t k8IValueLE{0xff};
-const uint64_t kDoubleValueLE{0x6e861bf0f9210940};
-const uint32_t kFloatValueLE{0xd00f4940};
-const uint8_t kBoolValueLE{0x1};
const uint64_t k64ValueBE{kInitialNumber};
const uint32_t k32ValueBE{k32Value};
const uint16_t k16ValueBE{k16Value};
-const uint8_t k8ValueBE{k8Value};
-const uint64_t k64IValueBE{0xa123456789abcdef};
-const uint32_t k32IValueBE{0x91234567};
-const uint16_t k16IValueBE{0xff85};
-const uint8_t k8IValueBE{0xff};
-const uint64_t kDoubleValueBE{0x400921f9f01b866e};
-const uint32_t kFloatValueBE{0x40490fd0};
-const uint8_t kBoolValueBE{0x1};
-#elif defined ABSL_IS_LITTLE_ENDIAN
+#elif defined(ABSL_IS_LITTLE_ENDIAN)
const uint64_t kInitialInNetworkOrder{0xefcdab8967452301};
const uint64_t k64ValueLE{kInitialNumber};
const uint32_t k32ValueLE{k32Value};
diff --git a/absl/base/internal/exception_testing.h b/absl/base/internal/exception_testing.h
index fd89a3f..0cf7918 100644
--- a/absl/base/internal/exception_testing.h
+++ b/absl/base/internal/exception_testing.h
@@ -35,7 +35,7 @@
EXPECT_DEATH(expr, ".*")
#else
#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \
- EXPECT_DEATH(expr, text)
+ EXPECT_DEATH_IF_SUPPORTED(expr, text)
#endif
diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc
index 1ce1388..d9485a6 100644
--- a/absl/base/internal/raw_logging.cc
+++ b/absl/base/internal/raw_logging.cc
@@ -139,7 +139,7 @@
#endif
#ifdef ABSL_MIN_LOG_LEVEL
- if (static_cast<int>(severity) < ABSL_MIN_LOG_LEVEL &&
+ if (severity < static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) &&
severity < absl::LogSeverity::kFatal) {
enabled = false;
}
@@ -206,6 +206,15 @@
va_end(ap);
}
+// Non-formatting version of RawLog().
+//
+// TODO(gfalcon): When string_view no longer depends on base, change this
+// interface to take its message as a string_view instead.
+static void DefaultInternalLog(absl::LogSeverity severity, const char* file,
+ int line, const std::string& message) {
+ RawLog(severity, file, line, "%s", message.c_str());
+}
+
bool RawLoggingFullySupported() {
#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED
return true;
@@ -214,5 +223,12 @@
#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED
}
+ABSL_CONST_INIT absl::base_internal::AtomicHook<InternalLogFunction>
+ internal_log_function(DefaultInternalLog);
+
+void RegisterInternalLogFunction(InternalLogFunction func) {
+ internal_log_function.Store(func);
+}
+
} // namespace raw_logging_internal
} // namespace absl
diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h
index a2b7207..67abfd3 100644
--- a/absl/base/internal/raw_logging.h
+++ b/absl/base/internal/raw_logging.h
@@ -19,7 +19,10 @@
#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_
#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_
+#include <string>
+
#include "absl/base/attributes.h"
+#include "absl/base/internal/atomic_hook.h"
#include "absl/base/log_severity.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
@@ -57,6 +60,34 @@
} \
} while (0)
+// ABSL_INTERNAL_LOG and ABSL_INTERNAL_CHECK work like the RAW variants above,
+// except that if the richer log library is linked into the binary, we dispatch
+// to that instead. This is potentially useful for internal logging and
+// assertions, where we are using RAW_LOG neither for its async-signal-safety
+// nor for its non-allocating nature, but rather because raw logging has very
+// few other dependencies.
+//
+// The API is a subset of the above: each macro only takes two arguments. Use
+// StrCat if you need to build a richer message.
+#define ABSL_INTERNAL_LOG(severity, message) \
+ do { \
+ constexpr const char* absl_raw_logging_internal_basename = \
+ ::absl::raw_logging_internal::Basename(__FILE__, \
+ sizeof(__FILE__) - 1); \
+ ::absl::raw_logging_internal::internal_log_function( \
+ ABSL_RAW_LOGGING_INTERNAL_##severity, \
+ absl_raw_logging_internal_basename, __LINE__, message); \
+ } while (0)
+
+#define ABSL_INTERNAL_CHECK(condition, message) \
+ do { \
+ if (ABSL_PREDICT_FALSE(!(condition))) { \
+ std::string death_message = "Check " #condition " failed: "; \
+ death_message += std::string(message); \
+ ABSL_INTERNAL_LOG(FATAL, death_message); \
+ } \
+ } while (0)
+
#define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo
#define ABSL_RAW_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning
#define ABSL_RAW_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError
@@ -131,6 +162,18 @@
using AbortHook = void (*)(const char* file, int line, const char* buf_start,
const char* prefix_end, const char* buf_end);
+// Internal logging function for ABSL_INTERNAL_LOG to dispatch to.
+//
+// TODO(gfalcon): When string_view no longer depends on base, change this
+// interface to take its message as a string_view instead.
+using InternalLogFunction = void (*)(absl::LogSeverity severity,
+ const char* file, int line,
+ const std::string& message);
+
+extern base_internal::AtomicHook<InternalLogFunction> internal_log_function;
+
+void RegisterInternalLogFunction(InternalLogFunction func);
+
} // namespace raw_logging_internal
} // namespace absl
diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h
index c572436..5c7517a 100644
--- a/absl/base/internal/unaligned_access.h
+++ b/absl/base/internal/unaligned_access.h
@@ -103,6 +103,47 @@
#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
(absl::UnalignedStore64(_p, _val))
+#elif defined(UNDEFINED_BEHAVIOR_SANITIZER)
+
+namespace absl {
+
+inline uint16_t UnalignedLoad16(const void *p) {
+ uint16_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint32_t UnalignedLoad32(const void *p) {
+ uint32_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline uint64_t UnalignedLoad64(const void *p) {
+ uint64_t t;
+ memcpy(&t, p, sizeof t);
+ return t;
+}
+
+inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); }
+
+inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); }
+
+inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); }
+
+} // namespace absl
+
+#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) (absl::UnalignedLoad16(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) (absl::UnalignedLoad32(_p))
+#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) (absl::UnalignedLoad64(_p))
+
+#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \
+ (absl::UnalignedStore16(_p, _val))
+#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \
+ (absl::UnalignedStore32(_p, _val))
+#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \
+ (absl::UnalignedStore64(_p, _val))
+
#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \
defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \
defined(__ppc64__) || defined(__PPC64__)
diff --git a/absl/base/raw_logging_test.cc b/absl/base/raw_logging_test.cc
index dae4b35..ebbc5db 100644
--- a/absl/base/raw_logging_test.cc
+++ b/absl/base/raw_logging_test.cc
@@ -18,12 +18,20 @@
#include "absl/base/internal/raw_logging.h"
+#include <tuple>
+
#include "gtest/gtest.h"
+#include "absl/strings/str_cat.h"
namespace {
TEST(RawLoggingCompilationTest, Log) {
ABSL_RAW_LOG(INFO, "RAW INFO: %d", 1);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d", 1, 2);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d", 1, 2, 3);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d", 1, 2, 3, 4);
+ ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d %d", 1, 2, 3, 4, 5);
+ ABSL_RAW_LOG(WARNING, "RAW WARNING: %d", 1);
ABSL_RAW_LOG(ERROR, "RAW ERROR: %d", 1);
}
@@ -47,4 +55,25 @@
kExpectedDeathOutput);
}
+TEST(InternalLog, CompilationTest) {
+ ABSL_INTERNAL_LOG(INFO, "Internal Log");
+ std::string log_msg = "Internal Log";
+ ABSL_INTERNAL_LOG(INFO, log_msg);
+
+ ABSL_INTERNAL_LOG(INFO, log_msg + " 2");
+
+ float d = 1.1f;
+ ABSL_INTERNAL_LOG(INFO, absl::StrCat("Internal log ", 3, " + ", d));
+}
+
+TEST(InternalLogDeathTest, FailingCheck) {
+ EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_CHECK(1 == 0, "explanation"),
+ kExpectedDeathOutput);
+}
+
+TEST(InternalLogDeathTest, LogFatal) {
+ EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_LOG(FATAL, "my dog has fleas"),
+ kExpectedDeathOutput);
+}
+
} // namespace
diff --git a/absl/compiler_config_setting.bzl b/absl/compiler_config_setting.bzl
new file mode 100644
index 0000000..b77c4f5
--- /dev/null
+++ b/absl/compiler_config_setting.bzl
@@ -0,0 +1,39 @@
+#
+# Copyright 2018 The Abseil Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Creates config_setting that allows selecting based on 'compiler' value."""
+
+def create_llvm_config(name, visibility):
+ # The "do_not_use_tools_cpp_compiler_present" attribute exists to
+ # distinguish between older versions of Bazel that do not support
+ # "@bazel_tools//tools/cpp:compiler" flag_value, and newer ones that do.
+ # In the future, the only way to select on the compiler will be through
+ # flag_values{"@bazel_tools//tools/cpp:compiler"} and the else branch can
+ # be removed.
+ if hasattr(cc_common, "do_not_use_tools_cpp_compiler_present"):
+ native.config_setting(
+ name = name,
+ flag_values = {
+ "@bazel_tools//tools/cpp:compiler": "llvm",
+ },
+ visibility = visibility,
+ )
+ else:
+ native.config_setting(
+ name = name,
+ values = {"compiler": "llvm"},
+ visibility = visibility,
+ )
diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel
index 07df367..6d5c958 100644
--- a/absl/container/BUILD.bazel
+++ b/absl/container/BUILD.bazel
@@ -26,10 +26,30 @@
licenses(["notice"]) # Apache 2.0
cc_library(
+ name = "compressed_tuple",
+ hdrs = ["internal/compressed_tuple.h"],
+ copts = ABSL_DEFAULT_COPTS,
+ deps = [
+ "//absl/utility",
+ ],
+)
+
+cc_test(
+ name = "compressed_tuple_test",
+ srcs = ["internal/compressed_tuple_test.cc"],
+ copts = ABSL_TEST_COPTS,
+ deps = [
+ ":compressed_tuple",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
+
+cc_library(
name = "fixed_array",
hdrs = ["fixed_array.h"],
copts = ABSL_DEFAULT_COPTS,
deps = [
+ ":compressed_tuple",
"//absl/algorithm",
"//absl/base:core_headers",
"//absl/base:dynamic_annotations",
diff --git a/absl/container/BUILD.gn b/absl/container/BUILD.gn
index a00eaf4..001a2a3 100644
--- a/absl/container/BUILD.gn
+++ b/absl/container/BUILD.gn
@@ -14,6 +14,21 @@
visibility = [ "*" ]
}
+source_set("compressed_tuple") {
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [
+ "//build/config/compiler:no_chromium_code",
+ "//third_party/abseil-cpp:absl_default_cflags_cc",
+ ]
+ public_configs = [ "//third_party/abseil-cpp:absl_include_config" ]
+ public = [
+ "internal/compressed_tuple.h",
+ ]
+ deps = [
+ "../utility",
+ ]
+}
+
source_set("fixed_array") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
@@ -25,6 +40,7 @@
"fixed_array.h",
]
deps = [
+ ":compressed_tuple",
"../algorithm",
"../base:core_headers",
"../base:dynamic_annotations",
diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt
index d580b48..123e4c4 100644
--- a/absl/container/CMakeLists.txt
+++ b/absl/container/CMakeLists.txt
@@ -52,7 +52,6 @@
${TEST_INSTANCE_TRACKER_LIB_SRC}
PUBLIC_LIBRARIES
absl::container
- DISABLE_INSTALL
)
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h
index 708c615..182258f 100644
--- a/absl/container/fixed_array.h
+++ b/absl/container/fixed_array.h
@@ -47,6 +47,7 @@
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
+#include "absl/container/internal/compressed_tuple.h"
#include "absl/memory/memory.h"
namespace absl {
@@ -76,73 +77,99 @@
// heap allocation, it will do so with global `::operator new[]()` and
// `::operator delete[]()`, even if T provides class-scope overrides for these
// operators.
-template <typename T, size_t inlined = kFixedArrayUseDefault>
+template <typename T, size_t N = kFixedArrayUseDefault,
+ typename A = std::allocator<T>>
class FixedArray {
static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
"Arrays with unknown bounds cannot be used with FixedArray.");
+
static constexpr size_t kInlineBytesDefault = 256;
+ using AllocatorTraits = std::allocator_traits<A>;
// std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17,
// but this seems to be mostly pedantic.
template <typename Iterator>
using EnableIfForwardIterator = absl::enable_if_t<std::is_convertible<
typename std::iterator_traits<Iterator>::iterator_category,
std::forward_iterator_tag>::value>;
+ static constexpr bool NoexceptCopyable() {
+ return std::is_nothrow_copy_constructible<StorageElement>::value &&
+ absl::allocator_is_nothrow<allocator_type>::value;
+ }
+ static constexpr bool NoexceptMovable() {
+ return std::is_nothrow_move_constructible<StorageElement>::value &&
+ absl::allocator_is_nothrow<allocator_type>::value;
+ }
+ static constexpr bool DefaultConstructorIsNonTrivial() {
+ return !absl::is_trivially_default_constructible<StorageElement>::value;
+ }
public:
- using value_type = T;
- using iterator = T*;
- using const_iterator = const T*;
+ using allocator_type = typename AllocatorTraits::allocator_type;
+ using value_type = typename allocator_type::value_type;
+ using pointer = typename allocator_type::pointer;
+ using const_pointer = typename allocator_type::const_pointer;
+ using reference = typename allocator_type::reference;
+ using const_reference = typename allocator_type::const_reference;
+ using size_type = typename allocator_type::size_type;
+ using difference_type = typename allocator_type::difference_type;
+ using iterator = pointer;
+ using const_iterator = const_pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- using reference = T&;
- using const_reference = const T&;
- using pointer = T*;
- using const_pointer = const T*;
- using difference_type = ptrdiff_t;
- using size_type = size_t;
static constexpr size_type inline_elements =
- inlined == kFixedArrayUseDefault
- ? kInlineBytesDefault / sizeof(value_type)
- : inlined;
+ (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type)
+ : static_cast<size_type>(N));
- FixedArray(const FixedArray& other)
- : FixedArray(other.begin(), other.end()) {}
+ FixedArray(
+ const FixedArray& other,
+ const allocator_type& a = allocator_type()) noexcept(NoexceptCopyable())
+ : FixedArray(other.begin(), other.end(), a) {}
- FixedArray(FixedArray&& other) noexcept(
- absl::conjunction<absl::allocator_is_nothrow<std::allocator<value_type>>,
- std::is_nothrow_move_constructible<value_type>>::value)
+ FixedArray(
+ FixedArray&& other,
+ const allocator_type& a = allocator_type()) noexcept(NoexceptMovable())
: FixedArray(std::make_move_iterator(other.begin()),
- std::make_move_iterator(other.end())) {}
+ std::make_move_iterator(other.end()), a) {}
// Creates an array object that can store `n` elements.
// Note that trivially constructible elements will be uninitialized.
- explicit FixedArray(size_type n) : storage_(n) {
- absl::memory_internal::uninitialized_default_construct_n(storage_.begin(),
- size());
+ explicit FixedArray(size_type n, const allocator_type& a = allocator_type())
+ : storage_(n, a) {
+ if (DefaultConstructorIsNonTrivial()) {
+ memory_internal::ConstructStorage(storage_.alloc(), storage_.begin(),
+ storage_.end());
+ }
}
// Creates an array initialized with `n` copies of `val`.
- FixedArray(size_type n, const value_type& val) : storage_(n) {
- std::uninitialized_fill_n(data(), size(), val);
+ FixedArray(size_type n, const value_type& val,
+ const allocator_type& a = allocator_type())
+ : storage_(n, a) {
+ memory_internal::ConstructStorage(storage_.alloc(), storage_.begin(),
+ storage_.end(), val);
}
+ // Creates an array initialized with the size and contents of `init_list`.
+ FixedArray(std::initializer_list<value_type> init_list,
+ const allocator_type& a = allocator_type())
+ : FixedArray(init_list.begin(), init_list.end(), a) {}
+
// Creates an array initialized with the elements from the input
// range. The array's size will always be `std::distance(first, last)`.
// REQUIRES: Iterator must be a forward_iterator or better.
template <typename Iterator, EnableIfForwardIterator<Iterator>* = nullptr>
- FixedArray(Iterator first, Iterator last)
- : storage_(std::distance(first, last)) {
- std::uninitialized_copy(first, last, data());
+ FixedArray(Iterator first, Iterator last,
+ const allocator_type& a = allocator_type())
+ : storage_(std::distance(first, last), a) {
+ memory_internal::CopyToStorageFromRange(storage_.alloc(), storage_.begin(),
+ first, last);
}
- FixedArray(std::initializer_list<value_type> init_list)
- : FixedArray(init_list.begin(), init_list.end()) {}
-
~FixedArray() noexcept {
- for (const StorageElement& cur : storage_) {
- cur.~StorageElement();
+ for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) {
+ AllocatorTraits::destroy(*storage_.alloc(), cur);
}
}
@@ -332,7 +359,6 @@
friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) {
return !(lhs < rhs);
}
-
private:
// StorageElement
//
@@ -364,6 +390,8 @@
using StorageElement =
absl::conditional_t<std::is_array<value_type>::value,
StorageElementWrapper<value_type>, value_type>;
+ using StorageElementBuffer =
+ absl::aligned_storage_t<sizeof(StorageElement), alignof(StorageElement)>;
static pointer AsValueType(pointer ptr) { return ptr; }
static pointer AsValueType(StorageElementWrapper<value_type>* ptr) {
@@ -374,9 +402,6 @@
static_assert(alignof(StorageElement) == alignof(value_type), "");
struct NonEmptyInlinedStorage {
- using StorageElementBuffer =
- absl::aligned_storage_t<sizeof(StorageElement),
- alignof(StorageElement)>;
StorageElement* data() {
return reinterpret_cast<StorageElement*>(inlined_storage_.data());
}
@@ -386,8 +411,8 @@
void* RedzoneEnd() { return &redzone_end_ + 1; }
#endif // ADDRESS_SANITIZER
- void AnnotateConstruct(size_t);
- void AnnotateDestruct(size_t);
+ void AnnotateConstruct(size_type);
+ void AnnotateDestruct(size_type);
ABSL_ADDRESS_SANITIZER_REDZONE(redzone_begin_);
std::array<StorageElementBuffer, inline_elements> inlined_storage_;
@@ -396,8 +421,8 @@
struct EmptyInlinedStorage {
StorageElement* data() { return nullptr; }
- void AnnotateConstruct(size_t) {}
- void AnnotateDestruct(size_t) {}
+ void AnnotateConstruct(size_type) {}
+ void AnnotateDestruct(size_type) {}
};
using InlinedStorage =
@@ -414,48 +439,57 @@
//
class Storage : public InlinedStorage {
public:
- explicit Storage(size_type n) : data_(CreateStorage(n)), size_(n) {}
+ Storage(size_type n, const allocator_type& a)
+ : size_alloc_(n, a), data_(InitializeData()) {}
+
~Storage() noexcept {
if (UsingInlinedStorage(size())) {
- this->AnnotateDestruct(size());
+ InlinedStorage::AnnotateDestruct(size());
} else {
- std::allocator<StorageElement>().deallocate(begin(), size());
+ AllocatorTraits::deallocate(*alloc(), AsValueType(begin()), size());
}
}
- size_type size() const { return size_; }
+ size_type size() const { return size_alloc_.template get<0>(); }
StorageElement* begin() const { return data_; }
StorageElement* end() const { return begin() + size(); }
+ allocator_type* alloc() {
+ return std::addressof(size_alloc_.template get<1>());
+ }
private:
static bool UsingInlinedStorage(size_type n) {
return n <= inline_elements;
}
- StorageElement* CreateStorage(size_type n) {
- if (UsingInlinedStorage(n)) {
- this->AnnotateConstruct(n);
+ StorageElement* InitializeData() {
+ if (UsingInlinedStorage(size())) {
+ InlinedStorage::AnnotateConstruct(size());
return InlinedStorage::data();
} else {
- return std::allocator<StorageElement>().allocate(n);
+ return reinterpret_cast<StorageElement*>(
+ AllocatorTraits::allocate(*alloc(), size()));
}
}
- StorageElement* const data_;
- const size_type size_;
+ // `CompressedTuple` takes advantage of EBCO for stateless `allocator_type`s
+ container_internal::CompressedTuple<size_type, allocator_type> size_alloc_;
+ StorageElement* data_;
};
- const Storage storage_;
+ Storage storage_;
};
-template <typename T, size_t N>
-constexpr size_t FixedArray<T, N>::inline_elements;
+template <typename T, size_t N, typename A>
+constexpr size_t FixedArray<T, N, A>::kInlineBytesDefault;
-template <typename T, size_t N>
-constexpr size_t FixedArray<T, N>::kInlineBytesDefault;
+template <typename T, size_t N, typename A>
+constexpr typename FixedArray<T, N, A>::size_type
+ FixedArray<T, N, A>::inline_elements;
-template <typename T, size_t N>
-void FixedArray<T, N>::NonEmptyInlinedStorage::AnnotateConstruct(size_t n) {
+template <typename T, size_t N, typename A>
+void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateConstruct(
+ typename FixedArray<T, N, A>::size_type n) {
#ifdef ADDRESS_SANITIZER
if (!n) return;
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), data() + n);
@@ -464,8 +498,9 @@
static_cast<void>(n); // Mark used when not in asan mode
}
-template <typename T, size_t N>
-void FixedArray<T, N>::NonEmptyInlinedStorage::AnnotateDestruct(size_t n) {
+template <typename T, size_t N, typename A>
+void FixedArray<T, N, A>::NonEmptyInlinedStorage::AnnotateDestruct(
+ typename FixedArray<T, N, A>::size_type n) {
#ifdef ADDRESS_SANITIZER
if (!n) return;
ABSL_ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, RedzoneEnd());
@@ -473,6 +508,5 @@
#endif // ADDRESS_SANITIZER
static_cast<void>(n); // Mark used when not in asan mode
}
-
} // namespace absl
#endif // ABSL_CONTAINER_FIXED_ARRAY_H_
diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc
index 2142132..b07ebcb 100644
--- a/absl/container/fixed_array_test.cc
+++ b/absl/container/fixed_array_test.cc
@@ -15,9 +15,11 @@
#include "absl/container/fixed_array.h"
#include <stdio.h>
+#include <cstring>
#include <list>
#include <memory>
#include <numeric>
+#include <scoped_allocator>
#include <stdexcept>
#include <string>
#include <vector>
@@ -607,6 +609,216 @@
empty.fill(fill_val);
}
+// TODO(johnsoncj): Investigate InlinedStorage default initialization in GCC 4.x
+#ifndef __GNUC__
+TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) {
+ using T = char;
+ constexpr auto capacity = 10;
+ using FixedArrType = absl::FixedArray<T, capacity>;
+ using FixedArrBuffType =
+ absl::aligned_storage_t<sizeof(FixedArrType), alignof(FixedArrType)>;
+ constexpr auto scrubbed_bits = 0x95;
+ constexpr auto length = capacity / 2;
+
+ FixedArrBuffType buff;
+ std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrBuffType));
+
+ FixedArrType* arr =
+ ::new (static_cast<void*>(std::addressof(buff))) FixedArrType(length);
+ EXPECT_THAT(*arr, testing::Each(scrubbed_bits));
+ arr->~FixedArrType();
+}
+#endif // __GNUC__
+
+// This is a stateful allocator, but the state lives outside of the
+// allocator (in whatever test is using the allocator). This is odd
+// but helps in tests where the allocator is propagated into nested
+// containers - that chain of allocators uses the same state and is
+// thus easier to query for aggregate allocation information.
+template <typename T>
+class CountingAllocator : public std::allocator<T> {
+ public:
+ using Alloc = std::allocator<T>;
+ using pointer = typename Alloc::pointer;
+ using size_type = typename Alloc::size_type;
+
+ CountingAllocator() : bytes_used_(nullptr), instance_count_(nullptr) {}
+ explicit CountingAllocator(int64_t* b)
+ : bytes_used_(b), instance_count_(nullptr) {}
+ CountingAllocator(int64_t* b, int64_t* a)
+ : bytes_used_(b), instance_count_(a) {}
+
+ template <typename U>
+ explicit CountingAllocator(const CountingAllocator<U>& x)
+ : Alloc(x),
+ bytes_used_(x.bytes_used_),
+ instance_count_(x.instance_count_) {}
+
+ pointer allocate(size_type n, const void* const hint = nullptr) {
+ assert(bytes_used_ != nullptr);
+ *bytes_used_ += n * sizeof(T);
+ return Alloc::allocate(n, hint);
+ }
+
+ void deallocate(pointer p, size_type n) {
+ Alloc::deallocate(p, n);
+ assert(bytes_used_ != nullptr);
+ *bytes_used_ -= n * sizeof(T);
+ }
+
+ template <typename... Args>
+ void construct(pointer p, Args&&... args) {
+ Alloc::construct(p, absl::forward<Args>(args)...);
+ if (instance_count_) {
+ *instance_count_ += 1;
+ }
+ }
+
+ void destroy(pointer p) {
+ Alloc::destroy(p);
+ if (instance_count_) {
+ *instance_count_ -= 1;
+ }
+ }
+
+ template <typename U>
+ class rebind {
+ public:
+ using other = CountingAllocator<U>;
+ };
+
+ int64_t* bytes_used_;
+ int64_t* instance_count_;
+};
+
+TEST(AllocatorSupportTest, CountInlineAllocations) {
+ constexpr size_t inlined_size = 4;
+ using Alloc = CountingAllocator<int>;
+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
+
+ int64_t allocated = 0;
+ int64_t active_instances = 0;
+
+ {
+ const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+ Alloc alloc(&allocated, &active_instances);
+
+ AllocFxdArr arr(ia, ia + inlined_size, alloc);
+ static_cast<void>(arr);
+ }
+
+ EXPECT_EQ(allocated, 0);
+ EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, CountOutoflineAllocations) {
+ constexpr size_t inlined_size = 4;
+ using Alloc = CountingAllocator<int>;
+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
+
+ int64_t allocated = 0;
+ int64_t active_instances = 0;
+
+ {
+ const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
+ Alloc alloc(&allocated, &active_instances);
+
+ AllocFxdArr arr(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
+
+ EXPECT_EQ(allocated, arr.size() * sizeof(int));
+ static_cast<void>(arr);
+ }
+
+ EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, CountCopyInlineAllocations) {
+ constexpr size_t inlined_size = 4;
+ using Alloc = CountingAllocator<int>;
+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
+
+ int64_t allocated1 = 0;
+ int64_t allocated2 = 0;
+ int64_t active_instances = 0;
+ Alloc alloc(&allocated1, &active_instances);
+ Alloc alloc2(&allocated2, &active_instances);
+
+ {
+ int initial_value = 1;
+
+ AllocFxdArr arr1(inlined_size / 2, initial_value, alloc);
+
+ EXPECT_EQ(allocated1, 0);
+
+ AllocFxdArr arr2(arr1, alloc2);
+
+ EXPECT_EQ(allocated2, 0);
+ static_cast<void>(arr1);
+ static_cast<void>(arr2);
+ }
+
+ EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) {
+ constexpr size_t inlined_size = 4;
+ using Alloc = CountingAllocator<int>;
+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
+
+ int64_t allocated1 = 0;
+ int64_t allocated2 = 0;
+ int64_t active_instances = 0;
+ Alloc alloc(&allocated1, &active_instances);
+ Alloc alloc2(&allocated2, &active_instances);
+
+ {
+ int initial_value = 1;
+
+ AllocFxdArr arr1(inlined_size * 2, initial_value, alloc);
+
+ EXPECT_EQ(allocated1, arr1.size() * sizeof(int));
+
+ AllocFxdArr arr2(arr1, alloc2);
+
+ EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int));
+ static_cast<void>(arr1);
+ static_cast<void>(arr2);
+ }
+
+ EXPECT_EQ(active_instances, 0);
+}
+
+TEST(AllocatorSupportTest, SizeValAllocConstructor) {
+ using testing::AllOf;
+ using testing::Each;
+ using testing::SizeIs;
+
+ constexpr size_t inlined_size = 4;
+ using Alloc = CountingAllocator<int>;
+ using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>;
+
+ {
+ auto len = inlined_size / 2;
+ auto val = 0;
+ int64_t allocated = 0;
+ AllocFxdArr arr(len, val, Alloc(&allocated));
+
+ EXPECT_EQ(allocated, 0);
+ EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
+ }
+
+ {
+ auto len = inlined_size * 2;
+ auto val = 0;
+ int64_t allocated = 0;
+ AllocFxdArr arr(len, val, Alloc(&allocated));
+
+ EXPECT_EQ(allocated, len * sizeof(int));
+ EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0)));
+ }
+}
+
#ifdef ADDRESS_SANITIZER
TEST(FixedArrayTest, AddressSanitizerAnnotations1) {
absl::FixedArray<int, 32> a(10);
@@ -655,5 +867,4 @@
EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow");
}
#endif // ADDRESS_SANITIZER
-
} // namespace
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h
index 03660f1..ca36fd3 100644
--- a/absl/container/inlined_vector.h
+++ b/absl/container/inlined_vector.h
@@ -626,14 +626,18 @@
// It holds whether the vector is allocated or not in the lowest bit.
// The size is held in the high bits:
// size_ = (size << 1) | is_allocated;
+ //
+ // Maintainer's Note: size_type is user defined. The contract is limited to
+ // arithmetic operators to avoid depending on compliant overloaded bitwise
+ // operators.
class Tag {
public:
Tag() : size_(0) {}
- size_type size() const { return size_ >> 1; }
- void add_size(size_type n) { size_ += n << 1; }
- void set_inline_size(size_type n) { size_ = n << 1; }
- void set_allocated_size(size_type n) { size_ = (n << 1) | 1; }
- bool allocated() const { return size_ & 1; }
+ size_type size() const { return size_ / 2; }
+ void add_size(size_type n) { size_ += n * 2; }
+ void set_inline_size(size_type n) { size_ = n * 2; }
+ void set_allocated_size(size_type n) { size_ = (n * 2) + 1; }
+ bool allocated() const { return size_ % 2; }
private:
size_type size_;
@@ -689,11 +693,14 @@
new (&rep_.allocation_storage.allocation) Allocation(allocation);
}
+ // TODO(absl-team): investigate whether the reinterpret_cast is appropriate.
value_type* inlined_space() {
- return reinterpret_cast<value_type*>(&rep_.inlined_storage.inlined);
+ return reinterpret_cast<value_type*>(
+ std::addressof(rep_.inlined_storage.inlined[0]));
}
const value_type* inlined_space() const {
- return reinterpret_cast<const value_type*>(&rep_.inlined_storage.inlined);
+ return reinterpret_cast<const value_type*>(
+ std::addressof(rep_.inlined_storage.inlined[0]));
}
value_type* allocated_space() { return allocation().buffer(); }
diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc
index f81fad5..196a1be 100644
--- a/absl/container/inlined_vector_test.cc
+++ b/absl/container/inlined_vector_test.cc
@@ -1788,5 +1788,4 @@
EXPECT_THAT(v, AllOf(SizeIs(len), Each(0)));
}
}
-
} // anonymous namespace
diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h
new file mode 100644
index 0000000..cc52614
--- /dev/null
+++ b/absl/container/internal/compressed_tuple.h
@@ -0,0 +1,175 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Helper class to perform the Empty Base Optimization.
+// Ts can contain classes and non-classes, empty or not. For the ones that
+// are empty classes, we perform the optimization. If all types in Ts are empty
+// classes, then CompressedTuple<Ts...> is itself an empty class.
+//
+// To access the members, use member get<N>() function.
+//
+// Eg:
+// absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2,
+// t3);
+// assert(value.get<0>() == 7);
+// T1& t1 = value.get<1>();
+// const T2& t2 = value.get<2>();
+// ...
+//
+// http://en.cppreference.com/w/cpp/language/ebo
+
+#ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
+#define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
+
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+#include "absl/utility/utility.h"
+
+#ifdef _MSC_VER
+// We need to mark these classes with this declspec to ensure that
+// CompressedTuple happens.
+#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases)
+#else // _MSC_VER
+#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
+#endif // _MSC_VER
+
+namespace absl {
+namespace container_internal {
+
+template <typename... Ts>
+class CompressedTuple;
+
+namespace internal_compressed_tuple {
+
+template <typename D, size_t I>
+struct Elem;
+template <typename... B, size_t I>
+struct Elem<CompressedTuple<B...>, I>
+ : std::tuple_element<I, std::tuple<B...>> {};
+template <typename D, size_t I>
+using ElemT = typename Elem<D, I>::type;
+
+// Use the __is_final intrinsic if available. Where it's not available, classes
+// declared with the 'final' specifier cannot be used as CompressedTuple
+// elements.
+// TODO(sbenza): Replace this with std::is_final in C++14.
+template <typename T>
+constexpr bool IsFinal() {
+#if defined(__clang__) || defined(__GNUC__)
+ return __is_final(T);
+#else
+ return false;
+#endif
+}
+
+template <typename T>
+constexpr bool ShouldUseBase() {
+ return std::is_class<T>::value && std::is_empty<T>::value && !IsFinal<T>();
+}
+
+// The storage class provides two specializations:
+// - For empty classes, it stores T as a base class.
+// - For everything else, it stores T as a member.
+template <typename D, size_t I, bool = ShouldUseBase<ElemT<D, I>>()>
+struct Storage {
+ using T = ElemT<D, I>;
+ T value;
+ constexpr Storage() = default;
+ explicit constexpr Storage(T&& v) : value(absl::forward<T>(v)) {}
+ constexpr const T& get() const { return value; }
+ T& get() { return value; }
+};
+
+template <typename D, size_t I>
+struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage<D, I, true>
+ : ElemT<D, I> {
+ using T = internal_compressed_tuple::ElemT<D, I>;
+ constexpr Storage() = default;
+ explicit constexpr Storage(T&& v) : T(absl::forward<T>(v)) {}
+ constexpr const T& get() const { return *this; }
+ T& get() { return *this; }
+};
+
+template <typename D, typename I>
+struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl;
+
+template <typename... Ts, size_t... I>
+struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
+ CompressedTupleImpl<CompressedTuple<Ts...>, absl::index_sequence<I...>>
+ // We use the dummy identity function through std::integral_constant to
+ // convince MSVC of accepting and expanding I in that context. Without it
+ // you would get:
+ // error C3548: 'I': parameter pack cannot be used in this context
+ : Storage<CompressedTuple<Ts...>,
+ std::integral_constant<size_t, I>::value>... {
+ constexpr CompressedTupleImpl() = default;
+ explicit constexpr CompressedTupleImpl(Ts&&... args)
+ : Storage<CompressedTuple<Ts...>, I>(absl::forward<Ts>(args))... {}
+};
+
+} // namespace internal_compressed_tuple
+
+// Helper class to perform the Empty Base Class Optimization.
+// Ts can contain classes and non-classes, empty or not. For the ones that
+// are empty classes, we perform the CompressedTuple. If all types in Ts are
+// empty classes, then CompressedTuple<Ts...> is itself an empty class.
+//
+// To access the members, use member .get<N>() function.
+//
+// Eg:
+// absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2,
+// t3);
+// assert(value.get<0>() == 7);
+// T1& t1 = value.get<1>();
+// const T2& t2 = value.get<2>();
+// ...
+//
+// http://en.cppreference.com/w/cpp/language/ebo
+template <typename... Ts>
+class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple
+ : private internal_compressed_tuple::CompressedTupleImpl<
+ CompressedTuple<Ts...>, absl::index_sequence_for<Ts...>> {
+ private:
+ template <int I>
+ using ElemT = internal_compressed_tuple::ElemT<CompressedTuple, I>;
+
+ public:
+ constexpr CompressedTuple() = default;
+ explicit constexpr CompressedTuple(Ts... base)
+ : CompressedTuple::CompressedTupleImpl(absl::forward<Ts>(base)...) {}
+
+ template <int I>
+ ElemT<I>& get() {
+ return internal_compressed_tuple::Storage<CompressedTuple, I>::get();
+ }
+
+ template <int I>
+ constexpr const ElemT<I>& get() const {
+ return internal_compressed_tuple::Storage<CompressedTuple, I>::get();
+ }
+};
+
+// Explicit specialization for a zero-element tuple
+// (needed to avoid ambiguous overloads for the default constructor).
+template <>
+class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {};
+
+} // namespace container_internal
+} // namespace absl
+
+#undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
+
+#endif // ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc
new file mode 100644
index 0000000..45030c6
--- /dev/null
+++ b/absl/container/internal/compressed_tuple_test.cc
@@ -0,0 +1,166 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/container/internal/compressed_tuple.h"
+
+#include <string>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace absl {
+namespace container_internal {
+namespace {
+
+template <int>
+struct Empty {};
+
+template <typename T>
+struct NotEmpty {
+ T value;
+};
+
+template <typename T, typename U>
+struct TwoValues {
+ T value1;
+ U value2;
+};
+
+TEST(CompressedTupleTest, Sizeof) {
+ EXPECT_EQ(sizeof(int), sizeof(CompressedTuple<int>));
+ EXPECT_EQ(sizeof(int), sizeof(CompressedTuple<int, Empty<0>>));
+ EXPECT_EQ(sizeof(int), sizeof(CompressedTuple<int, Empty<0>, Empty<1>>));
+ EXPECT_EQ(sizeof(int),
+ sizeof(CompressedTuple<int, Empty<0>, Empty<1>, Empty<2>>));
+
+ EXPECT_EQ(sizeof(TwoValues<int, double>),
+ sizeof(CompressedTuple<int, NotEmpty<double>>));
+ EXPECT_EQ(sizeof(TwoValues<int, double>),
+ sizeof(CompressedTuple<int, Empty<0>, NotEmpty<double>>));
+ EXPECT_EQ(sizeof(TwoValues<int, double>),
+ sizeof(CompressedTuple<int, Empty<0>, NotEmpty<double>, Empty<1>>));
+}
+
+TEST(CompressedTupleTest, Access) {
+ struct S {
+ std::string x;
+ };
+ CompressedTuple<int, Empty<0>, S> x(7, {}, S{"ABC"});
+ EXPECT_EQ(sizeof(x), sizeof(TwoValues<int, S>));
+ EXPECT_EQ(7, x.get<0>());
+ EXPECT_EQ("ABC", x.get<2>().x);
+}
+
+TEST(CompressedTupleTest, NonClasses) {
+ CompressedTuple<int, const char*> x(7, "ABC");
+ EXPECT_EQ(7, x.get<0>());
+ EXPECT_STREQ("ABC", x.get<1>());
+}
+
+TEST(CompressedTupleTest, MixClassAndNonClass) {
+ CompressedTuple<int, const char*, Empty<0>, NotEmpty<double>> x(7, "ABC", {},
+ {1.25});
+ struct Mock {
+ int v;
+ const char* p;
+ double d;
+ };
+ EXPECT_EQ(sizeof(x), sizeof(Mock));
+ EXPECT_EQ(7, x.get<0>());
+ EXPECT_STREQ("ABC", x.get<1>());
+ EXPECT_EQ(1.25, x.get<3>().value);
+}
+
+TEST(CompressedTupleTest, Nested) {
+ CompressedTuple<int, CompressedTuple<int>,
+ CompressedTuple<int, CompressedTuple<int>>>
+ x(1, CompressedTuple<int>(2),
+ CompressedTuple<int, CompressedTuple<int>>(3, CompressedTuple<int>(4)));
+ EXPECT_EQ(1, x.get<0>());
+ EXPECT_EQ(2, x.get<1>().get<0>());
+ EXPECT_EQ(3, x.get<2>().get<0>());
+ EXPECT_EQ(4, x.get<2>().get<1>().get<0>());
+
+ CompressedTuple<Empty<0>, Empty<0>,
+ CompressedTuple<Empty<0>, CompressedTuple<Empty<0>>>>
+ y;
+ std::set<Empty<0>*> empties{&y.get<0>(), &y.get<1>(), &y.get<2>().get<0>(),
+ &y.get<2>().get<1>().get<0>()};
+#ifdef _MSC_VER
+ // MSVC has a bug where many instances of the same base class are layed out in
+ // the same address when using __declspec(empty_bases).
+ // This will be fixed in a future version of MSVC.
+ int expected = 1;
+#else
+ int expected = 4;
+#endif
+ EXPECT_EQ(expected, sizeof(y));
+ EXPECT_EQ(expected, empties.size());
+ EXPECT_EQ(sizeof(y), sizeof(Empty<0>) * empties.size());
+
+ EXPECT_EQ(4 * sizeof(char),
+ sizeof(CompressedTuple<CompressedTuple<char, char>,
+ CompressedTuple<char, char>>));
+ EXPECT_TRUE(
+ (std::is_empty<CompressedTuple<CompressedTuple<Empty<0>>,
+ CompressedTuple<Empty<1>>>>::value));
+}
+
+TEST(CompressedTupleTest, Reference) {
+ int i = 7;
+ std::string s = "Very long std::string that goes in the heap";
+ CompressedTuple<int, int&, std::string, std::string&> x(i, i, s, s);
+
+ // Sanity check. We should have not moved from `s`
+ EXPECT_EQ(s, "Very long std::string that goes in the heap");
+
+ EXPECT_EQ(x.get<0>(), x.get<1>());
+ EXPECT_NE(&x.get<0>(), &x.get<1>());
+ EXPECT_EQ(&x.get<1>(), &i);
+
+ EXPECT_EQ(x.get<2>(), x.get<3>());
+ EXPECT_NE(&x.get<2>(), &x.get<3>());
+ EXPECT_EQ(&x.get<3>(), &s);
+}
+
+TEST(CompressedTupleTest, NoElements) {
+ CompressedTuple<> x;
+ static_cast<void>(x); // Silence -Wunused-variable.
+ EXPECT_TRUE(std::is_empty<CompressedTuple<>>::value);
+}
+
+TEST(CompressedTupleTest, Constexpr) {
+ constexpr CompressedTuple<int, double, CompressedTuple<int>> x(
+ 7, 1.25, CompressedTuple<int>(5));
+ constexpr int x0 = x.get<0>();
+ constexpr double x1 = x.get<1>();
+ constexpr int x2 = x.get<2>().get<0>();
+ EXPECT_EQ(x0, 7);
+ EXPECT_EQ(x1, 1.25);
+ EXPECT_EQ(x2, 5);
+}
+
+#if defined(__clang__) || defined(__GNUC__)
+TEST(CompressedTupleTest, EmptyFinalClass) {
+ struct S final {
+ int f() const { return 5; }
+ };
+ CompressedTuple<S> x;
+ EXPECT_EQ(x.get<0>().f(), 5);
+}
+#endif
+
+} // namespace
+} // namespace container_internal
+} // namespace absl
diff --git a/absl/copts.bzl b/absl/copts.bzl
index 20c9b61..0168ac5 100644
--- a/absl/copts.bzl
+++ b/absl/copts.bzl
@@ -31,7 +31,6 @@
"-Wno-unused-private-field",
]
-
# Docs on single flags is preceded by a comment.
# Docs on groups of flags is preceded by ###.
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc
index 4c131fe..d4b957b 100644
--- a/absl/debugging/failure_signal_handler.cc
+++ b/absl/debugging/failure_signal_handler.cc
@@ -252,7 +252,7 @@
depth, min_dropped_frames, symbolize_stacktrace, writerfn, writerfn_arg);
}
-// Called by FailureSignalHandler() to write the failure info. It is
+// Called by AbslFailureSignalHandler() to write the failure info. It is
// called once with writerfn set to WriteToStderr() and then possibly
// with writerfn set to the user provided function.
static void WriteFailureInfo(int signo, void* ucontext,
@@ -278,9 +278,9 @@
}
#ifdef ABSL_HAVE_ALARM
-// FailureSignalHandler() installs this as a signal handler for
+// AbslFailureSignalHandler() installs this as a signal handler for
// SIGALRM, then sets an alarm to be delivered to the program after a
-// set amount of time. If FailureSignalHandler() hangs for more than
+// set amount of time. If AbslFailureSignalHandler() hangs for more than
// the alarm timeout, ImmediateAbortSignalHandler() will abort the
// program.
static void ImmediateAbortSignalHandler(int) {
@@ -294,11 +294,10 @@
ABSL_CONST_INIT static std::atomic<GetTidType> failed_tid(0);
#ifndef ABSL_HAVE_SIGACTION
-static void FailureSignalHandler(int signo) {
+static void AbslFailureSignalHandler(int signo) {
void* ucontext = nullptr;
#else
-static void FailureSignalHandler(int signo, siginfo_t*,
- void* ucontext) {
+static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) {
#endif
const GetTidType this_tid = absl::base_internal::GetTID();
@@ -308,10 +307,10 @@
std::memory_order_acq_rel, std::memory_order_relaxed)) {
ABSL_RAW_LOG(
ERROR,
- "Signal %d raised at PC=%p while already in FailureSignalHandler()",
+ "Signal %d raised at PC=%p while already in AbslFailureSignalHandler()",
signo, absl::debugging_internal::GetProgramCounter(ucontext));
if (this_tid != previous_failed_tid) {
- // Another thread is already in FailureSignalHandler(), so wait
+ // Another thread is already in AbslFailureSignalHandler(), so wait
// a bit for it to finish. If the other thread doesn't kill us,
// we do so after sleeping.
PortableSleepForSeconds(3);
@@ -349,7 +348,7 @@
void InstallFailureSignalHandler(const FailureSignalHandlerOptions& options) {
fsh_options = options;
for (auto& it : failure_signal_data) {
- InstallOneFailureHandler(&it, FailureSignalHandler);
+ InstallOneFailureHandler(&it, AbslFailureSignalHandler);
}
}
diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc
index 8434709..faf8883 100644
--- a/absl/debugging/internal/examine_stack.cc
+++ b/absl/debugging/internal/examine_stack.cc
@@ -52,6 +52,10 @@
return reinterpret_cast<void*>(context->uc_mcontext.gp_regs[32]);
#elif defined(__powerpc__)
return reinterpret_cast<void*>(context->uc_mcontext.regs->nip);
+#elif defined(__s390__) && !defined(__s390x__)
+ return reinterpret_cast<void*>(context->uc_mcontext.psw.addr & 0x7fffffff);
+#elif defined(__s390__) && defined(__s390x__)
+ return reinterpret_cast<void*>(context->uc_mcontext.psw.addr);
#elif defined(__x86_64__)
if (16 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs))
return reinterpret_cast<void*>(context->uc_mcontext.gregs[16]);
diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h
index 48adfcc..dd713da 100644
--- a/absl/debugging/internal/stacktrace_config.h
+++ b/absl/debugging/internal/stacktrace_config.h
@@ -21,26 +21,16 @@
#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
-// First, test platforms which only support a stub.
-#if ABSL_STACKTRACE_INL_HEADER
+#if defined(ABSL_STACKTRACE_INL_HEADER)
#error ABSL_STACKTRACE_INL_HEADER cannot be directly set
-#elif defined(__native_client__) || defined(__APPLE__) || \
- defined(__FreeBSD__) || defined(__ANDROID__) || defined(__myriad2__) || \
- defined(__asmjs__) || defined(__wasm__) || defined(__Fuchsia__)
-#define ABSL_STACKTRACE_INL_HEADER \
- "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
-// Next, test for Mips and Windows.
-// TODO(marmstrong): Mips case, remove the check for ABSL_STACKTRACE_INL_HEADER
-#elif defined(__mips__) && !defined(ABSL_STACKTRACE_INL_HEADER)
-#define ABSL_STACKTRACE_INL_HEADER \
- "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
-#elif defined(_WIN32) // windows
+#elif defined(_WIN32)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_win32-inl.inc"
-// Finally, test NO_FRAME_POINTER.
-#elif !defined(NO_FRAME_POINTER)
+#elif defined(__linux__) && !defined(__ANDROID__)
+
+#if !defined(NO_FRAME_POINTER)
# if defined(__i386__) || defined(__x86_64__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_x86-inl.inc"
@@ -53,22 +43,27 @@
# elif defined(__arm__)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_arm-inl.inc"
+# else
+#define ABSL_STACKTRACE_INL_HEADER \
+ "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
# endif
#else // defined(NO_FRAME_POINTER)
# if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
#define ABSL_STACKTRACE_INL_HEADER \
- "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
+ "absl/debugging/internal/stacktrace_generic-inl.inc"
# elif defined(__ppc__) || defined(__PPC__)
-// Use glibc's backtrace.
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_generic-inl.inc"
-# elif defined(__arm__)
-# error stacktrace without frame pointer is not supported on ARM
+# else
+#define ABSL_STACKTRACE_INL_HEADER \
+ "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
# endif
#endif // NO_FRAME_POINTER
-#if !defined(ABSL_STACKTRACE_INL_HEADER)
-#error Not supported yet
+#else
+#define ABSL_STACKTRACE_INL_HEADER \
+ "absl/debugging/internal/stacktrace_unimplemented-inl.inc"
+
#endif
#endif // ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc
index 297bdad..860ac2b 100644
--- a/absl/debugging/internal/stacktrace_powerpc-inl.inc
+++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc
@@ -31,6 +31,8 @@
#include <cstdint>
#include <cstdio>
+#include "absl/base/attributes.h"
+#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/internal/address_is_readable.h"
@@ -150,8 +152,9 @@
}
// This ensures that absl::GetStackTrace sets up the Link Register properly.
-void StacktracePowerPCDummyFunction() __attribute__((noinline));
-void StacktracePowerPCDummyFunction() { __asm__ volatile(""); }
+ABSL_ATTRIBUTE_NOINLINE static void AbslStacktracePowerPCDummyFunction() {
+ ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
+}
template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS // May read random elements from stack.
@@ -176,7 +179,7 @@
// want here. While the compiler will always(?) set up LR for
// subroutine calls, it may not for leaf functions (such as this one).
// This routine forces the compiler (at least gcc) to push it anyway.
- StacktracePowerPCDummyFunction();
+ AbslStacktracePowerPCDummyFunction();
// The LR save area is used by the callee, so the top entry is bogus.
skip_count++;
diff --git a/absl/memory/memory.h b/absl/memory/memory.h
index c43e156..c7caf8b 100644
--- a/absl/memory/memory.h
+++ b/absl/memory/memory.h
@@ -83,7 +83,11 @@
} // namespace memory_internal
-#if __cplusplus >= 201402L || defined(_MSC_VER)
+// gcc 4.8 has __cplusplus at 201301 but doesn't define make_unique. Other
+// supported compilers either just define __cplusplus as 201103 but have
+// make_unique (msvc), or have make_unique whenever __cplusplus > 201103 (clang)
+#if (__cplusplus > 201103L || defined(_MSC_VER)) && \
+ !(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 8)
using std::make_unique;
#else
// -----------------------------------------------------------------------------
@@ -637,38 +641,56 @@
#endif
namespace memory_internal {
-// TODO(b110200014): Implement proper backports
-template <typename ForwardIt>
-void DefaultConstruct(ForwardIt it) {
- using value_type = typename std::iterator_traits<ForwardIt>::value_type;
- ::new (static_cast<void*>(std::addressof(*it))) value_type;
-} // namespace memory_internal
-
#ifdef ABSL_HAVE_EXCEPTIONS
-template <typename ForwardIt, typename Size>
-void uninitialized_default_construct_n(ForwardIt first, Size size) {
- for (ForwardIt cur = first; size > 0; static_cast<void>(++cur), --size) {
+template <typename Allocator, typename StorageElement, typename... Args>
+void ConstructStorage(Allocator* alloc, StorageElement* first,
+ StorageElement* last, const Args&... args) {
+ for (StorageElement* cur = first; cur != last; ++cur) {
try {
- absl::memory_internal::DefaultConstruct(cur);
+ std::allocator_traits<Allocator>::construct(*alloc, cur, args...);
} catch (...) {
- using value_type = typename std::iterator_traits<ForwardIt>::value_type;
- for (; first != cur; ++first) {
- first->~value_type();
+ while (cur != first) {
+ --cur;
+ std::allocator_traits<Allocator>::destroy(*alloc, cur);
+ }
+ throw;
+ }
+ }
+}
+template <typename Allocator, typename StorageElement, typename Iterator>
+void CopyToStorageFromRange(Allocator* alloc, StorageElement* destination,
+ Iterator first, Iterator last) {
+ for (StorageElement* cur = destination; first != last;
+ static_cast<void>(++cur), static_cast<void>(++first)) {
+ try {
+ std::allocator_traits<Allocator>::construct(*alloc, cur, *first);
+ } catch (...) {
+ while (cur != destination) {
+ --cur;
+ std::allocator_traits<Allocator>::destroy(*alloc, cur);
}
throw;
}
}
}
#else // ABSL_HAVE_EXCEPTIONS
-template <typename ForwardIt, typename Size>
-void uninitialized_default_construct_n(ForwardIt first, Size size) {
- for (; size > 0; static_cast<void>(++first), --size) {
- absl::memory_internal::DefaultConstruct(first);
+template <typename Allocator, typename StorageElement, typename... Args>
+void ConstructStorage(Allocator* alloc, StorageElement* first,
+ StorageElement* last, const Args&... args) {
+ for (; first != last; ++first) {
+ std::allocator_traits<Allocator>::construct(*alloc, first, args...);
+ }
+}
+template <typename Allocator, typename StorageElement, typename Iterator>
+void CopyToStorageFromRange(Allocator* alloc, StorageElement* destination,
+ Iterator first, Iterator last) {
+ for (; first != last;
+ static_cast<void>(++destination), static_cast<void>(++first)) {
+ std::allocator_traits<Allocator>::construct(*alloc, destination, *first);
}
}
#endif // ABSL_HAVE_EXCEPTIONS
} // namespace memory_internal
-
} // namespace absl
#endif // ABSL_MEMORY_MEMORY_H_
diff --git a/absl/memory/memory_exception_safety_test.cc b/absl/memory/memory_exception_safety_test.cc
index fb8b561..d1f6e84 100644
--- a/absl/memory/memory_exception_safety_test.cc
+++ b/absl/memory/memory_exception_safety_test.cc
@@ -48,16 +48,5 @@
}));
}
-TEST(MemoryInternal, UninitDefaultConstructNNonTrivial) {
- EXPECT_TRUE(testing::MakeExceptionSafetyTester()
- .WithInitialValue(ThrowerList{})
- .WithOperation([&](ThrowerList* list_ptr) {
- absl::memory_internal::uninitialized_default_construct_n(
- list_ptr->data(), kLength);
- })
- .WithInvariants([&](...) { return true; })
- .Test());
-}
-
} // namespace
} // namespace absl
diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc
index 8ff1945..dee9b48 100644
--- a/absl/memory/memory_test.cc
+++ b/absl/memory/memory_test.cc
@@ -611,47 +611,4 @@
EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value);
}
-TEST(MemoryInternal, UninitDefaultConstructNTrivial) {
- constexpr int kInitialValue = 123;
- constexpr int kExpectedValue = kInitialValue; // Expect no-op behavior
- constexpr int len = 5;
-
- struct TestObj {
- int val;
- };
- static_assert(absl::is_trivially_default_constructible<TestObj>::value, "");
- static_assert(absl::is_trivially_destructible<TestObj>::value, "");
-
- TestObj objs[len];
- for (auto& obj : objs) {
- obj.val = kInitialValue;
- }
-
- absl::memory_internal::uninitialized_default_construct_n(objs, len);
- for (auto& obj : objs) {
- EXPECT_EQ(obj.val, kExpectedValue);
- }
-}
-
-TEST(MemoryInternal, UninitDefaultConstructNNonTrivial) {
- constexpr int kInitialValue = 123;
- constexpr int kExpectedValue = 0; // Expect value-construction behavior
- constexpr int len = 5;
-
- struct TestObj {
- int val{kExpectedValue};
- };
- static_assert(absl::is_trivially_destructible<TestObj>::value, "");
-
- TestObj objs[len];
- for (auto& obj : objs) {
- obj.val = kInitialValue;
- }
-
- absl::memory_internal::uninitialized_default_construct_n(objs, len);
- for (auto& obj : objs) {
- EXPECT_EQ(obj.val, kExpectedValue);
- }
-}
-
} // namespace
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h
index c3e01fe..457b890 100644
--- a/absl/meta/type_traits.h
+++ b/absl/meta/type_traits.h
@@ -44,6 +44,7 @@
namespace absl {
namespace type_traits_internal {
+
template <typename... Ts>
struct VoidTImpl {
using type = void;
@@ -61,6 +62,49 @@
static constexpr size_t value = Align;
};
+////////////////////////////////
+// Library Fundamentals V2 TS //
+////////////////////////////////
+
+// NOTE: The `is_detected` family of templates here differ from the library
+// fundamentals specification in that for library fundamentals, `Op<Args...>` is
+// evaluated as soon as the type `is_detected<Op, Args...>` undergoes
+// substitution, regardless of whether or not the `::value` is accessed. That
+// is inconsistent with all other standard traits and prevents lazy evaluation
+// in larger contexts (such as if the `is_detected` check is a trailing argument
+// of a `conjunction`. This implementation opts to instead be lazy in the same
+// way that the standard traits are (this "defect" of the detection idiom
+// specifications has been reported).
+
+template <class Enabler, template <class...> class Op, class... Args>
+struct is_detected_impl {
+ using type = std::false_type;
+};
+
+template <template <class...> class Op, class... Args>
+struct is_detected_impl<typename VoidTImpl<Op<Args...>>::type, Op, Args...> {
+ using type = std::true_type;
+};
+
+template <template <class...> class Op, class... Args>
+struct is_detected : is_detected_impl<void, Op, Args...>::type {};
+
+template <class Enabler, class To, template <class...> class Op, class... Args>
+struct is_detected_convertible_impl {
+ using type = std::false_type;
+};
+
+template <class To, template <class...> class Op, class... Args>
+struct is_detected_convertible_impl<
+ typename std::enable_if<std::is_convertible<Op<Args...>, To>::value>::type,
+ To, Op, Args...> {
+ using type = std::true_type;
+};
+
+template <class To, template <class...> class Op, class... Args>
+struct is_detected_convertible
+ : is_detected_convertible_impl<void, To, Op, Args...>::type {};
+
} // namespace type_traits_internal
// void_t()
@@ -263,8 +307,9 @@
// `is_trivially_assignable<T&, const T&>`.
template <typename T>
struct is_trivially_copy_assignable
- : std::integral_constant<bool, __has_trivial_assign(T) &&
- std::is_copy_assignable<T>::value> {
+ : std::integral_constant<
+ bool, __has_trivial_assign(typename std::remove_reference<T>::type) &&
+ std::is_copy_assignable<T>::value> {
#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
private:
static constexpr bool compliant =
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc
index c44d1c5..81b4bd3 100644
--- a/absl/meta/type_traits_test.cc
+++ b/absl/meta/type_traits_test.cc
@@ -34,6 +34,83 @@
struct Dummy {};
+struct ReturnType {};
+struct ConvertibleToReturnType {
+ operator ReturnType() const; // NOLINT
+};
+
+// Unique types used as parameter types for testing the detection idiom.
+struct StructA {};
+struct StructB {};
+struct StructC {};
+
+struct TypeWithBarFunction {
+ template <class T,
+ absl::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0>
+ ReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT
+};
+
+struct TypeWithBarFunctionAndConvertibleReturnType {
+ template <class T,
+ absl::enable_if_t<std::is_same<T&&, StructA&>::value, int> = 0>
+ ConvertibleToReturnType bar(T&&, const StructB&, StructC&&) &&; // NOLINT
+};
+
+template <class Class, class... Ts>
+using BarIsCallableImpl =
+ decltype(std::declval<Class>().bar(std::declval<Ts>()...));
+
+template <class Class, class... T>
+using BarIsCallable =
+ absl::type_traits_internal::is_detected<BarIsCallableImpl, Class, T...>;
+
+template <class Class, class... T>
+using BarIsCallableConv = absl::type_traits_internal::is_detected_convertible<
+ ReturnType, BarIsCallableImpl, Class, T...>;
+
+// NOTE: Test of detail type_traits_internal::is_detected.
+TEST(IsDetectedTest, BasicUsage) {
+ EXPECT_TRUE((BarIsCallable<TypeWithBarFunction, StructA&, const StructB&,
+ StructC>::value));
+ EXPECT_TRUE(
+ (BarIsCallable<TypeWithBarFunction, StructA&, StructB&, StructC>::value));
+ EXPECT_TRUE(
+ (BarIsCallable<TypeWithBarFunction, StructA&, StructB, StructC>::value));
+
+ EXPECT_FALSE((BarIsCallable<int, StructA&, const StructB&, StructC>::value));
+ EXPECT_FALSE((BarIsCallable<TypeWithBarFunction&, StructA&, const StructB&,
+ StructC>::value));
+ EXPECT_FALSE((BarIsCallable<TypeWithBarFunction, StructA, const StructB&,
+ StructC>::value));
+}
+
+// NOTE: Test of detail type_traits_internal::is_detected_convertible.
+TEST(IsDetectedConvertibleTest, BasicUsage) {
+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, const StructB&,
+ StructC>::value));
+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, StructB&,
+ StructC>::value));
+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunction, StructA&, StructB,
+ StructC>::value));
+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType,
+ StructA&, const StructB&, StructC>::value));
+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType,
+ StructA&, StructB&, StructC>::value));
+ EXPECT_TRUE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType,
+ StructA&, StructB, StructC>::value));
+
+ EXPECT_FALSE(
+ (BarIsCallableConv<int, StructA&, const StructB&, StructC>::value));
+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunction&, StructA&,
+ const StructB&, StructC>::value));
+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunction, StructA, const StructB&,
+ StructC>::value));
+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType&,
+ StructA&, const StructB&, StructC>::value));
+ EXPECT_FALSE((BarIsCallableConv<TypeWithBarFunctionAndConvertibleReturnType,
+ StructA, const StructB&, StructC>::value));
+}
+
TEST(VoidTTest, BasicUsage) {
StaticAssertTypeEq<void, absl::void_t<Dummy>>();
StaticAssertTypeEq<void, absl::void_t<Dummy, Dummy, Dummy>>();
@@ -528,6 +605,10 @@
// Verify that arrays are not trivially copy assignable
using int10 = int[10];
EXPECT_FALSE(absl::is_trivially_copy_assignable<int10>::value);
+
+ // Verify that references are handled correctly
+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&&>::value);
+ EXPECT_TRUE(absl::is_trivially_copy_assignable<Trivial&>::value);
}
#define ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(trait_name, ...) \
@@ -714,8 +795,8 @@
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int[][1]);
ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int());
- ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float));
- ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...));
+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(float)); // NOLINT
+ ABSL_INTERNAL_EXPECT_ALIAS_EQUIVALENCE(decay, int(char, ...)); // NOLINT
}
struct TypeA {};
diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h
index e4f39c3..2d131b8 100644
--- a/absl/numeric/int128.h
+++ b/absl/numeric/int128.h
@@ -31,6 +31,7 @@
#include <cstring>
#include <iosfwd>
#include <limits>
+#include <utility>
#include "absl/base/config.h"
#include "absl/base/macros.h"
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 3b1e067..3a5f133 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -159,6 +159,18 @@
)
cc_test(
+ name = "ascii_benchmark",
+ srcs = ["ascii_benchmark.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = ["benchmark"],
+ visibility = ["//visibility:private"],
+ deps = [
+ ":strings",
+ "@com_github_google_benchmark//:benchmark_main",
+ ],
+)
+
+cc_test(
name = "memutil_benchmark",
srcs = [
"internal/memutil.h",
diff --git a/absl/strings/ascii_benchmark.cc b/absl/strings/ascii_benchmark.cc
new file mode 100644
index 0000000..8dea4b8
--- /dev/null
+++ b/absl/strings/ascii_benchmark.cc
@@ -0,0 +1,120 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/strings/ascii.h"
+
+#include <cctype>
+#include <string>
+#include <array>
+#include <random>
+
+#include "benchmark/benchmark.h"
+
+namespace {
+
+std::array<unsigned char, 256> MakeShuffledBytes() {
+ std::array<unsigned char, 256> bytes;
+ for (size_t i = 0; i < 256; ++i) bytes[i] = static_cast<unsigned char>(i);
+ std::random_device rd;
+ std::seed_seq seed({rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()});
+ std::mt19937 g(seed);
+ std::shuffle(bytes.begin(), bytes.end(), g);
+ return bytes;
+}
+
+template <typename Function>
+void AsciiBenchmark(benchmark::State& state, Function f) {
+ std::array<unsigned char, 256> bytes = MakeShuffledBytes();
+ size_t sum = 0;
+ for (auto _ : state) {
+ for (unsigned char b : bytes) sum += f(b) ? 1 : 0;
+ }
+ // Make a copy of `sum` before calling `DoNotOptimize` to make sure that `sum`
+ // can be put in a CPU register and not degrade performance in the loop above.
+ size_t sum2 = sum;
+ benchmark::DoNotOptimize(sum2);
+ state.SetBytesProcessed(state.iterations() * bytes.size());
+}
+
+using StdAsciiFunction = int (*)(int);
+template <StdAsciiFunction f>
+void BM_Ascii(benchmark::State& state) {
+ AsciiBenchmark(state, f);
+}
+
+using AbslAsciiIsFunction = bool (*)(unsigned char);
+template <AbslAsciiIsFunction f>
+void BM_Ascii(benchmark::State& state) {
+ AsciiBenchmark(state, f);
+}
+
+using AbslAsciiToFunction = char (*)(unsigned char);
+template <AbslAsciiToFunction f>
+void BM_Ascii(benchmark::State& state) {
+ AsciiBenchmark(state, f);
+}
+
+inline char Noop(unsigned char b) { return static_cast<char>(b); }
+
+BENCHMARK_TEMPLATE(BM_Ascii, Noop);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isalpha);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isalpha);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isdigit);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isdigit);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isalnum);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isalnum);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isspace);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isspace);
+BENCHMARK_TEMPLATE(BM_Ascii, std::ispunct);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_ispunct);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isblank);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isblank);
+BENCHMARK_TEMPLATE(BM_Ascii, std::iscntrl);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_iscntrl);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isxdigit);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isxdigit);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isprint);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isprint);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isgraph);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isgraph);
+BENCHMARK_TEMPLATE(BM_Ascii, std::isupper);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isupper);
+BENCHMARK_TEMPLATE(BM_Ascii, std::islower);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_islower);
+BENCHMARK_TEMPLATE(BM_Ascii, isascii);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_isascii);
+BENCHMARK_TEMPLATE(BM_Ascii, std::tolower);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_tolower);
+BENCHMARK_TEMPLATE(BM_Ascii, std::toupper);
+BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_toupper);
+
+static void BM_StrToLower(benchmark::State& state) {
+ const int size = state.range(0);
+ std::string s(size, 'X');
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(absl::AsciiStrToLower(s));
+ }
+}
+BENCHMARK(BM_StrToLower)->Range(1, 1 << 20);
+
+static void BM_StrToUpper(benchmark::State& state) {
+ const int size = state.range(0);
+ std::string s(size, 'x');
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(absl::AsciiStrToUpper(s));
+ }
+}
+BENCHMARK(BM_StrToUpper)->Range(1, 1 << 20);
+
+} // namespace
diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h
index 1af0afa..7f1ab96 100644
--- a/absl/strings/escaping.h
+++ b/absl/strings/escaping.h
@@ -139,7 +139,7 @@
// WebSafeBase64Escape()
//
-// Encodes a `src` std::string into a `dest` buffer using uses '-' instead of '+' and
+// Encodes a `src` std::string into a `dest` buffer using '-' instead of '+' and
// '_' instead of '/', and without padding. This function conforms with RFC 4648
// section 5 (base64url).
void WebSafeBase64Escape(absl::string_view src, std::string* dest);
diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc
index 37952b4..6176db9 100644
--- a/absl/strings/internal/str_format/float_conversion.cc
+++ b/absl/strings/internal/str_format/float_conversion.cc
@@ -153,7 +153,14 @@
template <typename Float, typename Int>
constexpr bool CanFitMantissa() {
- return std::numeric_limits<Float>::digits <= std::numeric_limits<Int>::digits;
+ return
+#if defined(__clang__) && !defined(__SSE3__)
+ // Workaround for clang bug: https://bugs.llvm.org/show_bug.cgi?id=38289
+ // Casting from long double to uint64_t is miscompiled and drops bits.
+ (!std::is_same<Float, long double>::value ||
+ !std::is_same<Int, uint64_t>::value) &&
+#endif
+ std::numeric_limits<Float>::digits <= std::numeric_limits<Int>::digits;
}
template <typename Float>
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index 24e7138..27cc047 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -56,16 +56,11 @@
using testing::MatchesRegex;
// Number of floats to test with.
-// 10,000,000 is a reasonable default for a test that only takes a few seconds.
+// 5,000,000 is a reasonable default for a test that only takes a few seconds.
// 1,000,000,000+ triggers checking for all possible mantissa values for
// double-precision tests. 2,000,000,000+ triggers checking for every possible
// single-precision float.
-#ifdef _MSC_VER
-// Use a smaller number on MSVC to avoid test time out (1 min)
const int kFloatNumCases = 5000000;
-#else
-const int kFloatNumCases = 10000000;
-#endif
// This is a slow, brute-force routine to compute the exact base-10
// representation of a double-precision floating-point number. It
@@ -716,8 +711,9 @@
}
}
-// feenableexcept() and fedisableexcept() are missing on Mac OS X, MSVC.
-#if defined(_MSC_VER) || defined(__APPLE__)
+// feenableexcept() and fedisableexcept() are missing on Mac OS X, MSVC,
+// and WebAssembly.
+#if defined(_MSC_VER) || defined(__APPLE__) || defined(__EMSCRIPTEN__)
#define ABSL_MISSING_FEENABLEEXCEPT 1
#define ABSL_MISSING_FEDISABLEEXCEPT 1
#endif
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc
index fe742bf..fed75fa 100644
--- a/absl/strings/str_format_test.cc
+++ b/absl/strings/str_format_test.cc
@@ -384,8 +384,8 @@
EXPECT_EQ(StrFormat("%G", 1e10), "1E+10");
// a/A - lower,upper case hex Eg: -3.0 -> "-0x1.8p+1"/"-0X1.8P+1"
-// On NDK r16, there is a regression in hexfloat formatting.
-#if !defined(__NDK_MAJOR__) || __NDK_MAJOR__ != 16
+// On Android platform <=21, there is a regression in hexfloat formatting.
+#if !defined(__ANDROID_API__) || __ANDROID_API__ > 21
EXPECT_EQ(StrFormat("%.1a", -3.0), "-0x1.8p+1"); // .1 to fix MSVC output
EXPECT_EQ(StrFormat("%.1A", -3.0), "-0X1.8P+1"); // .1 to fix MSVC output
#endif
diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h
index 1f089b9..9a7be2b 100644
--- a/absl/strings/str_split.h
+++ b/absl/strings/str_split.h
@@ -373,11 +373,11 @@
// StrSplit()
//
-// Splits a given `std::string` based on the provided `Delimiter` object,
-// returning the elements within the type specified by the caller. Optionally,
-// you may also pass a `Predicate` to `StrSplit()` indicating whether to include
-// or exclude the resulting element within the final result set. (See the
-// overviews for Delimiters and Predicates above.)
+// Splits a given std::string based on the provided `Delimiter` object, returning the
+// elements within the type specified by the caller. Optionally, you may pass a
+// `Predicate` to `StrSplit()` indicating whether to include or exclude the
+// resulting element within the final result set. (See the overviews for
+// Delimiters and Predicates above.)
//
// Example:
//
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt
index c19f572..de0d7b7 100644
--- a/absl/synchronization/CMakeLists.txt
+++ b/absl/synchronization/CMakeLists.txt
@@ -34,7 +34,7 @@
# synchronization library
-list(APPEND SYNCHRONIZATION_SRC
+list(APPEND SYNCHRONIZATION_SRC
"barrier.cc"
"blocking_counter.cc"
"internal/create_thread_identity.cc"
diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h
index 0d132d9..bb70800 100644
--- a/absl/synchronization/internal/kernel_timeout.h
+++ b/absl/synchronization/internal/kernel_timeout.h
@@ -25,9 +25,6 @@
#ifndef ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
-#ifdef _WIN32
-#include <intsafe.h>
-#endif
#include <time.h>
#include <algorithm>
#include <limits>
@@ -117,9 +114,14 @@
// Windows. Callers should recognize that the return value is a
// relative duration (it should be recomputed by calling this method
// in the case of a spurious wakeup).
- DWORD InMillisecondsFromNow() const {
+ // This header file may be included transitively by public header files,
+ // so we define our own DWORD and INFINITE instead of getting them from
+ // <intsafe.h> and <WinBase.h>.
+ typedef unsigned long DWord; // NOLINT
+ DWord InMillisecondsFromNow() const {
+ constexpr DWord kInfinite = std::numeric_limits<DWord>::max();
if (!has_timeout()) {
- return INFINITE;
+ return kInfinite;
}
// The use of absl::Now() to convert from absolute time to
// relative time means that absl::Now() cannot use anything that
@@ -131,10 +133,10 @@
std::numeric_limits<int64_t>::max() - 999999u;
uint64_t ms_from_now =
(std::min<uint64_t>(max_nanos, ns_ - now) + 999999u) / 1000000u;
- if (ms_from_now > std::numeric_limits<DWORD>::max()) {
- return INFINITE;
+ if (ms_from_now > kInfinite) {
+ return kInfinite;
}
- return static_cast<DWORD>(ms_from_now);
+ return static_cast<DWord>(ms_from_now);
}
return 0;
}
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index 840b9d6..83c2148 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -24,7 +24,7 @@
// Unlike a `std::mutex`, the Abseil `Mutex` provides the following additional
// features:
// * Conditional predicates intrinsic to the `Mutex` object
-// * Reader/writer locks, in addition to standard exclusive/writer locks
+// * Shared/reader locks, in addition to standard exclusive/writer locks
// * Deadlock detection and debug support.
//
// The following helper classes are also defined within this file:
@@ -290,7 +290,7 @@
// Mutex::ReaderLockWhen()
// Mutex::WriterLockWhen()
//
- // Blocks until simultaneously both `cond` is `true` and this` Mutex` can
+ // Blocks until simultaneously both `cond` is `true` and this `Mutex` can
// be acquired, then atomically acquires this `Mutex`. `LockWhen()` is
// logically equivalent to `*Lock(); Await();` though they may have different
// performance characteristics.
@@ -558,7 +558,7 @@
// WriterMutexLock
//
// The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and
-// releases a write (exclusive) lock on a `Mutex` va RAII.
+// releases a write (exclusive) lock on a `Mutex` via RAII.
class SCOPED_LOCKABLE WriterMutexLock {
public:
explicit WriterMutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu)
diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc
index 30a5235..1e019e0 100644
--- a/absl/synchronization/mutex_benchmark.cc
+++ b/absl/synchronization/mutex_benchmark.cc
@@ -74,11 +74,11 @@
mu.Unlock();
}
-#ifdef THREAD_SANITIZER
-// ThreadSanitizer can't handle 8192 threads.
-constexpr int kMaxConditionWaiters = 2048;
-#else
+// Some configurations have higher thread limits than others.
+#if defined(__linux__) && !defined(THREAD_SANITIZER)
constexpr int kMaxConditionWaiters = 8192;
+#else
+constexpr int kMaxConditionWaiters = 1024;
#endif
BENCHMARK(BM_ConditionWaiters)->RangePair(0, 2, 1, kMaxConditionWaiters);
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc
index 53b9378..b2820e2 100644
--- a/absl/synchronization/mutex_test.cc
+++ b/absl/synchronization/mutex_test.cc
@@ -29,6 +29,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/memory/memory.h"
@@ -54,8 +55,8 @@
// Hack to schedule a function to run on a thread pool thread after a
// duration has elapsed.
static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp,
- const std::function<void()> &func,
- absl::Duration after) {
+ absl::Duration after,
+ const std::function<void()> &func) {
tp->Schedule([func, after] {
absl::SleepFor(after);
func();
@@ -1150,249 +1151,369 @@
// and so never expires/passes, and one that will expire/pass in the near
// future.
-// Encapsulate a Mutex-protected bool with its associated Condition/CondVar.
-class Cond {
- public:
- explicit Cond(bool use_deadline) : use_deadline_(use_deadline), c_(&b_) {}
+static absl::Duration TimeoutTestAllowedSchedulingDelay() {
+ // Note: we use a function here because Microsoft Visual Studio fails to
+ // properly initialize constexpr static absl::Duration variables.
+ return absl::Milliseconds(150);
+}
- void Set(bool v) {
- absl::MutexLock lock(&mu_);
- b_ = v;
+// Returns true if `actual_delay` is close enough to `expected_delay` to pass
+// the timeouts/deadlines test. Otherwise, logs warnings and returns false.
+ABSL_MUST_USE_RESULT
+static bool DelayIsWithinBounds(absl::Duration expected_delay,
+ absl::Duration actual_delay) {
+ bool pass = true;
+ // Do not allow the observed delay to be less than expected. This may occur
+ // in practice due to clock skew or when the synchronization primitives use a
+ // different clock than absl::Now(), but these cases should be handled by the
+ // the retry mechanism in each TimeoutTest.
+ if (actual_delay < expected_delay) {
+ ABSL_RAW_LOG(WARNING,
+ "Actual delay %s was too short, expected %s (difference %s)",
+ absl::FormatDuration(actual_delay).c_str(),
+ absl::FormatDuration(expected_delay).c_str(),
+ absl::FormatDuration(actual_delay - expected_delay).c_str());
+ pass = false;
}
-
- bool AwaitWithTimeout(absl::Duration timeout) {
- absl::MutexLock lock(&mu_);
- return use_deadline_ ? mu_.AwaitWithDeadline(c_, absl::Now() + timeout)
- : mu_.AwaitWithTimeout(c_, timeout);
+ // If the expected delay is <= zero then allow a small error tolerance, since
+ // we do not expect context switches to occur during test execution.
+ // Otherwise, thread scheduling delays may be substantial in rare cases, so
+ // tolerate up to kTimeoutTestAllowedSchedulingDelay of error.
+ absl::Duration tolerance = expected_delay <= absl::ZeroDuration()
+ ? absl::Milliseconds(10)
+ : TimeoutTestAllowedSchedulingDelay();
+ if (actual_delay > expected_delay + tolerance) {
+ ABSL_RAW_LOG(WARNING,
+ "Actual delay %s was too long, expected %s (difference %s)",
+ absl::FormatDuration(actual_delay).c_str(),
+ absl::FormatDuration(expected_delay).c_str(),
+ absl::FormatDuration(actual_delay - expected_delay).c_str());
+ pass = false;
}
+ return pass;
+}
- bool LockWhenWithTimeout(absl::Duration timeout) {
- bool b = use_deadline_ ? mu_.LockWhenWithDeadline(c_, absl::Now() + timeout)
- : mu_.LockWhenWithTimeout(c_, timeout);
- mu_.Unlock();
- return b;
- }
+// Parameters for TimeoutTest, below.
+struct TimeoutTestParam {
+ // The file and line number (used for logging purposes only).
+ const char *from_file;
+ int from_line;
- bool ReaderLockWhenWithTimeout(absl::Duration timeout) {
- bool b = use_deadline_
- ? mu_.ReaderLockWhenWithDeadline(c_, absl::Now() + timeout)
- : mu_.ReaderLockWhenWithTimeout(c_, timeout);
- mu_.ReaderUnlock();
- return b;
- }
+ // Should the absolute deadline API based on absl::Time be tested? If false,
+ // the relative deadline API based on absl::Duration is tested.
+ bool use_absolute_deadline;
- void Await() {
- absl::MutexLock lock(&mu_);
- mu_.Await(c_);
- }
+ // The deadline/timeout used when calling the API being tested
+ // (e.g. Mutex::LockWhenWithDeadline).
+ absl::Duration wait_timeout;
- void Signal(bool v) {
- absl::MutexLock lock(&mu_);
- b_ = v;
- cv_.Signal();
- }
+ // The delay before the condition will be set true by the test code. If zero
+ // or negative, the condition is set true immediately (before calling the API
+ // being tested). Otherwise, if infinite, the condition is never set true.
+ // Otherwise a closure is scheduled for the future that sets the condition
+ // true.
+ absl::Duration satisfy_condition_delay;
- bool WaitWithTimeout(absl::Duration timeout) {
- absl::MutexLock lock(&mu_);
- absl::Time deadline = absl::Now() + timeout;
- if (use_deadline_) {
- while (!b_ && !cv_.WaitWithDeadline(&mu_, deadline)) {
- }
- } else {
- while (!b_ && !cv_.WaitWithTimeout(&mu_, timeout)) {
- timeout = deadline - absl::Now(); // recompute timeout
- }
- }
- return b_;
- }
+ // The expected result of the condition after the call to the API being
+ // tested. Generally `true` means the condition was true when the API returns,
+ // `false` indicates an expected timeout.
+ bool expected_result;
- void Wait() {
- absl::MutexLock lock(&mu_);
- while (!b_) cv_.Wait(&mu_);
- }
-
- private:
- const bool use_deadline_;
-
- bool b_;
- absl::Condition c_;
- absl::CondVar cv_;
- absl::Mutex mu_;
+ // The expected delay before the API under test returns. This is inherently
+ // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the
+ // test keeps trying indefinitely until this constraint passes.
+ absl::Duration expected_delay;
};
-class OperationTimer {
- public:
- OperationTimer() : start_(absl::Now()) {}
- absl::Duration Get() const { return absl::Now() - start_; }
+// Print a `TimeoutTestParam` to a debug log.
+std::ostream &operator<<(std::ostream &os, const TimeoutTestParam ¶m) {
+ return os << "from: " << param.from_file << ":" << param.from_line
+ << " use_absolute_deadline: "
+ << (param.use_absolute_deadline ? "true" : "false")
+ << " wait_timeout: " << param.wait_timeout
+ << " satisfy_condition_delay: " << param.satisfy_condition_delay
+ << " expected_result: "
+ << (param.expected_result ? "true" : "false")
+ << " expected_delay: " << param.expected_delay;
+}
- private:
- const absl::Time start_;
-};
+std::string FormatString(const TimeoutTestParam ¶m) {
+ std::ostringstream os;
+ os << param;
+ return os.str();
+}
-static void CheckResults(bool exp_result, bool act_result,
- absl::Duration exp_duration,
- absl::Duration act_duration) {
- ABSL_RAW_CHECK(exp_result == act_result, "CheckResults failed");
- // Allow for some worse-case scheduling delay and clock skew.
- if ((exp_duration - absl::Milliseconds(40) > act_duration) ||
- (exp_duration + absl::Milliseconds(150) < act_duration)) {
- ABSL_RAW_LOG(FATAL, "CheckResults failed: operation took %s, expected %s",
- absl::FormatDuration(act_duration).c_str(),
- absl::FormatDuration(exp_duration).c_str());
+// Like `thread::Executor::ScheduleAt` except:
+// a) Delays zero or negative are executed immediately in the current thread.
+// b) Infinite delays are never scheduled.
+// c) Calls this test's `ScheduleAt` helper instead of using `pool` directly.
+static void RunAfterDelay(absl::Duration delay,
+ absl::synchronization_internal::ThreadPool *pool,
+ const std::function<void()> &callback) {
+ if (delay <= absl::ZeroDuration()) {
+ callback(); // immediate
+ } else if (delay != absl::InfiniteDuration()) {
+ ScheduleAfter(pool, delay, callback);
}
}
-static void TestAwaitTimeout(Cond *cp, absl::Duration timeout, bool exp_result,
- absl::Duration exp_duration) {
- OperationTimer t;
- bool act_result = cp->AwaitWithTimeout(timeout);
- CheckResults(exp_result, act_result, exp_duration, t.Get());
-}
+class TimeoutTest : public ::testing::Test,
+ public ::testing::WithParamInterface<TimeoutTestParam> {};
-static void TestLockWhenTimeout(Cond *cp, absl::Duration timeout,
- bool exp_result, absl::Duration exp_duration) {
- OperationTimer t;
- bool act_result = cp->LockWhenWithTimeout(timeout);
- CheckResults(exp_result, act_result, exp_duration, t.Get());
-}
-
-static void TestReaderLockWhenTimeout(Cond *cp, absl::Duration timeout,
- bool exp_result,
- absl::Duration exp_duration) {
- OperationTimer t;
- bool act_result = cp->ReaderLockWhenWithTimeout(timeout);
- CheckResults(exp_result, act_result, exp_duration, t.Get());
-}
-
-static void TestWaitTimeout(Cond *cp, absl::Duration timeout, bool exp_result,
- absl::Duration exp_duration) {
- OperationTimer t;
- bool act_result = cp->WaitWithTimeout(timeout);
- CheckResults(exp_result, act_result, exp_duration, t.Get());
-}
-
-// Tests with a negative timeout (deadline in the past), which should
-// immediately return the current state of the condition.
-static void TestNegativeTimeouts(absl::synchronization_internal::ThreadPool *tp,
- Cond *cp) {
+std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
+ // The `finite` delay is a finite, relatively short, delay. We make it larger
+ // than our allowed scheduling delay (slop factor) to avoid confusion when
+ // diagnosing test failures. The other constants here have clear meanings.
+ const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
+ const absl::Duration never = absl::InfiniteDuration();
const absl::Duration negative = -absl::InfiniteDuration();
const absl::Duration immediate = absl::ZeroDuration();
- // The condition is already true:
- cp->Set(true);
- TestAwaitTimeout(cp, negative, true, immediate);
- TestLockWhenTimeout(cp, negative, true, immediate);
- TestReaderLockWhenTimeout(cp, negative, true, immediate);
- TestWaitTimeout(cp, negative, true, immediate);
+ // Every test case is run twice; once using the absolute deadline API and once
+ // using the relative timeout API.
+ std::vector<TimeoutTestParam> values;
+ for (bool use_absolute_deadline : {false, true}) {
+ // Tests with a negative timeout (deadline in the past), which should
+ // immediately return current state of the condition.
- // The condition becomes true, but the timeout has already expired:
- const absl::Duration delay = absl::Milliseconds(200);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), 3 * delay);
- TestAwaitTimeout(cp, negative, false, immediate);
- TestLockWhenTimeout(cp, negative, false, immediate);
- TestReaderLockWhenTimeout(cp, negative, false, immediate);
- cp->Await(); // wait for the scheduled Set() to complete
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay);
- TestWaitTimeout(cp, negative, false, immediate);
- cp->Wait(); // wait for the scheduled Signal() to complete
+ // The condition is already true:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ negative, // wait_timeout
+ immediate, // satisfy_condition_delay
+ true, // expected_result
+ immediate, // expected_delay
+ });
- // The condition never becomes true:
- cp->Set(false);
- TestAwaitTimeout(cp, negative, false, immediate);
- TestLockWhenTimeout(cp, negative, false, immediate);
- TestReaderLockWhenTimeout(cp, negative, false, immediate);
- TestWaitTimeout(cp, negative, false, immediate);
+ // The condition becomes true, but the timeout has already expired:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ negative, // wait_timeout
+ finite, // satisfy_condition_delay
+ false, // expected_result
+ immediate // expected_delay
+ });
+
+ // The condition never becomes true:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ negative, // wait_timeout
+ never, // satisfy_condition_delay
+ false, // expected_result
+ immediate // expected_delay
+ });
+
+ // Tests with an infinite timeout (deadline in the infinite future), which
+ // should only return when the condition becomes true.
+
+ // The condition is already true:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ never, // wait_timeout
+ immediate, // satisfy_condition_delay
+ true, // expected_result
+ immediate // expected_delay
+ });
+
+ // The condition becomes true before the (infinite) expiry:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ never, // wait_timeout
+ finite, // satisfy_condition_delay
+ true, // expected_result
+ finite, // expected_delay
+ });
+
+ // Tests with a (small) finite timeout (deadline soon), with the condition
+ // becoming true both before and after its expiry.
+
+ // The condition is already true:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ never, // wait_timeout
+ immediate, // satisfy_condition_delay
+ true, // expected_result
+ immediate // expected_delay
+ });
+
+ // The condition becomes true before the expiry:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ finite * 2, // wait_timeout
+ finite, // satisfy_condition_delay
+ true, // expected_result
+ finite // expected_delay
+ });
+
+ // The condition becomes true, but the timeout has already expired:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ finite, // wait_timeout
+ finite * 2, // satisfy_condition_delay
+ false, // expected_result
+ finite // expected_delay
+ });
+
+ // The condition never becomes true:
+ values.push_back(TimeoutTestParam{
+ __FILE__, __LINE__, use_absolute_deadline,
+ finite, // wait_timeout
+ never, // satisfy_condition_delay
+ false, // expected_result
+ finite // expected_delay
+ });
+ }
+ return values;
}
-// Tests with an infinite timeout (deadline in the infinite future), which
-// should only return when the condition becomes true.
-static void TestInfiniteTimeouts(absl::synchronization_internal::ThreadPool *tp,
- Cond *cp) {
- const absl::Duration infinite = absl::InfiniteDuration();
- const absl::Duration immediate = absl::ZeroDuration();
+// Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`.
+INSTANTIATE_TEST_CASE_P(All, TimeoutTest,
+ testing::ValuesIn(MakeTimeoutTestParamValues()));
- // The condition is already true:
- cp->Set(true);
- TestAwaitTimeout(cp, infinite, true, immediate);
- TestLockWhenTimeout(cp, infinite, true, immediate);
- TestReaderLockWhenTimeout(cp, infinite, true, immediate);
- TestWaitTimeout(cp, infinite, true, immediate);
+TEST_P(TimeoutTest, Await) {
+ const TimeoutTestParam params = GetParam();
+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
- // The condition becomes true before the (infinite) expiry:
- const absl::Duration delay = absl::Milliseconds(200);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay);
- TestAwaitTimeout(cp, infinite, true, delay);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay);
- TestLockWhenTimeout(cp, infinite, true, delay);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay);
- TestReaderLockWhenTimeout(cp, infinite, true, delay);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay);
- TestWaitTimeout(cp, infinite, true, delay);
+ // Because this test asserts bounds on scheduling delays it is flaky. To
+ // compensate it loops forever until it passes. Failures express as test
+ // timeouts, in which case the test log can be used to diagnose the issue.
+ for (int attempt = 1;; ++attempt) {
+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+
+ absl::Mutex mu;
+ bool value = false; // condition value (under mu)
+
+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
+ CreateDefaultPool();
+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
+ absl::MutexLock l(&mu);
+ value = true;
+ });
+
+ absl::MutexLock lock(&mu);
+ absl::Time start_time = absl::Now();
+ absl::Condition cond(&value);
+ bool result =
+ params.use_absolute_deadline
+ ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout)
+ : mu.AwaitWithTimeout(cond, params.wait_timeout);
+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
+ EXPECT_EQ(params.expected_result, result);
+ break;
+ }
+ }
}
-// Tests with a (small) finite timeout (deadline soon), with the condition
-// becoming true both before and after its expiry.
-static void TestFiniteTimeouts(absl::synchronization_internal::ThreadPool *tp,
- Cond *cp) {
- const absl::Duration finite = absl::Milliseconds(400);
- const absl::Duration immediate = absl::ZeroDuration();
+TEST_P(TimeoutTest, LockWhen) {
+ const TimeoutTestParam params = GetParam();
+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
- // The condition is already true:
- cp->Set(true);
- TestAwaitTimeout(cp, finite, true, immediate);
- TestLockWhenTimeout(cp, finite, true, immediate);
- TestReaderLockWhenTimeout(cp, finite, true, immediate);
- TestWaitTimeout(cp, finite, true, immediate);
+ // Because this test asserts bounds on scheduling delays it is flaky. To
+ // compensate it loops forever until it passes. Failures express as test
+ // timeouts, in which case the test log can be used to diagnose the issue.
+ for (int attempt = 1;; ++attempt) {
+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
- // The condition becomes true before the expiry:
- const absl::Duration delay1 = finite / 2;
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay1);
- TestAwaitTimeout(cp, finite, true, delay1);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay1);
- TestLockWhenTimeout(cp, finite, true, delay1);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay1);
- TestReaderLockWhenTimeout(cp, finite, true, delay1);
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay1);
- TestWaitTimeout(cp, finite, true, delay1);
+ absl::Mutex mu;
+ bool value = false; // condition value (under mu)
- // The condition becomes true, but the timeout has already expired:
- const absl::Duration delay2 = finite * 2;
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), 3 * delay2);
- TestAwaitTimeout(cp, finite, false, finite);
- TestLockWhenTimeout(cp, finite, false, finite);
- TestReaderLockWhenTimeout(cp, finite, false, finite);
- cp->Await(); // wait for the scheduled Set() to complete
- cp->Set(false);
- ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay2);
- TestWaitTimeout(cp, finite, false, finite);
- cp->Wait(); // wait for the scheduled Signal() to complete
+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
+ CreateDefaultPool();
+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
+ absl::MutexLock l(&mu);
+ value = true;
+ });
- // The condition never becomes true:
- cp->Set(false);
- TestAwaitTimeout(cp, finite, false, finite);
- TestLockWhenTimeout(cp, finite, false, finite);
- TestReaderLockWhenTimeout(cp, finite, false, finite);
- TestWaitTimeout(cp, finite, false, finite);
+ absl::Time start_time = absl::Now();
+ absl::Condition cond(&value);
+ bool result =
+ params.use_absolute_deadline
+ ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
+ : mu.LockWhenWithTimeout(cond, params.wait_timeout);
+ mu.Unlock();
+
+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
+ EXPECT_EQ(params.expected_result, result);
+ break;
+ }
+ }
}
-TEST(Mutex, Timeouts) {
- auto tp = CreateDefaultPool();
- for (bool use_deadline : {false, true}) {
- Cond cond(use_deadline);
- TestNegativeTimeouts(tp.get(), &cond);
- TestInfiniteTimeouts(tp.get(), &cond);
- TestFiniteTimeouts(tp.get(), &cond);
+TEST_P(TimeoutTest, ReaderLockWhen) {
+ const TimeoutTestParam params = GetParam();
+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
+
+ // Because this test asserts bounds on scheduling delays it is flaky. To
+ // compensate it loops forever until it passes. Failures express as test
+ // timeouts, in which case the test log can be used to diagnose the issue.
+ for (int attempt = 0;; ++attempt) {
+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+
+ absl::Mutex mu;
+ bool value = false; // condition value (under mu)
+
+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
+ CreateDefaultPool();
+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
+ absl::MutexLock l(&mu);
+ value = true;
+ });
+
+ absl::Time start_time = absl::Now();
+ bool result =
+ params.use_absolute_deadline
+ ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value),
+ start_time + params.wait_timeout)
+ : mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
+ params.wait_timeout);
+ mu.ReaderUnlock();
+
+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
+ EXPECT_EQ(params.expected_result, result);
+ break;
+ }
+ }
+}
+
+TEST_P(TimeoutTest, Wait) {
+ const TimeoutTestParam params = GetParam();
+ ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
+
+ // Because this test asserts bounds on scheduling delays it is flaky. To
+ // compensate it loops forever until it passes. Failures express as test
+ // timeouts, in which case the test log can be used to diagnose the issue.
+ for (int attempt = 0;; ++attempt) {
+ ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
+
+ absl::Mutex mu;
+ bool value = false; // condition value (under mu)
+ absl::CondVar cv; // signals a change of `value`
+
+ std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
+ CreateDefaultPool();
+ RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
+ absl::MutexLock l(&mu);
+ value = true;
+ cv.Signal();
+ });
+
+ absl::MutexLock lock(&mu);
+ absl::Time start_time = absl::Now();
+ absl::Duration timeout = params.wait_timeout;
+ absl::Time deadline = start_time + timeout;
+ while (!value) {
+ if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline)
+ : cv.WaitWithTimeout(&mu, timeout)) {
+ break; // deadline/timeout exceeded
+ }
+ timeout = deadline - absl::Now(); // recompute
+ }
+ bool result = value; // note: `mu` is still held
+
+ if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
+ EXPECT_EQ(params.expected_result, result);
+ break;
+ }
}
}
diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel
index e793da8..c7c16d4 100644
--- a/absl/time/BUILD.bazel
+++ b/absl/time/BUILD.bazel
@@ -30,9 +30,8 @@
"clock.cc",
"duration.cc",
"format.cc",
- "internal/get_current_time_ios.inc",
+ "internal/get_current_time_chrono.inc",
"internal/get_current_time_posix.inc",
- "internal/get_current_time_windows.inc",
"time.cc",
],
hdrs = [
diff --git a/absl/time/BUILD.gn b/absl/time/BUILD.gn
index 24de31c..9927af8 100644
--- a/absl/time/BUILD.gn
+++ b/absl/time/BUILD.gn
@@ -14,30 +14,19 @@
visibility = [ "*" ]
}
-config("suppress_unguarded_availability") {
- # TODO(bugs.webrtc.org/9557): Remove -Wno-unguarded-availability when
- # abseil will support Xcode 9.0+ (it currently supports Xcode 7.3.1+
- # which doesn't have -Wunguarded-availability and __builtin_available).
- cflags = [
- "-Wno-unguarded-availability",
- ]
-}
-
source_set("time") {
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
"//third_party/abseil-cpp:absl_default_cflags_cc",
- ":suppress_unguarded_availability",
]
public_configs = [ "//third_party/abseil-cpp:absl_include_config" ]
sources = [
"clock.cc",
"duration.cc",
"format.cc",
- "internal/get_current_time_ios.inc",
+ "internal/get_current_time_chrono.inc",
"internal/get_current_time_posix.inc",
- "internal/get_current_time_windows.inc",
"time.cc",
]
public = [
diff --git a/absl/time/clock.cc b/absl/time/clock.cc
index 772f852..74ee140 100644
--- a/absl/time/clock.cc
+++ b/absl/time/clock.cc
@@ -57,10 +57,8 @@
#endif
#endif
-#if defined(__APPLE__)
-#include "absl/time/internal/get_current_time_ios.inc"
-#elif defined(_WIN32)
-#include "absl/time/internal/get_current_time_windows.inc"
+#if defined(__APPLE__) || defined(_WIN32)
+#include "absl/time/internal/get_current_time_chrono.inc"
#else
#include "absl/time/internal/get_current_time_posix.inc"
#endif
diff --git a/absl/time/clock_test.cc b/absl/time/clock_test.cc
index f143c03..707166d 100644
--- a/absl/time/clock_test.cc
+++ b/absl/time/clock_test.cc
@@ -35,36 +35,84 @@
EXPECT_GE(after, now);
}
-TEST(SleepForTest, BasicSanity) {
- absl::Duration sleep_time = absl::Milliseconds(2500);
- absl::Time start = absl::Now();
- absl::SleepFor(sleep_time);
- absl::Time end = absl::Now();
- EXPECT_LE(sleep_time - absl::Milliseconds(100), end - start);
- EXPECT_GE(sleep_time + absl::Milliseconds(200), end - start);
-}
+enum class AlarmPolicy { kWithoutAlarm, kWithAlarm };
-#ifdef ABSL_HAVE_ALARM
-// Helper for test SleepFor.
+#if defined(ABSL_HAVE_ALARM)
bool alarm_handler_invoked = false;
+
void AlarmHandler(int signo) {
ASSERT_EQ(signo, SIGALRM);
alarm_handler_invoked = true;
}
+#endif
-TEST(SleepForTest, AlarmSupport) {
- alarm_handler_invoked = false;
- sig_t old_alarm = signal(SIGALRM, AlarmHandler);
- alarm(2);
- absl::Duration sleep_time = absl::Milliseconds(3500);
- absl::Time start = absl::Now();
- absl::SleepFor(sleep_time);
- absl::Time end = absl::Now();
- EXPECT_TRUE(alarm_handler_invoked);
- EXPECT_LE(sleep_time - absl::Milliseconds(100), end - start);
- EXPECT_GE(sleep_time + absl::Milliseconds(200), end - start);
- signal(SIGALRM, old_alarm);
+// Does SleepFor(d) take between lower_bound and upper_bound at least
+// once between now and (now + timeout)? If requested (and supported),
+// add an alarm for the middle of the sleep period and expect it to fire.
+bool SleepForBounded(absl::Duration d, absl::Duration lower_bound,
+ absl::Duration upper_bound, absl::Duration timeout,
+ AlarmPolicy alarm_policy, int* attempts) {
+ const absl::Time deadline = absl::Now() + timeout;
+ while (absl::Now() < deadline) {
+#if defined(ABSL_HAVE_ALARM)
+ sig_t old_alarm = SIG_DFL;
+ if (alarm_policy == AlarmPolicy::kWithAlarm) {
+ alarm_handler_invoked = false;
+ old_alarm = signal(SIGALRM, AlarmHandler);
+ alarm(absl::ToInt64Seconds(d / 2));
+ }
+#else
+ EXPECT_EQ(alarm_policy, AlarmPolicy::kWithoutAlarm);
+#endif
+ ++*attempts;
+ absl::Time start = absl::Now();
+ absl::SleepFor(d);
+ absl::Duration actual = absl::Now() - start;
+#if defined(ABSL_HAVE_ALARM)
+ if (alarm_policy == AlarmPolicy::kWithAlarm) {
+ signal(SIGALRM, old_alarm);
+ if (!alarm_handler_invoked) continue;
+ }
+#endif
+ if (lower_bound <= actual && actual <= upper_bound) {
+ return true; // yes, the SleepFor() was correctly bounded
+ }
+ }
+ return false;
}
-#endif // ABSL_HAVE_ALARM
+
+testing::AssertionResult AssertSleepForBounded(absl::Duration d,
+ absl::Duration early,
+ absl::Duration late,
+ absl::Duration timeout,
+ AlarmPolicy alarm_policy) {
+ const absl::Duration lower_bound = d - early;
+ const absl::Duration upper_bound = d + late;
+ int attempts = 0;
+ if (SleepForBounded(d, lower_bound, upper_bound, timeout, alarm_policy,
+ &attempts)) {
+ return testing::AssertionSuccess();
+ }
+ return testing::AssertionFailure()
+ << "SleepFor(" << d << ") did not return within [" << lower_bound
+ << ":" << upper_bound << "] in " << attempts << " attempt"
+ << (attempts == 1 ? "" : "s") << " over " << timeout
+ << (alarm_policy == AlarmPolicy::kWithAlarm ? " with" : " without")
+ << " an alarm";
+}
+
+// Tests that SleepFor() returns neither too early nor too late.
+TEST(SleepFor, Bounded) {
+ const absl::Duration d = absl::Milliseconds(2500);
+ const absl::Duration early = absl::Milliseconds(100);
+ const absl::Duration late = absl::Milliseconds(300);
+ const absl::Duration timeout = 48 * d;
+ EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout,
+ AlarmPolicy::kWithoutAlarm));
+#if defined(ABSL_HAVE_ALARM)
+ EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout,
+ AlarmPolicy::kWithAlarm));
+#endif
+}
} // namespace
diff --git a/absl/time/duration.cc b/absl/time/duration.cc
index c13fa79..f402137 100644
--- a/absl/time/duration.cc
+++ b/absl/time/duration.cc
@@ -895,13 +895,10 @@
*d = dur;
return true;
}
-
bool ParseFlag(const std::string& text, Duration* dst, std::string* ) {
return ParseDuration(text, dst);
}
-std::string UnparseFlag(Duration d) {
- return FormatDuration(d);
-}
+std::string UnparseFlag(Duration d) { return FormatDuration(d); }
} // namespace absl
diff --git a/absl/time/duration_benchmark.cc b/absl/time/duration_benchmark.cc
index 54f89a1..d5657bd 100644
--- a/absl/time/duration_benchmark.cc
+++ b/absl/time/duration_benchmark.cc
@@ -27,47 +27,113 @@
//
void BM_Duration_Factory_Nanoseconds(benchmark::State& state) {
+ int64_t i = 0;
while (state.KeepRunning()) {
- benchmark::DoNotOptimize(absl::Nanoseconds(1));
+ benchmark::DoNotOptimize(absl::Nanoseconds(i));
+ i += 314159;
}
}
BENCHMARK(BM_Duration_Factory_Nanoseconds);
void BM_Duration_Factory_Microseconds(benchmark::State& state) {
+ int64_t i = 0;
while (state.KeepRunning()) {
- benchmark::DoNotOptimize(absl::Microseconds(1));
+ benchmark::DoNotOptimize(absl::Microseconds(i));
+ i += 314;
}
}
BENCHMARK(BM_Duration_Factory_Microseconds);
void BM_Duration_Factory_Milliseconds(benchmark::State& state) {
+ int64_t i = 0;
while (state.KeepRunning()) {
- benchmark::DoNotOptimize(absl::Milliseconds(1));
+ benchmark::DoNotOptimize(absl::Milliseconds(i));
+ i += 1;
}
}
BENCHMARK(BM_Duration_Factory_Milliseconds);
void BM_Duration_Factory_Seconds(benchmark::State& state) {
+ int64_t i = 0;
while (state.KeepRunning()) {
- benchmark::DoNotOptimize(absl::Seconds(1));
+ benchmark::DoNotOptimize(absl::Seconds(i));
+ i += 1;
}
}
BENCHMARK(BM_Duration_Factory_Seconds);
void BM_Duration_Factory_Minutes(benchmark::State& state) {
+ int64_t i = 0;
while (state.KeepRunning()) {
- benchmark::DoNotOptimize(absl::Minutes(1));
+ benchmark::DoNotOptimize(absl::Minutes(i));
+ i += 1;
}
}
BENCHMARK(BM_Duration_Factory_Minutes);
void BM_Duration_Factory_Hours(benchmark::State& state) {
+ int64_t i = 0;
while (state.KeepRunning()) {
- benchmark::DoNotOptimize(absl::Hours(1));
+ benchmark::DoNotOptimize(absl::Hours(i));
+ i += 1;
}
}
BENCHMARK(BM_Duration_Factory_Hours);
+void BM_Duration_Factory_DoubleNanoseconds(benchmark::State& state) {
+ double d = 1;
+ while (state.KeepRunning()) {
+ benchmark::DoNotOptimize(absl::Nanoseconds(d));
+ d = d * 1.00000001 + 1;
+ }
+}
+BENCHMARK(BM_Duration_Factory_DoubleNanoseconds);
+
+void BM_Duration_Factory_DoubleMicroseconds(benchmark::State& state) {
+ double d = 1e-3;
+ while (state.KeepRunning()) {
+ benchmark::DoNotOptimize(absl::Microseconds(d));
+ d = d * 1.00000001 + 1e-3;
+ }
+}
+BENCHMARK(BM_Duration_Factory_DoubleMicroseconds);
+
+void BM_Duration_Factory_DoubleMilliseconds(benchmark::State& state) {
+ double d = 1e-6;
+ while (state.KeepRunning()) {
+ benchmark::DoNotOptimize(absl::Milliseconds(d));
+ d = d * 1.00000001 + 1e-6;
+ }
+}
+BENCHMARK(BM_Duration_Factory_DoubleMilliseconds);
+
+void BM_Duration_Factory_DoubleSeconds(benchmark::State& state) {
+ double d = 1e-9;
+ while (state.KeepRunning()) {
+ benchmark::DoNotOptimize(absl::Seconds(d));
+ d = d * 1.00000001 + 1e-9;
+ }
+}
+BENCHMARK(BM_Duration_Factory_DoubleSeconds);
+
+void BM_Duration_Factory_DoubleMinutes(benchmark::State& state) {
+ double d = 1e-9;
+ while (state.KeepRunning()) {
+ benchmark::DoNotOptimize(absl::Minutes(d));
+ d = d * 1.00000001 + 1e-9;
+ }
+}
+BENCHMARK(BM_Duration_Factory_DoubleMinutes);
+
+void BM_Duration_Factory_DoubleHours(benchmark::State& state) {
+ double d = 1e-9;
+ while (state.KeepRunning()) {
+ benchmark::DoNotOptimize(absl::Hours(d));
+ d = d * 1.00000001 + 1e-9;
+ }
+}
+BENCHMARK(BM_Duration_Factory_DoubleHours);
+
//
// Arithmetic
//
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc
index 704684e..7ae25dc 100644
--- a/absl/time/duration_test.cc
+++ b/absl/time/duration_test.cc
@@ -16,7 +16,9 @@
#include <cmath>
#include <cstdint>
#include <ctime>
+#include <iomanip>
#include <limits>
+#include <random>
#include <string>
#include "gmock/gmock.h"
@@ -105,22 +107,22 @@
}
TEST(Duration, ToConversion) {
-#define TEST_DURATION_CONVERSION(UNIT) \
- do { \
- const absl::Duration d = absl::UNIT(1.5); \
- const absl::Duration z = absl::ZeroDuration(); \
- const absl::Duration inf = absl::InfiniteDuration(); \
- const double dbl_inf = std::numeric_limits<double>::infinity(); \
- EXPECT_EQ(kint64min, absl::ToInt64##UNIT(-inf)); \
- EXPECT_EQ(-1, absl::ToInt64##UNIT(-d)); \
- EXPECT_EQ(0, absl::ToInt64##UNIT(z)); \
- EXPECT_EQ(1, absl::ToInt64##UNIT(d)); \
- EXPECT_EQ(kint64max, absl::ToInt64##UNIT(inf)); \
- EXPECT_EQ(-dbl_inf, absl::ToDouble##UNIT(-inf)); \
- EXPECT_EQ(-1.5, absl::ToDouble##UNIT(-d)); \
- EXPECT_EQ(0, absl::ToDouble##UNIT(z)); \
- EXPECT_EQ(1.5, absl::ToDouble##UNIT(d)); \
- EXPECT_EQ(dbl_inf, absl::ToDouble##UNIT(inf)); \
+#define TEST_DURATION_CONVERSION(UNIT) \
+ do { \
+ const absl::Duration d = absl::UNIT(1.5); \
+ constexpr absl::Duration z = absl::ZeroDuration(); \
+ constexpr absl::Duration inf = absl::InfiniteDuration(); \
+ constexpr double dbl_inf = std::numeric_limits<double>::infinity(); \
+ EXPECT_EQ(kint64min, absl::ToInt64##UNIT(-inf)); \
+ EXPECT_EQ(-1, absl::ToInt64##UNIT(-d)); \
+ EXPECT_EQ(0, absl::ToInt64##UNIT(z)); \
+ EXPECT_EQ(1, absl::ToInt64##UNIT(d)); \
+ EXPECT_EQ(kint64max, absl::ToInt64##UNIT(inf)); \
+ EXPECT_EQ(-dbl_inf, absl::ToDouble##UNIT(-inf)); \
+ EXPECT_EQ(-1.5, absl::ToDouble##UNIT(-d)); \
+ EXPECT_EQ(0, absl::ToDouble##UNIT(z)); \
+ EXPECT_EQ(1.5, absl::ToDouble##UNIT(d)); \
+ EXPECT_EQ(dbl_inf, absl::ToDouble##UNIT(inf)); \
} while (0)
TEST_DURATION_CONVERSION(Nanoseconds);
@@ -1284,6 +1286,16 @@
EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(0.875e-9));
EXPECT_EQ(absl::Nanoseconds(1), absl::Seconds(1.000e-9));
+ EXPECT_EQ(absl::ZeroDuration(), absl::Seconds(-0.124999999e-9));
+ EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.125e-9));
+ EXPECT_EQ(-absl::Nanoseconds(1) / 4, absl::Seconds(-0.250e-9));
+ EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.375e-9));
+ EXPECT_EQ(-absl::Nanoseconds(1) / 2, absl::Seconds(-0.500e-9));
+ EXPECT_EQ(-absl::Nanoseconds(3) / 4, absl::Seconds(-0.625e-9));
+ EXPECT_EQ(-absl::Nanoseconds(3) / 4, absl::Seconds(-0.750e-9));
+ EXPECT_EQ(-absl::Nanoseconds(1), absl::Seconds(-0.875e-9));
+ EXPECT_EQ(-absl::Nanoseconds(1), absl::Seconds(-1.000e-9));
+
timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = 0;
@@ -1313,6 +1325,86 @@
EXPECT_THAT(ToTimeval(absl::Nanoseconds(2000)), TimevalMatcher(tv));
}
+void VerifySameAsMul(double time_as_seconds, int* const misses) {
+ auto direct_seconds = absl::Seconds(time_as_seconds);
+ auto mul_by_one_second = time_as_seconds * absl::Seconds(1);
+ if (direct_seconds != mul_by_one_second) {
+ if (*misses > 10) return;
+ ASSERT_LE(++(*misses), 10) << "Too many errors, not reporting more.";
+ EXPECT_EQ(direct_seconds, mul_by_one_second)
+ << "given double time_as_seconds = " << std::setprecision(17)
+ << time_as_seconds;
+ }
+}
+
+// For a variety of interesting durations, we find the exact point
+// where one double converts to that duration, and the very next double
+// converts to the next duration. For both of those points, verify that
+// Seconds(point) returns the same duration as point * Seconds(1.0)
+TEST(Duration, ToDoubleSecondsCheckEdgeCases) {
+ constexpr uint32_t kTicksPerSecond = absl::time_internal::kTicksPerSecond;
+ constexpr auto duration_tick = absl::time_internal::MakeDuration(0, 1u);
+ int misses = 0;
+ for (int64_t seconds = 0; seconds < 99; ++seconds) {
+ uint32_t tick_vals[] = {0, +999, +999999, +999999999, kTicksPerSecond - 1,
+ 0, 1000, 1000000, 1000000000, kTicksPerSecond,
+ 1, 1001, 1000001, 1000000001, kTicksPerSecond + 1,
+ 2, 1002, 1000002, 1000000002, kTicksPerSecond + 2,
+ 3, 1003, 1000003, 1000000003, kTicksPerSecond + 3,
+ 4, 1004, 1000004, 1000000004, kTicksPerSecond + 4,
+ 5, 6, 7, 8, 9};
+ for (uint32_t ticks : tick_vals) {
+ absl::Duration s_plus_t = absl::Seconds(seconds) + ticks * duration_tick;
+ for (absl::Duration d : {s_plus_t, -s_plus_t}) {
+ absl::Duration after_d = d + duration_tick;
+ EXPECT_NE(d, after_d);
+ EXPECT_EQ(after_d - d, duration_tick);
+
+ double low_edge = ToDoubleSeconds(d);
+ EXPECT_EQ(d, absl::Seconds(low_edge));
+
+ double high_edge = ToDoubleSeconds(after_d);
+ EXPECT_EQ(after_d, absl::Seconds(high_edge));
+
+ for (;;) {
+ double midpoint = low_edge + (high_edge - low_edge) / 2;
+ if (midpoint == low_edge || midpoint == high_edge) break;
+ absl::Duration mid_duration = absl::Seconds(midpoint);
+ if (mid_duration == d) {
+ low_edge = midpoint;
+ } else {
+ EXPECT_EQ(mid_duration, after_d);
+ high_edge = midpoint;
+ }
+ }
+ // Now low_edge is the highest double that converts to Duration d,
+ // and high_edge is the lowest double that converts to Duration after_d.
+ VerifySameAsMul(low_edge, &misses);
+ VerifySameAsMul(high_edge, &misses);
+ }
+ }
+ }
+}
+
+TEST(Duration, ToDoubleSecondsCheckRandom) {
+ std::random_device rd;
+ std::seed_seq seed({rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()});
+ std::mt19937_64 gen(seed);
+ // We want doubles distributed from 1/8ns up to 2^63, where
+ // as many values are tested from 1ns to 2ns as from 1sec to 2sec,
+ // so even distribute along a log-scale of those values, and
+ // exponentiate before using them. (9.223377e+18 is just slightly
+ // out of bounds for absl::Duration.)
+ std::uniform_real_distribution<double> uniform(std::log(0.125e-9),
+ std::log(9.223377e+18));
+ int misses = 0;
+ for (int i = 0; i < 1000000; ++i) {
+ double d = std::exp(uniform(gen));
+ VerifySameAsMul(d, &misses);
+ VerifySameAsMul(-d, &misses);
+ }
+}
+
TEST(Duration, ConversionSaturation) {
absl::Duration d;
diff --git a/absl/time/internal/get_current_time_chrono.inc b/absl/time/internal/get_current_time_chrono.inc
new file mode 100644
index 0000000..cf884a1
--- /dev/null
+++ b/absl/time/internal/get_current_time_chrono.inc
@@ -0,0 +1,29 @@
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <chrono>
+#include <cstdint>
+
+namespace absl {
+namespace time_internal {
+
+static int64_t GetCurrentTimeNanosFromSystem() {
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(
+ std::chrono::system_clock::now() -
+ std::chrono::system_clock::from_time_t(0))
+ .count();
+}
+
+} // namespace time_internal
+} // namespace absl
diff --git a/absl/time/internal/get_current_time_ios.inc b/absl/time/internal/get_current_time_ios.inc
deleted file mode 100644
index f3db32b..0000000
--- a/absl/time/internal/get_current_time_ios.inc
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "absl/time/clock.h"
-
-#include <sys/time.h>
-#include <ctime>
-#include <cstdint>
-
-#include "absl/base/internal/raw_logging.h"
-
-// These are not defined in the Xcode 7.3.1 SDK Headers.
-// Once we are no longer supporting Xcode 7.3.1 we can
-// remove these.
-#ifndef __WATCHOS_3_0
-#define __WATCHOS_3_0 30000
-#endif
-
-#ifndef __TVOS_10_0
-#define __TVOS_10_0 100000
-#endif
-
-#ifndef __IPHONE_10_0
-#define __IPHONE_10_0 100000
-#endif
-
-#ifndef __MAC_10_12
-#define __MAC_10_12 101200
-#endif
-
-namespace absl {
-namespace time_internal {
-
-static int64_t GetCurrentTimeNanosFromSystem() {
-#if (__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_12) || \
- (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0) || \
- (__WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0) || \
- (__TV_OS_VERSION_MAX_ALLOWED >= __TVOS_10_0)
- // clock_gettime_nsec_np is not defined on SDKs before Xcode 8.0.
- // This preprocessor logic is based upon __CLOCK_AVAILABILITY in
- // usr/include/time.h. Once we are no longer supporting Xcode 7.3.1 we can
- // remove this #if.
- // We must continue to check if it is defined until we are sure that ALL the
- // platforms we are shipping on support it.
- // clock_gettime_nsec_np is preferred because it may give higher accuracy than
- // gettimeofday in future Apple operating systems.
- // Currently (macOS 10.12/iOS 10.2) clock_gettime_nsec_np accuracy is
- // microsecond accuracy (i.e. equivalent to gettimeofday).
- if (&clock_gettime_nsec_np != nullptr) {
- return clock_gettime_nsec_np(CLOCK_REALTIME);
- }
-#endif
-#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
- (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12)) || \
- (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
- (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)) || \
- (defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
- (__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0)) || \
- (defined(__TV_OS_VERSION_MIN_REQUIRED) && \
- (__TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0))
- // We need this block in 2 different cases:
- // a) where we are compiling with Xcode 7 in which case the block above
- // will not be compiled in, and this is the only block executed.
- // b) where we are compiling with Xcode 8+ but supporting operating systems
- // that do not define clock_gettime_nsec_np, so this is in effect
- // an else block to the block above.
- // This block will not be compiled if the min supported version is
- // guaranteed to supply clock_gettime_nsec_np.
- //
- // Once we know that clock_gettime_nsec_np is in the SDK *AND* exists on
- // all the platforms we support, we can remove both this block and alter the
- // block above to just call clock_gettime_nsec_np directly.
- const int64_t kNanosPerSecond = 1000 * 1000 * 1000;
- const int64_t kNanosPerMicrosecond = 1000;
- struct timeval tp;
- ABSL_RAW_CHECK(gettimeofday(&tp, nullptr) == 0, "Failed gettimeofday");
- return (int64_t{tp.tv_sec} * kNanosPerSecond +
- int64_t{tp.tv_usec} * kNanosPerMicrosecond);
-#endif
-}
-
-} // namespace time_internal
-} // namespace absl
diff --git a/absl/time/internal/get_current_time_windows.inc b/absl/time/internal/get_current_time_windows.inc
deleted file mode 100644
index b22a9c9..0000000
--- a/absl/time/internal/get_current_time_windows.inc
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "absl/time/clock.h"
-
-#include <chrono>
-#include <cstdint>
-
-namespace absl {
-namespace time_internal {
-
-static int64_t GetCurrentTimeNanosFromSystem() {
- return std::chrono::duration_cast<std::chrono::nanoseconds>(
- std::chrono::system_clock::now() -
- std::chrono::system_clock::from_time_t(0))
- .count();
-}
-
-} // namespace time_internal
-} // namespace absl
diff --git a/absl/time/time.h b/absl/time/time.h
index ceec2de..c41cb89 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -50,7 +50,7 @@
#ifndef ABSL_TIME_TIME_H_
#define ABSL_TIME_TIME_H_
-#if !defined(_WIN32)
+#if !defined(_MSC_VER)
#include <sys/time.h>
#else
#include <winsock2.h>
@@ -81,6 +81,7 @@
constexpr uint32_t GetRepLo(Duration d);
constexpr Duration MakeDuration(int64_t hi, uint32_t lo);
constexpr Duration MakeDuration(int64_t hi, int64_t lo);
+inline Duration MakePosDoubleDuration(double n);
constexpr int64_t kTicksPerNanosecond = 4;
constexpr int64_t kTicksPerSecond = 1000 * 1000 * 1000 * kTicksPerNanosecond;
template <std::intmax_t N>
@@ -295,6 +296,39 @@
// absl::Duration c = absl::Ceil(d, absl::Microseconds(1)); // 123457us
Duration Ceil(Duration d, Duration unit);
+// InfiniteDuration()
+//
+// Returns an infinite `Duration`. To get a `Duration` representing negative
+// infinity, use `-InfiniteDuration()`.
+//
+// Duration arithmetic overflows to +/- infinity and saturates. In general,
+// arithmetic with `Duration` infinities is similar to IEEE 754 infinities
+// except where IEEE 754 NaN would be involved, in which case +/-
+// `InfiniteDuration()` is used in place of a "nan" Duration.
+//
+// Examples:
+//
+// constexpr absl::Duration inf = absl::InfiniteDuration();
+// const absl::Duration d = ... any finite duration ...
+//
+// inf == inf + inf
+// inf == inf + d
+// inf == inf - inf
+// -inf == d - inf
+//
+// inf == d * 1e100
+// inf == inf / 2
+// 0 == d / inf
+// INT64_MAX == inf / d
+//
+// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate.
+// inf == d / 0
+// INT64_MAX == d / absl::ZeroDuration()
+//
+// The examples involving the `/` operator above also apply to `IDivDuration()`
+// and `FDivDuration()`.
+constexpr Duration InfiniteDuration();
+
// Nanoseconds()
// Microseconds()
// Milliseconds()
@@ -344,7 +378,13 @@
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
Duration Seconds(T n) {
- return n * Seconds(1);
+ if (n >= 0) {
+ if (n >= std::numeric_limits<int64_t>::max()) return InfiniteDuration();
+ return time_internal::MakePosDoubleDuration(n);
+ } else {
+ if (n <= std::numeric_limits<int64_t>::min()) return -InfiniteDuration();
+ return -time_internal::MakePosDoubleDuration(-n);
+ }
}
template <typename T, time_internal::EnableIfFloat<T> = 0>
Duration Minutes(T n) {
@@ -439,39 +479,6 @@
std::chrono::minutes ToChronoMinutes(Duration d);
std::chrono::hours ToChronoHours(Duration d);
-// InfiniteDuration()
-//
-// Returns an infinite `Duration`. To get a `Duration` representing negative
-// infinity, use `-InfiniteDuration()`.
-//
-// Duration arithmetic overflows to +/- infinity and saturates. In general,
-// arithmetic with `Duration` infinities is similar to IEEE 754 infinities
-// except where IEEE 754 NaN would be involved, in which case +/-
-// `InfiniteDuration()` is used in place of a "nan" Duration.
-//
-// Examples:
-//
-// constexpr absl::Duration inf = absl::InfiniteDuration();
-// const absl::Duration d = ... any finite duration ...
-//
-// inf == inf + inf
-// inf == inf + d
-// inf == inf - inf
-// -inf == d - inf
-//
-// inf == d * 1e100
-// inf == inf / 2
-// 0 == d / inf
-// INT64_MAX == inf / d
-//
-// // Division by zero returns infinity, or INT64_MIN/MAX where appropriate.
-// inf == d / 0
-// INT64_MAX == d / absl::ZeroDuration()
-//
-// The examples involving the `/` operator above also apply to `IDivDuration()`
-// and `FDivDuration()`.
-constexpr Duration InfiniteDuration();
-
// FormatDuration()
//
// Returns a std::string representing the duration in the form "72h3m0.5s".
@@ -492,12 +499,9 @@
// `ZeroDuration()`. Parses "inf" and "-inf" as +/- `InfiniteDuration()`.
bool ParseDuration(const std::string& dur_string, Duration* d);
-// ParseFlag()
-//
+// Support for flag values of type Duration. Duration flags must be specified
+// in a format that is valid input for absl::ParseDuration().
bool ParseFlag(const std::string& text, Duration* dst, std::string* error);
-
-// UnparseFlag()
-//
std::string UnparseFlag(Duration d);
// Time
@@ -991,9 +995,6 @@
bool ParseTime(const std::string& format, const std::string& input, TimeZone tz,
Time* time, std::string* err);
-// ParseFlag()
-// UnparseFlag()
-//
// Support for flag values of type Time. Time flags must be specified in a
// format that matches absl::RFC3339_full. For example:
//
@@ -1114,6 +1115,18 @@
return MakeDuration(hi, static_cast<uint32_t>(lo));
}
+// Make a Duration value from a floating-point number, as long as that number
+// is in the range [ 0 .. numeric_limits<int64_t>::max ), that is, as long as
+// it's positive and can be converted to int64_t without risk of UB.
+inline Duration MakePosDoubleDuration(double n) {
+ const int64_t int_secs = static_cast<int64_t>(n);
+ const uint32_t ticks =
+ static_cast<uint32_t>((n - int_secs) * kTicksPerSecond + 0.5);
+ return ticks < kTicksPerSecond
+ ? MakeDuration(int_secs, ticks)
+ : MakeDuration(int_secs + 1, ticks - kTicksPerSecond);
+}
+
// Creates a normalized Duration from an almost-normalized (sec,ticks)
// pair. sec may be positive or negative. ticks must be in the range
// -kTicksPerSecond < *ticks < kTicksPerSecond. If ticks is negative it
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h
index 7db5e05..7708e67 100644
--- a/absl/types/internal/variant.h
+++ b/absl/types/internal/variant.h
@@ -1062,32 +1062,6 @@
static void Overload(...);
};
-////////////////////////////////
-// Library Fundamentals V2 TS //
-////////////////////////////////
-
-// TODO(calabrese): Consider moving this to absl/meta/type_traits.h
-
-// The following is a rough implementation of parts of the detection idiom.
-// It is used for the comparison operator checks.
-
-template <class Enabler, class To, template <class...> class Op, class... Args>
-struct is_detected_convertible_impl {
- using type = std::false_type;
-};
-
-template <class To, template <class...> class Op, class... Args>
-struct is_detected_convertible_impl<
- absl::enable_if_t<std::is_convertible<Op<Args...>, To>::value>, To, Op,
- Args...> {
- using type = std::true_type;
-};
-
-// NOTE: This differs from library fundamentals by being lazy.
-template <class To, template <class...> class Op, class... Args>
-struct is_detected_convertible
- : is_detected_convertible_impl<void, To, Op, Args...>::type {};
-
template <class T>
using LessThanResult = decltype(std::declval<T>() < std::declval<T>());
@@ -1107,6 +1081,8 @@
template <class T>
using NotEqualResult = decltype(std::declval<T>() != std::declval<T>());
+using type_traits_internal::is_detected_convertible;
+
template <class... T>
using RequireAllHaveEqualT = absl::enable_if_t<
absl::conjunction<is_detected_convertible<bool, EqualResult, T>...>::value,
diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc
index 5a4f001..fbce7e8 100644
--- a/absl/types/span_test.cc
+++ b/absl/types/span_test.cc
@@ -288,7 +288,7 @@
#ifdef ABSL_HAVE_EXCEPTIONS
EXPECT_THROW(absl::MakeSpan(ramp).subspan(11, 5), std::out_of_range);
#else
- EXPECT_DEATH(absl::MakeSpan(ramp).subspan(11, 5), "");
+ EXPECT_DEATH_IF_SUPPORTED(absl::MakeSpan(ramp).subspan(11, 5), "");
#endif
}
diff --git a/absl/types/variant.h b/absl/types/variant.h
index fd1d49a..17e0634 100644
--- a/absl/types/variant.h
+++ b/absl/types/variant.h
@@ -248,7 +248,7 @@
//
// Example:
//
-// absl::variant<int, std::string> bar = 42;
+// absl::variant<int, std::string> foo = 42;
// if (absl::holds_alternative<int>(foo)) {
// std::cout << "The variant holds an integer";
// }
@@ -449,14 +449,19 @@
//------------------------------------------------------------------------------
template <typename T0, typename... Tn>
class variant<T0, Tn...> : private variant_internal::VariantBase<T0, Tn...> {
+ static_assert(absl::conjunction<std::is_object<T0>,
+ std::is_object<Tn>...>::value,
+ "Attempted to instantiate a variant containing a non-object "
+ "type.");
// Intentionally not qualifing `negation` with `absl::` to work around a bug
// in MSVC 2015 with inline namespace and variadic template.
- static_assert(absl::conjunction<std::is_object<T0>, std::is_object<Tn>...,
- negation<std::is_array<T0> >,
- negation<std::is_array<Tn> >...,
- std::is_nothrow_destructible<T0>,
+ static_assert(absl::conjunction<negation<std::is_array<T0> >,
+ negation<std::is_array<Tn> >...>::value,
+ "Attempted to instantiate a variant containing an array type.");
+ static_assert(absl::conjunction<std::is_nothrow_destructible<T0>,
std::is_nothrow_destructible<Tn>...>::value,
- "Attempted to instantiate a variant with an unsupported type.");
+ "Attempted to instantiate a variant containing a non-nothrow "
+ "destructible type.");
friend struct variant_internal::VariantCoreAccess;
diff --git a/api/asyncresolverfactory.h b/api/asyncresolverfactory.h
new file mode 100644
index 0000000..96abee4
--- /dev/null
+++ b/api/asyncresolverfactory.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 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_ASYNCRESOLVERFACTORY_H_
+#define API_ASYNCRESOLVERFACTORY_H_
+
+#include "rtc_base/asyncresolverinterface.h"
+
+namespace webrtc {
+
+// An abstract factory for creating AsyncResolverInterfaces. This allows
+// client applications to provide WebRTC with their own mechanism for
+// performing DNS resolution.
+class AsyncResolverFactory {
+ public:
+ AsyncResolverFactory() = default;
+ virtual ~AsyncResolverFactory() = default;
+
+ // The caller should call Destroy on the returned object to delete it.
+ virtual rtc::AsyncResolverInterface* Create() = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_ASYNCRESOLVERFACTORY_H_
diff --git a/api/audio/audio_frame.h b/api/audio/audio_frame.h
index 4c9aa9c..dd6ac02 100644
--- a/api/audio/audio_frame.h
+++ b/api/audio/audio_frame.h
@@ -12,13 +12,13 @@
#define API_AUDIO_AUDIO_FRAME_H_
#include <stddef.h>
+#include <stdint.h>
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
-/* This class holds up to 60 ms of super-wideband (32 kHz) stereo audio. It
+/* This class holds up to 120 ms of super-wideband (32 kHz) stereo audio. It
* allows for adding and subtracting frames while keeping track of the resulting
* states.
*
@@ -38,8 +38,9 @@
// variables which should allow us to switch to constexpr and keep this a
// header-only class.
enum : size_t {
- // Stereo, 32 kHz, 60 ms (2 * 32 * 60)
- kMaxDataSizeSamples = 3840,
+ // Stereo, 32 kHz, 120 ms (2 * 32 * 120)
+ // Stereo, 192 kHz, 20 ms (2 * 192 * 20)
+ kMaxDataSizeSamples = 7680,
kMaxDataSizeBytes = kMaxDataSizeSamples * sizeof(int16_t),
};
diff --git a/api/audio/echo_canceller3_config.cc b/api/audio/echo_canceller3_config.cc
index 9af7f11..3b03d13 100644
--- a/api/audio/echo_canceller3_config.cc
+++ b/api/audio/echo_canceller3_config.cc
@@ -14,6 +14,10 @@
EchoCanceller3Config::EchoCanceller3Config() = default;
EchoCanceller3Config::EchoCanceller3Config(const EchoCanceller3Config& e) =
default;
+EchoCanceller3Config::Delay::Delay() = default;
+EchoCanceller3Config::Delay::Delay(const EchoCanceller3Config::Delay& e) =
+ default;
+
EchoCanceller3Config::Mask::Mask() = default;
EchoCanceller3Config::Mask::Mask(const EchoCanceller3Config::Mask& m) = default;
@@ -21,4 +25,30 @@
EchoCanceller3Config::EchoModel::EchoModel(
const EchoCanceller3Config::EchoModel& e) = default;
+EchoCanceller3Config::Suppressor::Suppressor() = default;
+EchoCanceller3Config::Suppressor::Suppressor(
+ const EchoCanceller3Config::Suppressor& e) = default;
+
+EchoCanceller3Config::Suppressor::MaskingThresholds::MaskingThresholds(
+ float enr_transparent,
+ float enr_suppress,
+ float emr_transparent)
+ : enr_transparent(enr_transparent),
+ enr_suppress(enr_suppress),
+ emr_transparent(emr_transparent) {}
+EchoCanceller3Config::Suppressor::Suppressor::MaskingThresholds::
+ MaskingThresholds(
+ const EchoCanceller3Config::Suppressor::MaskingThresholds& e) = default;
+
+EchoCanceller3Config::Suppressor::Tuning::Tuning(MaskingThresholds mask_lf,
+ MaskingThresholds mask_hf,
+ float max_inc_factor,
+ float max_dec_factor_lf)
+ : mask_lf(mask_lf),
+ mask_hf(mask_hf),
+ max_inc_factor(max_inc_factor),
+ max_dec_factor_lf(max_dec_factor_lf) {}
+EchoCanceller3Config::Suppressor::Tuning::Tuning(
+ const EchoCanceller3Config::Suppressor::Tuning& e) = default;
+
} // namespace webrtc
diff --git a/api/audio/echo_canceller3_config.h b/api/audio/echo_canceller3_config.h
index d633d04..f4ba8e9 100644
--- a/api/audio/echo_canceller3_config.h
+++ b/api/audio/echo_canceller3_config.h
@@ -20,6 +20,8 @@
EchoCanceller3Config();
EchoCanceller3Config(const EchoCanceller3Config& e);
struct Delay {
+ Delay();
+ Delay(const Delay& e);
size_t default_delay = 5;
size_t down_sampling_factor = 4;
size_t num_filters = 6;
@@ -29,6 +31,7 @@
size_t hysteresis_limit_1_blocks = 1;
size_t hysteresis_limit_2_blocks = 1;
size_t skew_hysteresis_blocks = 3;
+ size_t fixed_capture_delay_samples = 0;
} delay;
struct Filter {
@@ -53,12 +56,16 @@
ShadowConfiguration shadow_initial = {12, 0.9f, 20075344.f};
size_t config_change_duration_blocks = 250;
+ float initial_state_seconds = 2.5f;
+ bool conservative_initial_phase = false;
+ bool enable_shadow_filter_output_usage = true;
} filter;
struct Erle {
float min = 1.f;
float max_l = 4.f;
float max_h = 1.5f;
+ bool onset_detection = true;
} erle;
struct EpStrength {
@@ -107,27 +114,6 @@
float poor_excitation_render_limit_ds8 = 20.f;
} render_levels;
- struct GainUpdates {
- struct GainChanges {
- float max_inc;
- float max_dec;
- float rate_inc;
- float rate_dec;
- float min_inc;
- float min_dec;
- };
-
- GainChanges low_noise = {2.f, 2.f, 1.4f, 1.4f, 1.1f, 1.1f};
- GainChanges initial = {2.f, 2.f, 1.5f, 1.5f, 1.2f, 1.2f};
- GainChanges normal = {2.f, 2.f, 1.5f, 1.5f, 1.2f, 1.2f};
- GainChanges saturation = {1.2f, 1.2f, 1.5f, 1.5f, 1.f, 1.f};
- GainChanges nonlinear = {1.5f, 1.5f, 1.2f, 1.2f, 1.1f, 1.1f};
-
- float max_inc_factor = 2.0f;
- float max_dec_factor_lf = 0.25f;
- float floor_first_increase = 0.00001f;
- } gain_updates;
-
struct EchoRemovalControl {
struct GainRampup {
float initial_gain = 0.0f;
@@ -156,16 +142,57 @@
} echo_model;
struct Suppressor {
- size_t bands_with_reliable_coherence = 5;
+ Suppressor();
+ Suppressor(const Suppressor& e);
+
size_t nearend_average_blocks = 4;
struct MaskingThresholds {
+ MaskingThresholds(float enr_transparent,
+ float enr_suppress,
+ float emr_transparent);
+ MaskingThresholds(const MaskingThresholds& e);
float enr_transparent;
float enr_suppress;
float emr_transparent;
};
- MaskingThresholds mask_lf = {.2f, .3f, .3f};
- MaskingThresholds mask_hf = {.07f, .1f, .3f};
+
+ struct Tuning {
+ Tuning(MaskingThresholds mask_lf,
+ MaskingThresholds mask_hf,
+ float max_inc_factor,
+ float max_dec_factor_lf);
+ Tuning(const Tuning& e);
+ MaskingThresholds mask_lf;
+ MaskingThresholds mask_hf;
+ float max_inc_factor;
+ float max_dec_factor_lf;
+ };
+
+ Tuning normal_tuning = Tuning(MaskingThresholds(.2f, .3f, .3f),
+ MaskingThresholds(.07f, .1f, .3f),
+ 2.0f,
+ 0.25f);
+ Tuning nearend_tuning = Tuning(MaskingThresholds(.2f, .3f, .3f),
+ MaskingThresholds(.07f, .1f, .3f),
+ 2.0f,
+ 0.25f);
+
+ struct DominantNearendDetection {
+ float enr_threshold = 10.f;
+ float snr_threshold = 10.f;
+ int hold_duration = 25;
+ int trigger_threshold = 15;
+ } dominant_nearend_detection;
+
+ struct HighBandsSuppression {
+ float enr_threshold = 1.f;
+ float max_gain_during_echo = 1.f;
+ } high_bands_suppression;
+
+ float floor_first_increase = 0.00001f;
+ bool enforce_transparent = false;
+ bool enforce_empty_higher_bands = false;
} suppressor;
};
} // namespace webrtc
diff --git a/api/audio_options.h b/api/audio_options.h
index df66d36..aefc7a1 100644
--- a/api/audio_options.h
+++ b/api/audio_options.h
@@ -44,7 +44,6 @@
SetFrom(&extended_filter_aec, change.extended_filter_aec);
SetFrom(&delay_agnostic_aec, change.delay_agnostic_aec);
SetFrom(&experimental_ns, change.experimental_ns);
- SetFrom(&intelligibility_enhancer, change.intelligibility_enhancer);
SetFrom(&residual_echo_detector, change.residual_echo_detector);
SetFrom(&tx_agc_target_dbov, change.tx_agc_target_dbov);
SetFrom(&tx_agc_digital_compression_gain,
@@ -74,7 +73,6 @@
extended_filter_aec == o.extended_filter_aec &&
delay_agnostic_aec == o.delay_agnostic_aec &&
experimental_ns == o.experimental_ns &&
- intelligibility_enhancer == o.intelligibility_enhancer &&
residual_echo_detector == o.residual_echo_detector &&
tx_agc_target_dbov == o.tx_agc_target_dbov &&
tx_agc_digital_compression_gain ==
@@ -108,7 +106,6 @@
ost << ToStringIfSet("extended_filter_aec", extended_filter_aec);
ost << ToStringIfSet("delay_agnostic_aec", delay_agnostic_aec);
ost << ToStringIfSet("experimental_ns", experimental_ns);
- ost << ToStringIfSet("intelligibility_enhancer", intelligibility_enhancer);
ost << ToStringIfSet("residual_echo_detector", residual_echo_detector);
ost << ToStringIfSet("tx_agc_target_dbov", tx_agc_target_dbov);
ost << ToStringIfSet("tx_agc_digital_compression_gain",
@@ -153,7 +150,6 @@
absl::optional<bool> extended_filter_aec;
absl::optional<bool> delay_agnostic_aec;
absl::optional<bool> experimental_ns;
- absl::optional<bool> intelligibility_enhancer;
// Note that tx_agc_* only applies to non-experimental AGC.
absl::optional<bool> residual_echo_detector;
absl::optional<uint16_t> tx_agc_target_dbov;
diff --git a/api/datachannelinterface.cc b/api/datachannelinterface.cc
new file mode 100644
index 0000000..141462d
--- /dev/null
+++ b/api/datachannelinterface.cc
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 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/datachannelinterface.h"
+
+namespace webrtc {
+
+bool DataChannelInterface::ordered() const {
+ return false;
+}
+
+uint16_t DataChannelInterface::maxRetransmitTime() const {
+ return 0;
+}
+
+uint16_t DataChannelInterface::maxRetransmits() const {
+ return 0;
+}
+
+std::string DataChannelInterface::protocol() const {
+ return std::string();
+}
+
+bool DataChannelInterface::negotiated() const {
+ return false;
+}
+
+} // namespace webrtc
diff --git a/api/datachannelinterface.h b/api/datachannelinterface.h
index 5cbe717..a0d2b3b 100644
--- a/api/datachannelinterface.h
+++ b/api/datachannelinterface.h
@@ -88,7 +88,7 @@
virtual void OnBufferedAmountChange(uint64_t previous_amount) {}
protected:
- virtual ~DataChannelObserver() {}
+ virtual ~DataChannelObserver() = default;
};
class DataChannelInterface : public rtc::RefCountInterface {
@@ -134,11 +134,11 @@
// TODO(deadbeef): Remove these dummy implementations when all classes have
// implemented these APIs. They should all just return the values the
// DataChannel was created with.
- virtual bool ordered() const { return false; }
- virtual uint16_t maxRetransmitTime() const { return 0; }
- virtual uint16_t maxRetransmits() const { return 0; }
- virtual std::string protocol() const { return std::string(); }
- virtual bool negotiated() const { return false; }
+ virtual bool ordered() const;
+ virtual uint16_t maxRetransmitTime() const;
+ virtual uint16_t maxRetransmits() const;
+ virtual std::string protocol() const;
+ virtual bool negotiated() const;
// Returns the ID from the DataChannelInit, if it was negotiated out-of-band.
// If negotiated in-band, this ID will be populated once the DTLS role is
@@ -170,7 +170,7 @@
virtual bool Send(const DataBuffer& buffer) = 0;
protected:
- virtual ~DataChannelInterface() {}
+ ~DataChannelInterface() override = default;
};
} // namespace webrtc
diff --git a/api/dtmfsenderinterface.h b/api/dtmfsenderinterface.h
index 217f9d2..b79bb31 100644
--- a/api/dtmfsenderinterface.h
+++ b/api/dtmfsenderinterface.h
@@ -29,7 +29,7 @@
virtual void OnToneChange(const std::string& tone) = 0;
protected:
- virtual ~DtmfSenderObserverInterface() {}
+ virtual ~DtmfSenderObserverInterface() = default;
};
// The interface of native implementation of the RTCDTMFSender defined by the
@@ -85,7 +85,7 @@
virtual int inter_tone_gap() const = 0;
protected:
- virtual ~DtmfSenderInterface() {}
+ ~DtmfSenderInterface() override = default;
};
} // namespace webrtc
diff --git a/api/jsep.cc b/api/jsep.cc
index 1f4afba..52a60f9 100644
--- a/api/jsep.cc
+++ b/api/jsep.cc
@@ -21,4 +21,21 @@
return 0;
}
+void CreateSessionDescriptionObserver::OnFailure(RTCError error) {
+ OnFailure(error.message());
+}
+
+void CreateSessionDescriptionObserver::OnFailure(const std::string& error) {
+ OnFailure(RTCError(RTCErrorType::INTERNAL_ERROR, std::string(error)));
+}
+
+void SetSessionDescriptionObserver::OnFailure(RTCError error) {
+ std::string message(error.message());
+ OnFailure(message);
+}
+
+void SetSessionDescriptionObserver::OnFailure(const std::string& error) {
+ OnFailure(RTCError(RTCErrorType::INTERNAL_ERROR, std::string(error)));
+}
+
} // namespace webrtc
diff --git a/api/jsep.h b/api/jsep.h
index dbf97f6..4d4bcc0 100644
--- a/api/jsep.h
+++ b/api/jsep.h
@@ -78,6 +78,12 @@
const std::string& sdp,
SdpParseError* error);
+// Creates an IceCandidateInterface based on a parsed candidate structure.
+std::unique_ptr<IceCandidateInterface> CreateIceCandidate(
+ const std::string& sdp_mid,
+ int sdp_mline_index,
+ const cricket::Candidate& candidate);
+
// This class represents a collection of candidates for a specific m= section.
// Used in SessionDescriptionInterface.
class IceCandidateCollection {
@@ -191,6 +197,14 @@
const std::string& sdp,
SdpParseError* error_out);
+// Creates a SessionDescriptionInterface based on a parsed SDP structure and the
+// given type, ID and version.
+std::unique_ptr<SessionDescriptionInterface> CreateSessionDescription(
+ SdpType type,
+ const std::string& session_id,
+ const std::string& session_version,
+ std::unique_ptr<cricket::SessionDescription> description);
+
// CreateOffer and CreateAnswer callback interface.
class CreateSessionDescriptionObserver : public rtc::RefCountInterface {
public:
@@ -205,10 +219,8 @@
// is deprecated; in order to let clients remove the old version, it has a
// default implementation. If both versions are unimplemented, the
// result will be a runtime error (stack overflow). This is intentional.
- virtual void OnFailure(RTCError error) { OnFailure(error.message()); }
- virtual void OnFailure(const std::string& error) {
- OnFailure(RTCError(RTCErrorType::INTERNAL_ERROR, std::string(error)));
- }
+ virtual void OnFailure(RTCError error);
+ virtual void OnFailure(const std::string& error);
protected:
~CreateSessionDescriptionObserver() override = default;
@@ -219,13 +231,9 @@
public:
virtual void OnSuccess() = 0;
// See description in CreateSessionDescriptionObserver for OnFailure.
- virtual void OnFailure(RTCError error) {
- std::string message(error.message());
- OnFailure(message);
- }
- virtual void OnFailure(const std::string& error) {
- OnFailure(RTCError(RTCErrorType::INTERNAL_ERROR, std::string(error)));
- }
+ virtual void OnFailure(RTCError error);
+
+ virtual void OnFailure(const std::string& error);
protected:
~SetSessionDescriptionObserver() override = default;
diff --git a/api/jsepicecandidate.cc b/api/jsepicecandidate.cc
new file mode 100644
index 0000000..b9ba2fe
--- /dev/null
+++ b/api/jsepicecandidate.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2018 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/jsepicecandidate.h"
+
+namespace webrtc {
+
+std::string JsepIceCandidate::sdp_mid() const {
+ return sdp_mid_;
+}
+
+int JsepIceCandidate::sdp_mline_index() const {
+ return sdp_mline_index_;
+}
+
+const cricket::Candidate& JsepIceCandidate::candidate() const {
+ return candidate_;
+}
+
+std::string JsepIceCandidate::server_url() const {
+ return candidate_.url();
+}
+
+JsepCandidateCollection::JsepCandidateCollection() = default;
+
+JsepCandidateCollection::JsepCandidateCollection(JsepCandidateCollection&& o)
+ : candidates_(std::move(o.candidates_)) {}
+
+size_t JsepCandidateCollection::count() const {
+ return candidates_.size();
+}
+
+void JsepCandidateCollection::add(JsepIceCandidate* candidate) {
+ candidates_.push_back(candidate);
+}
+
+const IceCandidateInterface* JsepCandidateCollection::at(size_t index) const {
+ return candidates_[index];
+}
+
+JsepCandidateCollection::~JsepCandidateCollection() {
+ for (std::vector<JsepIceCandidate*>::iterator it = candidates_.begin();
+ it != candidates_.end(); ++it) {
+ delete *it;
+ }
+}
+
+bool JsepCandidateCollection::HasCandidate(
+ const IceCandidateInterface* candidate) const {
+ bool ret = false;
+ for (std::vector<JsepIceCandidate*>::const_iterator it = candidates_.begin();
+ it != candidates_.end(); ++it) {
+ if ((*it)->sdp_mid() == candidate->sdp_mid() &&
+ (*it)->sdp_mline_index() == candidate->sdp_mline_index() &&
+ (*it)->candidate().IsEquivalent(candidate->candidate())) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+size_t JsepCandidateCollection::remove(const cricket::Candidate& candidate) {
+ auto iter = std::find_if(candidates_.begin(), candidates_.end(),
+ [candidate](JsepIceCandidate* c) {
+ return candidate.MatchesForRemoval(c->candidate());
+ });
+ if (iter != candidates_.end()) {
+ delete *iter;
+ candidates_.erase(iter);
+ return 1;
+ }
+ return 0;
+}
+
+} // namespace webrtc
diff --git a/api/jsepicecandidate.h b/api/jsepicecandidate.h
index 4801a04..50520fe 100644
--- a/api/jsepicecandidate.h
+++ b/api/jsepicecandidate.h
@@ -31,20 +31,20 @@
JsepIceCandidate(const std::string& sdp_mid,
int sdp_mline_index,
const cricket::Candidate& candidate);
- ~JsepIceCandidate();
+ ~JsepIceCandidate() override;
// |err| may be null.
bool Initialize(const std::string& sdp, SdpParseError* err);
void SetCandidate(const cricket::Candidate& candidate) {
candidate_ = candidate;
}
- virtual std::string sdp_mid() const { return sdp_mid_; }
- virtual int sdp_mline_index() const { return sdp_mline_index_; }
- virtual const cricket::Candidate& candidate() const { return candidate_; }
+ std::string sdp_mid() const override;
+ int sdp_mline_index() const override;
+ const cricket::Candidate& candidate() const override;
- virtual std::string server_url() const { return candidate_.url(); }
+ std::string server_url() const override;
- virtual bool ToString(std::string* out) const;
+ bool ToString(std::string* out) const override;
private:
std::string sdp_mid_;
@@ -57,23 +57,18 @@
// Implementation of IceCandidateCollection which stores JsepIceCandidates.
class JsepCandidateCollection : public IceCandidateCollection {
public:
- JsepCandidateCollection() {}
+ JsepCandidateCollection();
// Move constructor is defined so that a vector of JsepCandidateCollections
// can be resized.
- JsepCandidateCollection(JsepCandidateCollection&& o)
- : candidates_(std::move(o.candidates_)) {}
- ~JsepCandidateCollection();
- virtual size_t count() const { return candidates_.size(); }
- virtual bool HasCandidate(const IceCandidateInterface* candidate) const;
+ JsepCandidateCollection(JsepCandidateCollection&& o);
+ ~JsepCandidateCollection() override;
+ size_t count() const override;
+ bool HasCandidate(const IceCandidateInterface* candidate) const override;
// Adds and takes ownership of the JsepIceCandidate.
// TODO(deadbeef): Make this use an std::unique_ptr<>, so ownership logic is
// more clear.
- virtual void add(JsepIceCandidate* candidate) {
- candidates_.push_back(candidate);
- }
- virtual const IceCandidateInterface* at(size_t index) const {
- return candidates_[index];
- }
+ virtual void add(JsepIceCandidate* candidate);
+ const IceCandidateInterface* at(size_t index) const override;
// Removes the candidate that has a matching address and protocol.
//
// Returns the number of candidates that were removed.
diff --git a/api/mediaconstraintsinterface.cc b/api/mediaconstraintsinterface.cc
index fb4481f..5567786 100644
--- a/api/mediaconstraintsinterface.cc
+++ b/api/mediaconstraintsinterface.cc
@@ -104,8 +104,6 @@
"googNoiseSuppression";
const char MediaConstraintsInterface::kExperimentalNoiseSuppression[] =
"googNoiseSuppression2";
-const char MediaConstraintsInterface::kIntelligibilityEnhancer[] =
- "intelligibilityEnhancer";
const char MediaConstraintsInterface::kHighpassFilter[] = "googHighpassFilter";
const char MediaConstraintsInterface::kTypingNoiseDetection[] =
"googTypingNoiseDetection";
@@ -146,6 +144,9 @@
"googCpuOveruseDetection";
const char MediaConstraintsInterface::kPayloadPadding[] = "googPayloadPadding";
+const char MediaConstraintsInterface::kNumSimulcastLayers[] =
+ "googNumSimulcastLayers";
+
// Set |value| to the value associated with the first appearance of |key|, or
// return false if |key| is not found.
bool MediaConstraintsInterface::Constraints::FindFirst(
@@ -238,9 +239,6 @@
ConstraintToOptional<bool>(
constraints, MediaConstraintsInterface::kExperimentalNoiseSuppression,
&options->experimental_ns);
- ConstraintToOptional<bool>(
- constraints, MediaConstraintsInterface::kIntelligibilityEnhancer,
- &options->intelligibility_enhancer);
ConstraintToOptional<bool>(constraints,
MediaConstraintsInterface::kHighpassFilter,
&options->highpass_filter);
@@ -260,4 +258,55 @@
}
}
+bool CopyConstraintsIntoOfferAnswerOptions(
+ const MediaConstraintsInterface* constraints,
+ PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options) {
+ if (!constraints) {
+ return true;
+ }
+
+ bool value = false;
+ size_t mandatory_constraints_satisfied = 0;
+
+ if (FindConstraint(constraints,
+ MediaConstraintsInterface::kOfferToReceiveAudio, &value,
+ &mandatory_constraints_satisfied)) {
+ offer_answer_options->offer_to_receive_audio =
+ value ? PeerConnectionInterface::RTCOfferAnswerOptions::
+ kOfferToReceiveMediaTrue
+ : 0;
+ }
+
+ if (FindConstraint(constraints,
+ MediaConstraintsInterface::kOfferToReceiveVideo, &value,
+ &mandatory_constraints_satisfied)) {
+ offer_answer_options->offer_to_receive_video =
+ value ? PeerConnectionInterface::RTCOfferAnswerOptions::
+ kOfferToReceiveMediaTrue
+ : 0;
+ }
+ if (FindConstraint(constraints,
+ MediaConstraintsInterface::kVoiceActivityDetection, &value,
+ &mandatory_constraints_satisfied)) {
+ offer_answer_options->voice_activity_detection = value;
+ }
+ if (FindConstraint(constraints, MediaConstraintsInterface::kUseRtpMux, &value,
+ &mandatory_constraints_satisfied)) {
+ offer_answer_options->use_rtp_mux = value;
+ }
+ if (FindConstraint(constraints, MediaConstraintsInterface::kIceRestart,
+ &value, &mandatory_constraints_satisfied)) {
+ offer_answer_options->ice_restart = value;
+ }
+
+ int layers;
+ if (FindConstraint(constraints,
+ MediaConstraintsInterface::kNumSimulcastLayers,
+ &layers, &mandatory_constraints_satisfied)) {
+ offer_answer_options->num_simulcast_layers = layers;
+ }
+
+ return mandatory_constraints_satisfied == constraints->GetMandatory().size();
+}
+
} // namespace webrtc
diff --git a/api/mediaconstraintsinterface.h b/api/mediaconstraintsinterface.h
index 54ab706..c6a914a 100644
--- a/api/mediaconstraintsinterface.h
+++ b/api/mediaconstraintsinterface.h
@@ -13,9 +13,10 @@
// http://www.w3.org/TR/mediacapture-streams/#mediastreamconstraints and also
// used in WebRTC: http://dev.w3.org/2011/webrtc/editor/webrtc.html#constraints.
-// This interface is being deprecated in Chrome, and may be removed
-// from WebRTC too.
-// https://bugs.chromium.org/p/webrtc/issues/detail?id=5617
+// Implementation of the w3c constraints spec is the responsibility of the
+// browser. Chrome no longer uses the constraints api declared here, and it will
+// be removed from WebRTC.
+// https://bugs.chromium.org/p/webrtc/issues/detail?id=9239
#ifndef API_MEDIACONSTRAINTSINTERFACE_H_
#define API_MEDIACONSTRAINTSINTERFACE_H_
@@ -72,7 +73,6 @@
static const char kExperimentalAutoGainControl[]; // googAutoGainControl2
static const char kNoiseSuppression[]; // googNoiseSuppression
static const char kExperimentalNoiseSuppression[]; // googNoiseSuppression2
- static const char kIntelligibilityEnhancer[]; // intelligibilityEnhancer
static const char kHighpassFilter[]; // googHighpassFilter
static const char kTypingNoiseDetection[]; // googTypingNoiseDetection
static const char kAudioMirroring[]; // googAudioMirroring
@@ -118,6 +118,11 @@
// stripped by Chrome before passed down to Libjingle.
static const char kInternalConstraintPrefix[];
+ // Specifies number of simulcast layers for all video tracks
+ // with a Plan B offer/answer
+ // (see RTCOfferAnswerOptions::num_simulcast_layers).
+ static const char kNumSimulcastLayers[];
+
virtual ~MediaConstraintsInterface() = default;
virtual const Constraints& GetMandatory() const = 0;
@@ -144,6 +149,10 @@
const MediaConstraintsInterface* constraints,
cricket::AudioOptions* options);
+bool CopyConstraintsIntoOfferAnswerOptions(
+ const MediaConstraintsInterface* constraints,
+ PeerConnectionInterface::RTCOfferAnswerOptions* offer_answer_options);
+
} // namespace webrtc
#endif // API_MEDIACONSTRAINTSINTERFACE_H_
diff --git a/api/peerconnectionfactoryproxy.h b/api/peerconnectionfactoryproxy.h
index db52083..d885cc1 100644
--- a/api/peerconnectionfactoryproxy.h
+++ b/api/peerconnectionfactoryproxy.h
@@ -31,13 +31,6 @@
// removed.
using PeerConnectionFactoryInterface::CreateVideoSource;
PROXY_METHOD1(void, SetOptions, const Options&)
-PROXY_METHOD5(rtc::scoped_refptr<PeerConnectionInterface>,
- CreatePeerConnection,
- const PeerConnectionInterface::RTCConfiguration&,
- const MediaConstraintsInterface*,
- std::unique_ptr<cricket::PortAllocator>,
- std::unique_ptr<rtc::RTCCertificateGeneratorInterface>,
- PeerConnectionObserver*);
PROXY_METHOD4(rtc::scoped_refptr<PeerConnectionInterface>,
CreatePeerConnection,
const PeerConnectionInterface::RTCConfiguration&,
diff --git a/api/peerconnectioninterface.cc b/api/peerconnectioninterface.cc
new file mode 100644
index 0000000..05aa53f
--- /dev/null
+++ b/api/peerconnectioninterface.cc
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2018 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/peerconnectioninterface.h"
+
+namespace webrtc {
+
+PeerConnectionInterface::IceServer::IceServer() = default;
+PeerConnectionInterface::IceServer::IceServer(const IceServer& rhs) = default;
+PeerConnectionInterface::IceServer::~IceServer() = default;
+
+PeerConnectionInterface::RTCConfiguration::RTCConfiguration() = default;
+
+PeerConnectionInterface::RTCConfiguration::RTCConfiguration(
+ const RTCConfiguration& rhs) = default;
+
+PeerConnectionInterface::RTCConfiguration::RTCConfiguration(
+ RTCConfigurationType type) {
+ if (type == RTCConfigurationType::kAggressive) {
+ // These parameters are also defined in Java and IOS configurations,
+ // so their values may be overwritten by the Java or IOS configuration.
+ bundle_policy = kBundlePolicyMaxBundle;
+ rtcp_mux_policy = kRtcpMuxPolicyRequire;
+ ice_connection_receiving_timeout = kAggressiveIceConnectionReceivingTimeout;
+
+ // These parameters are not defined in Java or IOS configuration,
+ // so their values will not be overwritten.
+ enable_ice_renomination = true;
+ redetermine_role_on_ice_restart = false;
+ }
+}
+
+PeerConnectionInterface::RTCConfiguration::~RTCConfiguration() = default;
+
+RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>
+PeerConnectionInterface::AddTrack(
+ rtc::scoped_refptr<MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids) {
+ return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented");
+}
+
+bool PeerConnectionInterface::RemoveTrack(RtpSenderInterface* sender) {
+ return RemoveTrackNew(sender).ok();
+}
+
+RTCError PeerConnectionInterface::RemoveTrackNew(
+ rtc::scoped_refptr<RtpSenderInterface> sender) {
+ return RTCError(RemoveTrack(sender) ? RTCErrorType::NONE
+ : RTCErrorType::INTERNAL_ERROR);
+}
+
+RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+PeerConnectionInterface::AddTransceiver(
+ rtc::scoped_refptr<MediaStreamTrackInterface> track) {
+ return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
+}
+
+RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+PeerConnectionInterface::AddTransceiver(
+ rtc::scoped_refptr<MediaStreamTrackInterface> track,
+ const RtpTransceiverInit& init) {
+ return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
+}
+
+RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+PeerConnectionInterface::AddTransceiver(cricket::MediaType media_type) {
+ return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
+}
+
+RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
+PeerConnectionInterface::AddTransceiver(cricket::MediaType media_type,
+ const RtpTransceiverInit& init) {
+ return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
+}
+
+rtc::scoped_refptr<RtpSenderInterface> PeerConnectionInterface::CreateSender(
+ const std::string& kind,
+ const std::string& stream_id) {
+ return rtc::scoped_refptr<RtpSenderInterface>();
+}
+
+std::vector<rtc::scoped_refptr<RtpSenderInterface>>
+PeerConnectionInterface::GetSenders() const {
+ return std::vector<rtc::scoped_refptr<RtpSenderInterface>>();
+}
+
+std::vector<rtc::scoped_refptr<RtpReceiverInterface>>
+PeerConnectionInterface::GetReceivers() const {
+ return std::vector<rtc::scoped_refptr<RtpReceiverInterface>>();
+}
+
+std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
+PeerConnectionInterface::GetTransceivers() const {
+ return std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>();
+}
+
+const SessionDescriptionInterface*
+PeerConnectionInterface::current_local_description() const {
+ return nullptr;
+}
+
+const SessionDescriptionInterface*
+PeerConnectionInterface::current_remote_description() const {
+ return nullptr;
+}
+
+const SessionDescriptionInterface*
+PeerConnectionInterface::pending_local_description() const {
+ return nullptr;
+}
+
+const SessionDescriptionInterface*
+PeerConnectionInterface::pending_remote_description() const {
+ return nullptr;
+}
+
+PeerConnectionInterface::RTCConfiguration
+PeerConnectionInterface::GetConfiguration() {
+ return PeerConnectionInterface::RTCConfiguration();
+}
+
+bool PeerConnectionInterface::SetConfiguration(
+ const PeerConnectionInterface::RTCConfiguration& config,
+ RTCError* error) {
+ return false;
+}
+
+bool PeerConnectionInterface::SetConfiguration(
+ const PeerConnectionInterface::RTCConfiguration& config) {
+ return false;
+}
+
+bool PeerConnectionInterface::RemoveIceCandidates(
+ const std::vector<cricket::Candidate>& candidates) {
+ return false;
+}
+
+RTCError PeerConnectionInterface::SetBitrate(const BitrateSettings& bitrate) {
+ BitrateParameters bitrate_parameters;
+ bitrate_parameters.min_bitrate_bps = bitrate.min_bitrate_bps;
+ bitrate_parameters.current_bitrate_bps = bitrate.start_bitrate_bps;
+ bitrate_parameters.max_bitrate_bps = bitrate.max_bitrate_bps;
+ return SetBitrate(bitrate_parameters);
+}
+
+RTCError PeerConnectionInterface::SetBitrate(
+ const BitrateParameters& bitrate_parameters) {
+ BitrateSettings bitrate;
+ bitrate.min_bitrate_bps = bitrate_parameters.min_bitrate_bps;
+ bitrate.start_bitrate_bps = bitrate_parameters.current_bitrate_bps;
+ bitrate.max_bitrate_bps = bitrate_parameters.max_bitrate_bps;
+ return SetBitrate(bitrate);
+}
+
+bool PeerConnectionInterface::StartRtcEventLog(rtc::PlatformFile file,
+ int64_t max_size_bytes) {
+ return false;
+}
+
+bool PeerConnectionInterface::StartRtcEventLog(
+ std::unique_ptr<RtcEventLogOutput> output,
+ int64_t output_period_ms) {
+ return false;
+}
+
+PeerConnectionInterface::BitrateParameters::BitrateParameters() = default;
+
+PeerConnectionInterface::BitrateParameters::~BitrateParameters() = default;
+
+PeerConnectionDependencies::PeerConnectionDependencies(
+ PeerConnectionObserver* observer_in)
+ : observer(observer_in) {}
+
+PeerConnectionDependencies::PeerConnectionDependencies(
+ PeerConnectionDependencies&&) = default;
+
+PeerConnectionDependencies::~PeerConnectionDependencies() = default;
+
+PeerConnectionFactoryDependencies::PeerConnectionFactoryDependencies() =
+ default;
+
+PeerConnectionFactoryDependencies::PeerConnectionFactoryDependencies(
+ PeerConnectionFactoryDependencies&&) = default;
+
+PeerConnectionFactoryDependencies::~PeerConnectionFactoryDependencies() =
+ default;
+
+rtc::scoped_refptr<PeerConnectionInterface>
+PeerConnectionFactoryInterface::CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ const MediaConstraintsInterface* constraints,
+ std::unique_ptr<cricket::PortAllocator> allocator,
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
+ PeerConnectionObserver* observer) {
+ return nullptr;
+}
+
+rtc::scoped_refptr<PeerConnectionInterface>
+PeerConnectionFactoryInterface::CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ std::unique_ptr<cricket::PortAllocator> allocator,
+ std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
+ PeerConnectionObserver* observer) {
+ return nullptr;
+}
+
+rtc::scoped_refptr<PeerConnectionInterface>
+PeerConnectionFactoryInterface::CreatePeerConnection(
+ const PeerConnectionInterface::RTCConfiguration& configuration,
+ PeerConnectionDependencies dependencies) {
+ return nullptr;
+}
+
+RtpCapabilities PeerConnectionFactoryInterface::GetRtpSenderCapabilities(
+ cricket::MediaType kind) const {
+ return {};
+}
+
+RtpCapabilities PeerConnectionFactoryInterface::GetRtpReceiverCapabilities(
+ cricket::MediaType kind) const {
+ return {};
+}
+
+rtc::scoped_refptr<VideoTrackSourceInterface>
+PeerConnectionFactoryInterface::CreateVideoSource(
+ std::unique_ptr<cricket::VideoCapturer> capturer) {
+ return nullptr;
+}
+
+rtc::scoped_refptr<VideoTrackSourceInterface>
+PeerConnectionFactoryInterface::CreateVideoSource(
+ std::unique_ptr<cricket::VideoCapturer> capturer,
+ const MediaConstraintsInterface* constraints) {
+ return nullptr;
+}
+
+rtc::scoped_refptr<VideoTrackSourceInterface>
+PeerConnectionFactoryInterface::CreateVideoSource(
+ cricket::VideoCapturer* capturer) {
+ return CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(capturer));
+}
+
+} // namespace webrtc
diff --git a/api/peerconnectioninterface.h b/api/peerconnectioninterface.h
index 90a99a6..2b94ee8 100644
--- a/api/peerconnectioninterface.h
+++ b/api/peerconnectioninterface.h
@@ -72,6 +72,7 @@
#include <utility>
#include <vector>
+#include "api/asyncresolverfactory.h"
#include "api/audio/audio_mixer.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/audio_encoder_factory.h"
@@ -102,6 +103,7 @@
// TODO(bugs.webrtc.org/7447): We plan to provide a way to let applications
// inject a PacketSocketFactory and/or NetworkManager, and not expose
// PortAllocator in the PeerConnection api.
+#include "media/base/mediaengine.h" // nogncheck
#include "p2p/base/portallocator.h" // nogncheck
// TODO(nisse): The interface for bitrate allocation strategy belongs in api/.
#include "rtc_base/bitrateallocationstrategy.h"
@@ -119,7 +121,6 @@
} // namespace rtc
namespace cricket {
-class MediaEngineInterface;
class WebRtcVideoDecoderFactory;
class WebRtcVideoEncoderFactory;
} // namespace cricket
@@ -144,7 +145,7 @@
protected:
// Dtor protected as objects shouldn't be deleted via this interface.
- ~StreamCollectionInterface() {}
+ ~StreamCollectionInterface() override = default;
};
class StatsObserver : public rtc::RefCountInterface {
@@ -152,7 +153,7 @@
virtual void OnComplete(const StatsReports& reports) = 0;
protected:
- virtual ~StatsObserver() {}
+ ~StatsObserver() override = default;
};
enum class SdpSemantics { kPlanB, kUnifiedPlan };
@@ -198,6 +199,10 @@
};
struct IceServer {
+ IceServer();
+ IceServer(const IceServer&);
+ ~IceServer();
+
// TODO(jbauch): Remove uri when all code using it has switched to urls.
// List of URIs associated with this server. Valid formats are described
// in RFC7064 and RFC7065, and more may be added in the future. The "host"
@@ -284,22 +289,10 @@
// methods for all settings which are of interest to applications,
// Chrome in particular.
- RTCConfiguration() = default;
- explicit RTCConfiguration(RTCConfigurationType type) {
- if (type == RTCConfigurationType::kAggressive) {
- // These parameters are also defined in Java and IOS configurations,
- // so their values may be overwritten by the Java or IOS configuration.
- bundle_policy = kBundlePolicyMaxBundle;
- rtcp_mux_policy = kRtcpMuxPolicyRequire;
- ice_connection_receiving_timeout =
- kAggressiveIceConnectionReceivingTimeout;
-
- // These parameters are not defined in Java or IOS configuration,
- // so their values will not be overwritten.
- enable_ice_renomination = true;
- redetermine_role_on_ice_restart = false;
- }
- }
+ RTCConfiguration();
+ RTCConfiguration(const RTCConfiguration&);
+ explicit RTCConfiguration(RTCConfigurationType type);
+ ~RTCConfiguration();
bool operator==(const RTCConfiguration& o) const;
bool operator!=(const RTCConfiguration& o) const;
@@ -603,6 +596,9 @@
// confused with RTCP mux (multiplexing RTP and RTCP together).
bool use_rtp_mux = true;
+ // This will apply to all video tracks with a Plan B SDP offer/answer.
+ int num_simulcast_layers = 1;
+
RTCOfferAnswerOptions() = default;
RTCOfferAnswerOptions(int offer_to_receive_video,
@@ -668,11 +664,25 @@
// - INVALID_STATE: The PeerConnection is closed.
virtual RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> AddTrack(
rtc::scoped_refptr<MediaStreamTrackInterface> track,
- const std::vector<std::string>& stream_ids) = 0;
+ const std::vector<std::string>& stream_ids);
// Remove an RtpSender from this PeerConnection.
// Returns true on success.
- virtual bool RemoveTrack(RtpSenderInterface* sender) = 0;
+ // TODO(steveanton): Replace with signature that returns RTCError.
+ virtual bool RemoveTrack(RtpSenderInterface* sender);
+
+ // Plan B semantics: Removes the RtpSender from this PeerConnection.
+ // Unified Plan semantics: Stop sending on the RtpSender and mark the
+ // corresponding RtpTransceiver direction as no longer sending.
+ //
+ // Errors:
+ // - INVALID_PARAMETER: |sender| is null or (Plan B only) the sender is not
+ // associated with this PeerConnection.
+ // - INVALID_STATE: PeerConnection is closed.
+ // TODO(bugs.webrtc.org/9534): Rename to RemoveTrack once the other signature
+ // is removed.
+ virtual RTCError RemoveTrackNew(
+ rtc::scoped_refptr<RtpSenderInterface> sender);
// AddTransceiver creates a new RtpTransceiver and adds it to the set of
// transceivers. Adding a transceiver will cause future calls to CreateOffer
@@ -701,14 +711,10 @@
// Errors:
// - INVALID_PARAMETER: |track| is null.
virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
- AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track) {
- return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
- }
+ AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track);
virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track,
- const RtpTransceiverInit& init) {
- return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
- }
+ const RtpTransceiverInit& init);
// Adds a transceiver with the given kind. Can either be MEDIA_TYPE_AUDIO or
// MEDIA_TYPE_VIDEO.
@@ -716,14 +722,9 @@
// - INVALID_PARAMETER: |media_type| is not MEDIA_TYPE_AUDIO or
// MEDIA_TYPE_VIDEO.
virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
- AddTransceiver(cricket::MediaType media_type) {
- return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
- }
+ AddTransceiver(cricket::MediaType media_type);
virtual RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>>
- AddTransceiver(cricket::MediaType media_type,
- const RtpTransceiverInit& init) {
- return RTCError(RTCErrorType::INTERNAL_ERROR, "not implemented");
- }
+ AddTransceiver(cricket::MediaType media_type, const RtpTransceiverInit& init);
// TODO(deadbeef): Make these pure virtual once all subclasses implement them.
@@ -743,9 +744,7 @@
// AddTransceiver instead.
virtual rtc::scoped_refptr<RtpSenderInterface> CreateSender(
const std::string& kind,
- const std::string& stream_id) {
- return rtc::scoped_refptr<RtpSenderInterface>();
- }
+ const std::string& stream_id);
// If Plan B semantics are specified, gets all RtpSenders, created either
// through AddStream, AddTrack, or CreateSender. All senders of a specific
@@ -754,9 +753,7 @@
// If Unified Plan semantics are specified, gets the RtpSender for each
// RtpTransceiver.
virtual std::vector<rtc::scoped_refptr<RtpSenderInterface>> GetSenders()
- const {
- return std::vector<rtc::scoped_refptr<RtpSenderInterface>>();
- }
+ const;
// If Plan B semantics are specified, gets all RtpReceivers created when a
// remote description is applied. All receivers of a specific media type share
@@ -767,9 +764,7 @@
// If Unified Plan semantics are specified, gets the RtpReceiver for each
// RtpTransceiver.
virtual std::vector<rtc::scoped_refptr<RtpReceiverInterface>> GetReceivers()
- const {
- return std::vector<rtc::scoped_refptr<RtpReceiverInterface>>();
- }
+ const;
// Get all RtpTransceivers, created either through AddTransceiver, AddTrack or
// by a remote description applied with SetRemoteDescription.
@@ -777,9 +772,7 @@
// Note: This method is only available when Unified Plan is enabled (see
// RTCConfiguration).
virtual std::vector<rtc::scoped_refptr<RtpTransceiverInterface>>
- GetTransceivers() const {
- return {};
- }
+ GetTransceivers() const;
// The legacy non-compliant GetStats() API. This correspond to the
// callback-based version of getStats() in JavaScript. The returned metrics
@@ -844,44 +837,24 @@
// A "current" description the one currently negotiated from a complete
// offer/answer exchange.
- virtual const SessionDescriptionInterface* current_local_description() const {
- return nullptr;
- }
- virtual const SessionDescriptionInterface* current_remote_description()
- const {
- return nullptr;
- }
+ virtual const SessionDescriptionInterface* current_local_description() const;
+ virtual const SessionDescriptionInterface* current_remote_description() const;
// A "pending" description is one that's part of an incomplete offer/answer
// exchange (thus, either an offer or a pranswer). Once the offer/answer
// exchange is finished, the "pending" description will become "current".
- virtual const SessionDescriptionInterface* pending_local_description() const {
- return nullptr;
- }
- virtual const SessionDescriptionInterface* pending_remote_description()
- const {
- return nullptr;
- }
+ virtual const SessionDescriptionInterface* pending_local_description() const;
+ virtual const SessionDescriptionInterface* pending_remote_description() const;
// Create a new offer.
// The CreateSessionDescriptionObserver callback will be called when done.
virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
- const MediaConstraintsInterface* constraints) {}
-
- // TODO(jiayl): remove the default impl and the old interface when chromium
- // code is updated.
- virtual void CreateOffer(CreateSessionDescriptionObserver* observer,
- const RTCOfferAnswerOptions& options) {}
+ const RTCOfferAnswerOptions& options) = 0;
// Create an answer to an offer.
// The CreateSessionDescriptionObserver callback will be called when done.
virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
- const RTCOfferAnswerOptions& options) {}
- // Deprecated - use version above.
- // TODO(hta): Remove and remove default implementations when all callers
- // are updated.
- virtual void CreateAnswer(CreateSessionDescriptionObserver* observer,
- const MediaConstraintsInterface* constraints) {}
+ const RTCOfferAnswerOptions& options) = 0;
// Sets the local session description.
// The PeerConnection takes the ownership of |desc| even if it fails.
@@ -903,9 +876,7 @@
// TODO(deadbeef): Make this pure virtual once all Chrome subclasses of
// PeerConnectionInterface implement it.
- virtual PeerConnectionInterface::RTCConfiguration GetConfiguration() {
- return PeerConnectionInterface::RTCConfiguration();
- }
+ virtual PeerConnectionInterface::RTCConfiguration GetConfiguration();
// Sets the PeerConnection's global configuration to |config|.
//
@@ -932,15 +903,12 @@
// PeerConnectionInterface implement it.
virtual bool SetConfiguration(
const PeerConnectionInterface::RTCConfiguration& config,
- RTCError* error) {
- return false;
- }
+ RTCError* error);
+
// Version without error output param for backwards compatibility.
// TODO(deadbeef): Remove once chromium is updated.
virtual bool SetConfiguration(
- const PeerConnectionInterface::RTCConfiguration& config) {
- return false;
- }
+ const PeerConnectionInterface::RTCConfiguration& config);
// Provides a remote candidate to the ICE Agent.
// A copy of the |candidate| will be created and added to the remote
@@ -952,21 +920,13 @@
// continual gathering, to avoid an ever-growing list of candidates as
// networks come and go.
virtual bool RemoveIceCandidates(
- const std::vector<cricket::Candidate>& candidates) {
- return false;
- }
-
- // Register a metric observer (used by chromium). It's reference counted, and
- // this method takes a reference. RegisterUMAObserver(nullptr) will release
- // the reference.
- // TODO(deadbeef): Take argument as scoped_refptr?
- //
- // This method is soon to be deprecated. This no-op default implementation
- // allows the implementations of the interface to remove this method.
- virtual void RegisterUMAObserver(UMAObserver* observer) {}
+ const std::vector<cricket::Candidate>& candidates);
// 0 <= min <= current <= max should hold for set parameters.
struct BitrateParameters {
+ BitrateParameters();
+ ~BitrateParameters();
+
absl::optional<int> min_bitrate_bps;
absl::optional<int> current_bitrate_bps;
absl::optional<int> max_bitrate_bps;
@@ -978,24 +938,12 @@
//
// Setting |current_bitrate_bps| will reset the current bitrate estimate
// to the provided value.
- virtual RTCError SetBitrate(const BitrateSettings& bitrate) {
- BitrateParameters bitrate_parameters;
- bitrate_parameters.min_bitrate_bps = bitrate.min_bitrate_bps;
- bitrate_parameters.current_bitrate_bps = bitrate.start_bitrate_bps;
- bitrate_parameters.max_bitrate_bps = bitrate.max_bitrate_bps;
- return SetBitrate(bitrate_parameters);
- }
+ virtual RTCError SetBitrate(const BitrateSettings& bitrate);
// TODO(nisse): Deprecated - use version above. These two default
// implementations require subclasses to implement one or the other
// of the methods.
- virtual RTCError SetBitrate(const BitrateParameters& bitrate_parameters) {
- BitrateSettings bitrate;
- bitrate.min_bitrate_bps = bitrate_parameters.min_bitrate_bps;
- bitrate.start_bitrate_bps = bitrate_parameters.current_bitrate_bps;
- bitrate.max_bitrate_bps = bitrate_parameters.max_bitrate_bps;
- return SetBitrate(bitrate);
- }
+ virtual RTCError SetBitrate(const BitrateParameters& bitrate_parameters);
// Sets current strategy. If not set default WebRTC allocator will be used.
// May be changed during an active session. The strategy
@@ -1037,19 +985,14 @@
// automatically after 10 minutes have passed, or when the StopRtcEventLog
// function is called.
// TODO(eladalon): Deprecate and remove this.
- virtual bool StartRtcEventLog(rtc::PlatformFile file,
- int64_t max_size_bytes) {
- return false;
- }
+ virtual bool StartRtcEventLog(rtc::PlatformFile file, int64_t max_size_bytes);
// Start RtcEventLog using an existing output-sink. Takes ownership of
// |output| and passes it on to Call, which will take the ownership. If the
// operation fails the output will be closed and deallocated. The event log
// will send serialized events to the output object every |output_period_ms|.
virtual bool StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,
- int64_t output_period_ms) {
- return false;
- }
+ int64_t output_period_ms);
// Stops logging the RtcEventLog.
// TODO(ivoc): Make this pure virtual when Chrome is updated.
@@ -1065,7 +1008,7 @@
protected:
// Dtor protected as objects shouldn't be deleted via this interface.
- ~PeerConnectionInterface() {}
+ ~PeerConnectionInterface() override = default;
};
// PeerConnection callback interface, used for RTCPeerConnection events.
@@ -1149,6 +1092,14 @@
// TODO(hbos,deadbeef): Make pure virtual when all subclasses implement it.
virtual void OnRemoveTrack(
rtc::scoped_refptr<RtpReceiverInterface> receiver) {}
+
+ // Called when an interesting usage is detected by WebRTC.
+ // An appropriate action is to add information about the context of the
+ // PeerConnection and write the event to some kind of "interesting events"
+ // log function.
+ // The heuristics for defining what constitutes "interesting" are
+ // implementation-defined.
+ virtual void OnInterestingUsage(int usage_pattern) {}
};
// PeerConnectionDependencies holds all of PeerConnections dependencies.
@@ -1159,19 +1110,20 @@
// PeerConnection object to be the definitive owner of the dependencies
// lifetime making injection safer.
struct PeerConnectionDependencies final {
- explicit PeerConnectionDependencies(PeerConnectionObserver* observer_in)
- : observer(observer_in) {}
+ explicit PeerConnectionDependencies(PeerConnectionObserver* observer_in);
// This object is not copyable or assignable.
PeerConnectionDependencies(const PeerConnectionDependencies&) = delete;
PeerConnectionDependencies& operator=(const PeerConnectionDependencies&) =
delete;
// This object is only moveable.
- PeerConnectionDependencies(PeerConnectionDependencies&&) = default;
+ PeerConnectionDependencies(PeerConnectionDependencies&&);
PeerConnectionDependencies& operator=(PeerConnectionDependencies&&) = default;
+ ~PeerConnectionDependencies();
// Mandatory dependencies
PeerConnectionObserver* observer = nullptr;
// Optional dependencies
std::unique_ptr<cricket::PortAllocator> allocator;
+ std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory;
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator;
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier;
};
@@ -1183,17 +1135,17 @@
// connection factory to take ownership of the dependency by adding a unique_ptr
// to this structure.
struct PeerConnectionFactoryDependencies final {
- PeerConnectionFactoryDependencies() = default;
+ PeerConnectionFactoryDependencies();
// This object is not copyable or assignable.
PeerConnectionFactoryDependencies(const PeerConnectionFactoryDependencies&) =
delete;
PeerConnectionFactoryDependencies& operator=(
const PeerConnectionFactoryDependencies&) = delete;
// This object is only moveable.
- PeerConnectionFactoryDependencies(PeerConnectionFactoryDependencies&&) =
- default;
+ PeerConnectionFactoryDependencies(PeerConnectionFactoryDependencies&&);
PeerConnectionFactoryDependencies& operator=(
PeerConnectionFactoryDependencies&&) = default;
+ ~PeerConnectionFactoryDependencies();
// Optional dependencies
rtc::Thread* network_thread = nullptr;
@@ -1264,9 +1216,7 @@
// are updated.
virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
const PeerConnectionInterface::RTCConfiguration& configuration,
- PeerConnectionDependencies dependencies) {
- return nullptr;
- }
+ PeerConnectionDependencies dependencies);
// Deprecated; |allocator| and |cert_generator| may be null, in which case
// default implementations will be used.
@@ -1281,9 +1231,8 @@
const PeerConnectionInterface::RTCConfiguration& configuration,
std::unique_ptr<cricket::PortAllocator> allocator,
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
- PeerConnectionObserver* observer) {
- return nullptr;
- }
+ PeerConnectionObserver* observer);
+
// Deprecated; should use RTCConfiguration for everything that previously
// used constraints.
virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
@@ -1291,25 +1240,19 @@
const MediaConstraintsInterface* constraints,
std::unique_ptr<cricket::PortAllocator> allocator,
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
- PeerConnectionObserver* observer) {
- return nullptr;
- }
+ PeerConnectionObserver* observer);
// Returns the capabilities of an RTP sender of type |kind|.
// If for some reason you pass in MEDIA_TYPE_DATA, returns an empty structure.
// TODO(orphis): Make pure virtual when all subclasses implement it.
virtual RtpCapabilities GetRtpSenderCapabilities(
- cricket::MediaType kind) const {
- return {};
- }
+ cricket::MediaType kind) const;
// Returns the capabilities of an RTP receiver of type |kind|.
// If for some reason you pass in MEDIA_TYPE_DATA, returns an empty structure.
// TODO(orphis): Make pure virtual when all subclasses implement it.
virtual RtpCapabilities GetRtpReceiverCapabilities(
- cricket::MediaType kind) const {
- return {};
- }
+ cricket::MediaType kind) const;
virtual rtc::scoped_refptr<MediaStreamInterface> CreateLocalMediaStream(
const std::string& stream_id) = 0;
@@ -1327,9 +1270,7 @@
// TODO(deadbeef): Make pure virtual once downstream mock PC factory classes
// are updated.
virtual rtc::scoped_refptr<VideoTrackSourceInterface> CreateVideoSource(
- std::unique_ptr<cricket::VideoCapturer> capturer) {
- return nullptr;
- }
+ std::unique_ptr<cricket::VideoCapturer> capturer);
// A video source creator that allows selection of resolution and frame rate.
// |constraints| decides video resolution and frame rate but can be null.
@@ -1339,23 +1280,12 @@
// safely be destroyed afterwards.
virtual rtc::scoped_refptr<VideoTrackSourceInterface> CreateVideoSource(
std::unique_ptr<cricket::VideoCapturer> capturer,
- const MediaConstraintsInterface* constraints) {
- return nullptr;
- }
+ const MediaConstraintsInterface* constraints);
// Deprecated; please use the versions that take unique_ptrs above.
// TODO(deadbeef): Remove these once safe to do so.
virtual rtc::scoped_refptr<VideoTrackSourceInterface> CreateVideoSource(
- cricket::VideoCapturer* capturer) {
- return CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(capturer));
- }
- virtual rtc::scoped_refptr<VideoTrackSourceInterface> CreateVideoSource(
- cricket::VideoCapturer* capturer,
- const MediaConstraintsInterface* constraints) {
- return CreateVideoSource(std::unique_ptr<cricket::VideoCapturer>(capturer),
- constraints);
- }
-
+ cricket::VideoCapturer* capturer);
// Creates a new local VideoTrack. The same |source| can be used in several
// tracks.
virtual rtc::scoped_refptr<VideoTrackInterface> CreateVideoTrack(
@@ -1383,9 +1313,10 @@
// Dtor and ctor protected as objects shouldn't be created or deleted via
// this interface.
PeerConnectionFactoryInterface() {}
- ~PeerConnectionFactoryInterface() {} // NOLINT
+ ~PeerConnectionFactoryInterface() override = default;
};
+#if defined(USE_BUILTIN_SW_CODECS)
// Create a new instance of PeerConnectionFactoryInterface.
//
// This method relies on the thread it's called on as the "signaling thread"
@@ -1462,6 +1393,7 @@
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory,
std::unique_ptr<NetworkControllerFactoryInterface>
network_controller_factory = nullptr);
+#endif
// Create a new instance of PeerConnectionFactoryInterface with optional video
// codec factories. These video factories represents all video codecs, i.e. no
@@ -1480,6 +1412,7 @@
rtc::scoped_refptr<AudioMixer> audio_mixer,
rtc::scoped_refptr<AudioProcessing> audio_processing);
+#if defined(USE_BUILTIN_SW_CODECS)
// Create a new instance of PeerConnectionFactoryInterface with external audio
// mixer.
//
@@ -1512,6 +1445,7 @@
default_adm, audio_encoder_factory, audio_decoder_factory,
video_encoder_factory, video_decoder_factory);
}
+#endif
// This is a lower-level version of the CreatePeerConnectionFactory functions
// above. It's implemented in the "peerconnection" build target, whereas the
diff --git a/api/peerconnectionproxy.h b/api/peerconnectionproxy.h
index 6855975..6b66bcc 100644
--- a/api/peerconnectionproxy.h
+++ b/api/peerconnectionproxy.h
@@ -88,14 +88,6 @@
PROXY_METHOD2(void,
CreateOffer,
CreateSessionDescriptionObserver*,
- const MediaConstraintsInterface*)
-PROXY_METHOD2(void,
- CreateAnswer,
- CreateSessionDescriptionObserver*,
- const MediaConstraintsInterface*)
-PROXY_METHOD2(void,
- CreateOffer,
- CreateSessionDescriptionObserver*,
const RTCOfferAnswerOptions&)
PROXY_METHOD2(void,
CreateAnswer,
@@ -127,7 +119,6 @@
const std::vector<cricket::Candidate>&);
PROXY_METHOD1(void, SetAudioPlayout, bool)
PROXY_METHOD1(void, SetAudioRecording, bool)
-PROXY_METHOD1(void, RegisterUMAObserver, UMAObserver*)
PROXY_METHOD1(RTCError, SetBitrate, const BitrateSettings&);
PROXY_METHOD1(void,
SetBitrateAllocationStrategy,
diff --git a/api/rtp_headers.h b/api/rtp_headers.h
index ded6c4b..c762534 100644
--- a/api/rtp_headers.h
+++ b/api/rtp_headers.h
@@ -25,7 +25,6 @@
#include "common_types.h" // NOLINT(build/include)
#include "rtc_base/checks.h"
#include "rtc_base/deprecation.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -40,7 +39,14 @@
// maximum length that can be encoded with one-byte header extensions.
static constexpr size_t kMaxSize = 16;
- static bool IsLegalName(rtc::ArrayView<const char> name);
+ static bool IsLegalMidName(rtc::ArrayView<const char> name);
+ static bool IsLegalRsidName(rtc::ArrayView<const char> name);
+
+ // TODO(bugs.webrtc.org/9537): Deprecate and remove when third parties have
+ // migrated to "IsLegalRsidName".
+ static bool IsLegalName(rtc::ArrayView<const char> name) {
+ return IsLegalRsidName(name);
+ }
StringRtpHeaderExtension() { value_[0] = 0; }
explicit StringRtpHeaderExtension(rtc::ArrayView<const char> value) {
diff --git a/api/rtpparameters.cc b/api/rtpparameters.cc
index 5a873de..62ca3fc 100644
--- a/api/rtpparameters.cc
+++ b/api/rtpparameters.cc
@@ -19,17 +19,18 @@
const double kDefaultBitratePriority = 1.0;
-RtcpFeedback::RtcpFeedback() {}
+RtcpFeedback::RtcpFeedback() = default;
RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {}
RtcpFeedback::RtcpFeedback(RtcpFeedbackType type,
RtcpFeedbackMessageType message_type)
: type(type), message_type(message_type) {}
-RtcpFeedback::~RtcpFeedback() {}
+RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default;
+RtcpFeedback::~RtcpFeedback() = default;
-RtpCodecCapability::RtpCodecCapability() {}
-RtpCodecCapability::~RtpCodecCapability() {}
+RtpCodecCapability::RtpCodecCapability() = default;
+RtpCodecCapability::~RtpCodecCapability() = default;
-RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() {}
+RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
const std::string& uri)
: uri(uri) {}
@@ -37,39 +38,46 @@
const std::string& uri,
int preferred_id)
: uri(uri), preferred_id(preferred_id) {}
-RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() {}
+RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;
-RtpExtension::RtpExtension() {}
+RtpExtension::RtpExtension() = default;
RtpExtension::RtpExtension(const std::string& uri, int id) : uri(uri), id(id) {}
RtpExtension::RtpExtension(const std::string& uri, int id, bool encrypt)
: uri(uri), id(id), encrypt(encrypt) {}
-RtpExtension::~RtpExtension() {}
+RtpExtension::~RtpExtension() = default;
-RtpFecParameters::RtpFecParameters() {}
+RtpFecParameters::RtpFecParameters() = default;
RtpFecParameters::RtpFecParameters(FecMechanism mechanism)
: mechanism(mechanism) {}
RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
: ssrc(ssrc), mechanism(mechanism) {}
-RtpFecParameters::~RtpFecParameters() {}
+RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default;
+RtpFecParameters::~RtpFecParameters() = default;
-RtpRtxParameters::RtpRtxParameters() {}
+RtpRtxParameters::RtpRtxParameters() = default;
RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
-RtpRtxParameters::~RtpRtxParameters() {}
+RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
+RtpRtxParameters::~RtpRtxParameters() = default;
-RtpEncodingParameters::RtpEncodingParameters() {}
-RtpEncodingParameters::~RtpEncodingParameters() {}
+RtpEncodingParameters::RtpEncodingParameters() = default;
+RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
+ default;
+RtpEncodingParameters::~RtpEncodingParameters() = default;
-RtpCodecParameters::RtpCodecParameters() {}
-RtpCodecParameters::~RtpCodecParameters() {}
+RtpCodecParameters::RtpCodecParameters() = default;
+RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default;
+RtpCodecParameters::~RtpCodecParameters() = default;
-RtpCapabilities::RtpCapabilities() {}
-RtpCapabilities::~RtpCapabilities() {}
+RtpCapabilities::RtpCapabilities() = default;
+RtpCapabilities::~RtpCapabilities() = default;
-RtcpParameters::RtcpParameters() {}
-RtcpParameters::~RtcpParameters() {}
+RtcpParameters::RtcpParameters() = default;
+RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default;
+RtcpParameters::~RtcpParameters() = default;
-RtpParameters::RtpParameters() {}
-RtpParameters::~RtpParameters() {}
+RtpParameters::RtpParameters() = default;
+RtpParameters::RtpParameters(const RtpParameters& rhs) = default;
+RtpParameters::~RtpParameters() = default;
std::string RtpExtension::ToString() const {
char buf[256];
diff --git a/api/rtpparameters.h b/api/rtpparameters.h
index ba318ca..9a29c08 100644
--- a/api/rtpparameters.h
+++ b/api/rtpparameters.h
@@ -100,6 +100,7 @@
RtcpFeedback();
explicit RtcpFeedback(RtcpFeedbackType type);
RtcpFeedback(RtcpFeedbackType type, RtcpFeedbackMessageType message_type);
+ RtcpFeedback(const RtcpFeedback&);
~RtcpFeedback();
bool operator==(const RtcpFeedback& o) const {
@@ -321,6 +322,7 @@
RtpFecParameters();
explicit RtpFecParameters(FecMechanism mechanism);
RtpFecParameters(FecMechanism mechanism, uint32_t ssrc);
+ RtpFecParameters(const RtpFecParameters&);
~RtpFecParameters();
bool operator==(const RtpFecParameters& o) const {
@@ -337,6 +339,7 @@
// Constructors for convenience.
RtpRtxParameters();
explicit RtpRtxParameters(uint32_t ssrc);
+ RtpRtxParameters(const RtpRtxParameters&);
~RtpRtxParameters();
bool operator==(const RtpRtxParameters& o) const { return ssrc == o.ssrc; }
@@ -345,6 +348,7 @@
struct RtpEncodingParameters {
RtpEncodingParameters();
+ RtpEncodingParameters(const RtpEncodingParameters&);
~RtpEncodingParameters();
// If unset, a value is chosen by the implementation.
@@ -460,6 +464,7 @@
struct RtpCodecParameters {
RtpCodecParameters();
+ RtpCodecParameters(const RtpCodecParameters&);
~RtpCodecParameters();
// Build MIME "type/subtype" string from |name| and |kind|.
@@ -545,6 +550,7 @@
struct RtcpParameters final {
RtcpParameters();
+ RtcpParameters(const RtcpParameters&);
~RtcpParameters();
// The SSRC to be used in the "SSRC of packet sender" field. If not set, one
@@ -579,6 +585,7 @@
struct RtpParameters {
RtpParameters();
+ RtpParameters(const RtpParameters&);
~RtpParameters();
// Used when calling getParameters/setParameters with a PeerConnection
@@ -602,7 +609,9 @@
// abstraction on which RTCP parameters are set.
RtcpParameters rtcp;
- // TODO(deadbeef): Not implemented.
+ // When bandwidth is constrained and the RtpSender needs to choose between
+ // degrading resolution or degrading framerate, degradationPreference
+ // indicates which is preferred. Only for video tracks.
DegradationPreference degradation_preference =
DegradationPreference::BALANCED;
diff --git a/api/rtpreceiverinterface.cc b/api/rtpreceiverinterface.cc
index fcdca69..216ed2e 100644
--- a/api/rtpreceiverinterface.cc
+++ b/api/rtpreceiverinterface.cc
@@ -45,4 +45,12 @@
return {};
}
+void RtpReceiverInterface::SetFrameDecryptor(
+ rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) {}
+
+rtc::scoped_refptr<FrameDecryptorInterface>
+RtpReceiverInterface::GetFrameDecryptor() const {
+ return nullptr;
+}
+
} // namespace webrtc
diff --git a/api/rtpreceiverinterface.h b/api/rtpreceiverinterface.h
index b2499b4..266f6ac 100644
--- a/api/rtpreceiverinterface.h
+++ b/api/rtpreceiverinterface.h
@@ -17,6 +17,7 @@
#include <string>
#include <vector>
+#include "api/crypto/framedecryptorinterface.h"
#include "api/mediastreaminterface.h"
#include "api/mediatypes.h"
#include "api/proxy.h"
@@ -124,6 +125,17 @@
// content::FakeRtpReceiver in Chromium.
virtual std::vector<RtpSource> GetSources() const;
+ // Sets a user defined frame decryptor that will decrypt the entire frame
+ // before it is sent across the network. This will decrypt the entire frame
+ // using the user provided decryption mechanism regardless of whether SRTP is
+ // enabled or not.
+ virtual void SetFrameDecryptor(
+ rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor);
+
+ // Returns a pointer to the frame decryptor set previously by the
+ // user. This can be used to update the state of the object.
+ virtual rtc::scoped_refptr<FrameDecryptorInterface> GetFrameDecryptor() const;
+
protected:
~RtpReceiverInterface() override = default;
};
@@ -142,6 +154,11 @@
PROXY_METHOD1(bool, SetParameters, const RtpParameters&)
PROXY_METHOD1(void, SetObserver, RtpReceiverObserverInterface*);
PROXY_CONSTMETHOD0(std::vector<RtpSource>, GetSources);
+PROXY_METHOD1(void,
+ SetFrameDecryptor,
+ rtc::scoped_refptr<FrameDecryptorInterface>);
+PROXY_CONSTMETHOD0(rtc::scoped_refptr<FrameDecryptorInterface>,
+ GetFrameDecryptor);
END_PROXY_MAP()
} // namespace webrtc
diff --git a/api/rtpsenderinterface.cc b/api/rtpsenderinterface.cc
new file mode 100644
index 0000000..bbf3901
--- /dev/null
+++ b/api/rtpsenderinterface.cc
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018 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/rtpsenderinterface.h"
+
+namespace webrtc {
+
+void RtpSenderInterface::SetFrameEncryptor(
+ rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {}
+
+rtc::scoped_refptr<FrameEncryptorInterface>
+RtpSenderInterface::GetFrameEncryptor() const {
+ return nullptr;
+}
+
+} // namespace webrtc
diff --git a/api/rtpsenderinterface.h b/api/rtpsenderinterface.h
index 6003aa0..96c2669 100644
--- a/api/rtpsenderinterface.h
+++ b/api/rtpsenderinterface.h
@@ -17,6 +17,7 @@
#include <string>
#include <vector>
+#include "api/crypto/frameencryptorinterface.h"
#include "api/dtmfsenderinterface.h"
#include "api/mediastreaminterface.h"
#include "api/mediatypes.h"
@@ -63,8 +64,19 @@
// Returns null for a video sender.
virtual rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const = 0;
+ // Sets a user defined frame encryptor that will encrypt the entire frame
+ // before it is sent across the network. This will encrypt the entire frame
+ // using the user provided encryption mechanism regardless of whether SRTP is
+ // enabled or not.
+ virtual void SetFrameEncryptor(
+ rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor);
+
+ // Returns a pointer to the frame encryptor set previously by the
+ // user. This can be used to update the state of the object.
+ virtual rtc::scoped_refptr<FrameEncryptorInterface> GetFrameEncryptor() const;
+
protected:
- virtual ~RtpSenderInterface() {}
+ ~RtpSenderInterface() override = default;
};
// Define proxy for RtpSenderInterface.
@@ -81,6 +93,11 @@
PROXY_METHOD0(RtpParameters, GetParameters);
PROXY_METHOD1(RTCError, SetParameters, const RtpParameters&)
PROXY_CONSTMETHOD0(rtc::scoped_refptr<DtmfSenderInterface>, GetDtmfSender);
+PROXY_METHOD1(void,
+ SetFrameEncryptor,
+ rtc::scoped_refptr<FrameEncryptorInterface>);
+PROXY_CONSTMETHOD0(rtc::scoped_refptr<FrameEncryptorInterface>,
+ GetFrameEncryptor);
END_PROXY_MAP()
} // namespace webrtc
diff --git a/api/rtptransceiverinterface.cc b/api/rtptransceiverinterface.cc
new file mode 100644
index 0000000..065ac04
--- /dev/null
+++ b/api/rtptransceiverinterface.cc
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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/rtptransceiverinterface.h"
+
+namespace webrtc {
+
+RtpTransceiverInit::RtpTransceiverInit() = default;
+
+RtpTransceiverInit::RtpTransceiverInit(const RtpTransceiverInit& rhs) = default;
+
+RtpTransceiverInit::~RtpTransceiverInit() = default;
+
+absl::optional<RtpTransceiverDirection>
+RtpTransceiverInterface::fired_direction() const {
+ return absl::nullopt;
+}
+
+} // namespace webrtc
diff --git a/api/rtptransceiverinterface.h b/api/rtptransceiverinterface.h
index 26f1fdf..4c22957 100644
--- a/api/rtptransceiverinterface.h
+++ b/api/rtptransceiverinterface.h
@@ -34,6 +34,9 @@
// PeerConnectionInterface::AddTransceiver.
// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit
struct RtpTransceiverInit final {
+ RtpTransceiverInit();
+ RtpTransceiverInit(const RtpTransceiverInit&);
+ ~RtpTransceiverInit();
// Direction of the RtpTransceiver. See RtpTransceiverInterface::direction().
RtpTransceiverDirection direction = RtpTransceiverDirection::kSendRecv;
@@ -112,9 +115,7 @@
// OnAddTrack only get fired once even if the same session description is
// applied again.
// Exposed in the public interface for use by Chromium.
- virtual absl::optional<RtpTransceiverDirection> fired_direction() const {
- return absl::nullopt;
- }
+ virtual absl::optional<RtpTransceiverDirection> fired_direction() const;
// The Stop method irreversibly stops the RtpTransceiver. The sender of this
// transceiver will no longer send, the receiver will no longer receive.
@@ -129,7 +130,7 @@
rtc::ArrayView<RtpCodecCapability> codecs) = 0;
protected:
- virtual ~RtpTransceiverInterface() = default;
+ ~RtpTransceiverInterface() override = default;
};
} // namespace webrtc
diff --git a/api/statstypes.cc b/api/statstypes.cc
index ceba28d..ad68894 100644
--- a/api/statstypes.cc
+++ b/api/statstypes.cc
@@ -99,7 +99,7 @@
std::string ToString() const override {
return std::string(InternalTypeToString(type_)) + kSeparator +
- rtc::ToString<int>(id_);
+ rtc::ToString(id_);
}
protected:
@@ -165,7 +165,7 @@
std::string ret(prefix);
ret += content_name_;
ret += '-';
- ret += rtc::ToString<>(component_);
+ ret += rtc::ToString(component_);
return ret;
}
@@ -190,7 +190,7 @@
std::string ToString() const override {
std::string ret(ComponentId::ToString("Conn-"));
ret += '-';
- ret += rtc::ToString<>(index_);
+ ret += rtc::ToString(index_);
return ret;
}
diff --git a/api/transport/network_types.h b/api/transport/network_types.h
index a389716..8e9526b 100644
--- a/api/transport/network_types.h
+++ b/api/transport/network_types.h
@@ -45,6 +45,7 @@
Timestamp at_time = Timestamp::Infinity();
absl::optional<DataRate> min_data_rate;
absl::optional<DataRate> max_data_rate;
+ absl::optional<DataRate> starting_rate;
};
// Send side information
@@ -62,7 +63,6 @@
// The TargetRateConstraints are set here so they can be changed synchronously
// when network route changes.
TargetRateConstraints constraints;
- absl::optional<DataRate> starting_rate;
};
struct PacedPacketInfo {
diff --git a/api/umametrics.h b/api/umametrics.h
index b999b64..88ab08c 100644
--- a/api/umametrics.h
+++ b/api/umametrics.h
@@ -17,38 +17,6 @@
namespace webrtc {
-// Used to specify which enum counter type we're incrementing in
-// MetricsObserverInterface::IncrementEnumCounter.
-enum PeerConnectionEnumCounterType {
- kEnumCounterAddressFamily,
- // For the next 2 counters, we track them separately based on the "first hop"
- // protocol used by the local candidate. "First hop" means the local candidate
- // type in the case of non-TURN candidates, and the protocol used to connect
- // to the TURN server in the case of TURN candidates.
- kEnumCounterIceCandidatePairTypeUdp,
- kEnumCounterIceCandidatePairTypeTcp,
-
- kEnumCounterAudioSrtpCipher,
- kEnumCounterAudioSslCipher,
- kEnumCounterVideoSrtpCipher,
- kEnumCounterVideoSslCipher,
- kEnumCounterDataSrtpCipher,
- kEnumCounterDataSslCipher,
- kEnumCounterDtlsHandshakeError,
- kEnumCounterIceRegathering,
- kEnumCounterIceRestart,
- kEnumCounterKeyProtocol,
- kEnumCounterSdpSemanticRequested,
- kEnumCounterSdpSemanticNegotiated,
- kEnumCounterKeyProtocolMediaType,
- kEnumCounterSdpFormatReceived,
- // The next 2 counters log the value of srtp_err_status_t defined in libsrtp.
- kEnumCounterSrtpUnprotectError,
- kEnumCounterSrtcpUnprotectError,
- kEnumCounterUsagePattern,
- kPeerConnectionEnumCounterMax
-};
-
// Currently this contains information related to WebRTC network/transport
// information.
@@ -169,27 +137,19 @@
kSdpFormatReceivedMax
};
-class MetricsObserverInterface : public rtc::RefCountInterface {
- public:
- // |type| is the type of the enum counter to be incremented. |counter|
- // is the particular counter in that type. |counter_max| is the next sequence
- // number after the highest counter.
- virtual void IncrementEnumCounter(PeerConnectionEnumCounterType type,
- int counter,
- int counter_max) = 0;
-
- // This is used to handle sparse counters like SSL cipher suites.
- // TODO(guoweis): Remove the implementation once the dependency's interface
- // definition is updated.
- virtual void IncrementSparseEnumCounter(PeerConnectionEnumCounterType type,
- int counter) = 0;
-
- virtual void AddHistogramSample(PeerConnectionMetricsName type,
- int value) = 0;
+// Metric for counting the outcome of adding an ICE candidate
+enum AddIceCandidateResult {
+ kAddIceCandidateSuccess,
+ kAddIceCandidateFailClosed,
+ kAddIceCandidateFailNoRemoteDescription,
+ kAddIceCandidateFailNullCandidate,
+ kAddIceCandidateFailNotValid,
+ kAddIceCandidateFailNotReady,
+ kAddIceCandidateFailInAddition,
+ kAddIceCandidateFailNotUsable,
+ kAddIceCandidateMax
};
-typedef MetricsObserverInterface UMAObserver;
-
} // namespace webrtc
#endif // API_UMAMETRICS_H_
diff --git a/api/units/data_rate.cc b/api/units/data_rate.cc
index 4e31d51..9170627 100644
--- a/api/units/data_rate.cc
+++ b/api/units/data_rate.cc
@@ -20,7 +20,11 @@
if (value.IsInfinite()) {
sb << "inf bps";
} else {
- sb << value.bps() << " bps";
+ if (value.bps() == 0 || value.bps() % 1000 != 0) {
+ sb << value.bps() << " bps";
+ } else {
+ sb << value.kbps() << " kbps";
+ }
}
return sb.str();
}
diff --git a/api/units/data_rate.h b/api/units/data_rate.h
index c7164e3..5c421d4 100644
--- a/api/units/data_rate.h
+++ b/api/units/data_rate.h
@@ -10,6 +10,11 @@
#ifndef API_UNITS_DATA_RATE_H_
#define API_UNITS_DATA_RATE_H_
+
+#ifdef UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // UNIT_TEST
+
#include <stdint.h>
#include <cmath>
#include <limits>
@@ -40,10 +45,22 @@
class DataRate {
public:
DataRate() = delete;
- static DataRate Zero() { return DataRate(0); }
- static DataRate Infinity() {
+ static constexpr DataRate Zero() { return DataRate(0); }
+ static constexpr DataRate Infinity() {
return DataRate(data_rate_impl::kPlusInfinityVal);
}
+ template <int64_t bps>
+ static constexpr DataRate BitsPerSec() {
+ static_assert(bps >= 0, "");
+ static_assert(bps < data_rate_impl::kPlusInfinityVal, "");
+ return DataRate(bps);
+ }
+ template <int64_t kbps>
+ static constexpr DataRate KilobitsPerSec() {
+ static_assert(kbps >= 0, "");
+ static_assert(kbps < data_rate_impl::kPlusInfinityVal / 1000, "");
+ return DataRate(kbps * 1000);
+ }
template <
typename T,
@@ -89,56 +106,64 @@
}
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type kbps() const {
- return rtc::dchecked_cast<T>((bps() + 500) / 1000);
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(UnsafeKilobitsPerSec());
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type bps()
- const {
- if (IsInfinite()) {
- return std::numeric_limits<T>::infinity();
- } else {
- return bits_per_sec_;
- }
+ typename std::enable_if<std::is_floating_point<T>::value,
+ T>::type constexpr bps() const {
+ return IsInfinite() ? std::numeric_limits<T>::infinity() : bits_per_sec_;
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type kbps()
- const {
+ typename std::enable_if<std::is_floating_point<T>::value,
+ T>::type constexpr kbps() const {
return bps<T>() * 1e-3;
}
- bool IsZero() const { return bits_per_sec_ == 0; }
- bool IsInfinite() const {
+ constexpr int64_t bps_or(int64_t fallback_value) const {
+ return IsFinite() ? bits_per_sec_ : fallback_value;
+ }
+ constexpr int64_t kbps_or(int64_t fallback_value) const {
+ return IsFinite() ? UnsafeKilobitsPerSec() : fallback_value;
+ }
+
+ constexpr bool IsZero() const { return bits_per_sec_ == 0; }
+ constexpr bool IsInfinite() const {
return bits_per_sec_ == data_rate_impl::kPlusInfinityVal;
}
- bool IsFinite() const { return !IsInfinite(); }
+ constexpr bool IsFinite() const { return !IsInfinite(); }
- double operator/(const DataRate& other) const {
+ constexpr double operator/(const DataRate& other) const {
return bps<double>() / other.bps<double>();
}
- bool operator==(const DataRate& other) const {
+ constexpr bool operator==(const DataRate& other) const {
return bits_per_sec_ == other.bits_per_sec_;
}
- bool operator!=(const DataRate& other) const {
+ constexpr bool operator!=(const DataRate& other) const {
return bits_per_sec_ != other.bits_per_sec_;
}
- bool operator<=(const DataRate& other) const {
+ constexpr bool operator<=(const DataRate& other) const {
return bits_per_sec_ <= other.bits_per_sec_;
}
- bool operator>=(const DataRate& other) const {
+ constexpr bool operator>=(const DataRate& other) const {
return bits_per_sec_ >= other.bits_per_sec_;
}
- bool operator>(const DataRate& other) const {
+ constexpr bool operator>(const DataRate& other) const {
return bits_per_sec_ > other.bits_per_sec_;
}
- bool operator<(const DataRate& other) const {
+ constexpr bool operator<(const DataRate& other) const {
return bits_per_sec_ < other.bits_per_sec_;
}
private:
// Bits per second used internally to simplify debugging by making the value
// more recognizable.
- explicit DataRate(int64_t bits_per_second) : bits_per_sec_(bits_per_second) {}
+ explicit constexpr DataRate(int64_t bits_per_second)
+ : bits_per_sec_(bits_per_second) {}
+ constexpr int64_t UnsafeKilobitsPerSec() const {
+ return (bits_per_sec_ + 500) / 1000;
+ }
int64_t bits_per_sec_;
};
@@ -177,6 +202,14 @@
std::string ToString(const DataRate& value);
+#ifdef UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ DataRate value) {
+ return stream << ToString(value);
+}
+#endif // UNIT_TEST
+
} // namespace webrtc
#endif // API_UNITS_DATA_RATE_H_
diff --git a/api/units/data_rate_unittest.cc b/api/units/data_rate_unittest.cc
index 073e80e..9c91fd6 100644
--- a/api/units/data_rate_unittest.cc
+++ b/api/units/data_rate_unittest.cc
@@ -13,6 +13,23 @@
namespace webrtc {
namespace test {
+
+TEST(DataRateTest, ConstExpr) {
+ constexpr int64_t kValue = 12345;
+ constexpr DataRate kDataRateZero = DataRate::Zero();
+ constexpr DataRate kDataRateInf = DataRate::Infinity();
+ static_assert(kDataRateZero.IsZero(), "");
+ static_assert(kDataRateInf.IsInfinite(), "");
+ static_assert(kDataRateInf.bps_or(-1) == -1, "");
+ static_assert(kDataRateInf > kDataRateZero, "");
+
+ constexpr DataRate kDataRateBps = DataRate::BitsPerSec<kValue>();
+ constexpr DataRate kDataRateKbps = DataRate::KilobitsPerSec<kValue>();
+ static_assert(kDataRateBps.bps<double>() == kValue, "");
+ static_assert(kDataRateBps.bps_or(0) == kValue, "");
+ static_assert(kDataRateKbps.kbps_or(0) == kValue, "");
+}
+
TEST(DataRateTest, GetBackSameValues) {
const int64_t kValue = 123 * 8;
EXPECT_EQ(DataRate::bps(kValue).bps(), kValue);
diff --git a/api/units/data_size.h b/api/units/data_size.h
index 8c35766..ac61a6f 100644
--- a/api/units/data_size.h
+++ b/api/units/data_size.h
@@ -11,6 +11,10 @@
#ifndef API_UNITS_DATA_SIZE_H_
#define API_UNITS_DATA_SIZE_H_
+#ifdef UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // UNIT_TEST
+
#include <stdint.h>
#include <cmath>
#include <limits>
@@ -29,10 +33,16 @@
class DataSize {
public:
DataSize() = delete;
- static DataSize Zero() { return DataSize(0); }
- static DataSize Infinity() {
+ static constexpr DataSize Zero() { return DataSize(0); }
+ static constexpr DataSize Infinity() {
return DataSize(data_size_impl::kPlusInfinityVal);
}
+ template <int64_t bytes>
+ static constexpr DataSize Bytes() {
+ static_assert(bytes >= 0, "");
+ static_assert(bytes < data_size_impl::kPlusInfinityVal, "");
+ return DataSize(bytes);
+ }
template <
typename T,
@@ -64,18 +74,20 @@
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type bytes()
- const {
- if (IsInfinite()) {
- return std::numeric_limits<T>::infinity();
- } else {
- return bytes_;
- }
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ bytes() const {
+ return IsInfinite() ? std::numeric_limits<T>::infinity() : bytes_;
}
- bool IsZero() const { return bytes_ == 0; }
- bool IsInfinite() const { return bytes_ == data_size_impl::kPlusInfinityVal; }
- bool IsFinite() const { return !IsInfinite(); }
+ constexpr int64_t bytes_or(int64_t fallback_value) const {
+ return IsFinite() ? bytes_ : fallback_value;
+ }
+
+ constexpr bool IsZero() const { return bytes_ == 0; }
+ constexpr bool IsInfinite() const {
+ return bytes_ == data_size_impl::kPlusInfinityVal;
+ }
+ constexpr bool IsFinite() const { return !IsInfinite(); }
DataSize operator-(const DataSize& other) const {
return DataSize::bytes(bytes() - other.bytes());
}
@@ -90,26 +102,30 @@
bytes_ += other.bytes();
return *this;
}
- double operator/(const DataSize& other) const {
+ constexpr double operator/(const DataSize& other) const {
return bytes<double>() / other.bytes<double>();
}
- bool operator==(const DataSize& other) const {
+ constexpr bool operator==(const DataSize& other) const {
return bytes_ == other.bytes_;
}
- bool operator!=(const DataSize& other) const {
+ constexpr bool operator!=(const DataSize& other) const {
return bytes_ != other.bytes_;
}
- bool operator<=(const DataSize& other) const {
+ constexpr bool operator<=(const DataSize& other) const {
return bytes_ <= other.bytes_;
}
- bool operator>=(const DataSize& other) const {
+ constexpr bool operator>=(const DataSize& other) const {
return bytes_ >= other.bytes_;
}
- bool operator>(const DataSize& other) const { return bytes_ > other.bytes_; }
- bool operator<(const DataSize& other) const { return bytes_ < other.bytes_; }
+ constexpr bool operator>(const DataSize& other) const {
+ return bytes_ > other.bytes_;
+ }
+ constexpr bool operator<(const DataSize& other) const {
+ return bytes_ < other.bytes_;
+ }
private:
- explicit DataSize(int64_t bytes) : bytes_(bytes) {}
+ explicit constexpr DataSize(int64_t bytes) : bytes_(bytes) {}
int64_t bytes_;
};
@@ -137,6 +153,14 @@
std::string ToString(const DataSize& value);
+#ifdef UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ DataSize value) {
+ return stream << ToString(value);
+}
+#endif // UNIT_TEST
+
} // namespace webrtc
#endif // API_UNITS_DATA_SIZE_H_
diff --git a/api/units/data_size_unittest.cc b/api/units/data_size_unittest.cc
index 7747258..fe7f591 100644
--- a/api/units/data_size_unittest.cc
+++ b/api/units/data_size_unittest.cc
@@ -14,6 +14,21 @@
namespace webrtc {
namespace test {
+TEST(DataSizeTest, ConstExpr) {
+ constexpr int64_t kValue = 12345;
+ constexpr DataSize kDataSizeZero = DataSize::Zero();
+ constexpr DataSize kDataSizeInf = DataSize::Infinity();
+ static_assert(kDataSizeZero.IsZero(), "");
+ static_assert(kDataSizeInf.IsInfinite(), "");
+ static_assert(kDataSizeInf.bytes_or(-1) == -1, "");
+ static_assert(kDataSizeInf > kDataSizeZero, "");
+
+ constexpr DataSize kDataSize = DataSize::Bytes<kValue>();
+ static_assert(kDataSize.bytes_or(-1) == kValue, "");
+
+ EXPECT_EQ(kDataSize.bytes(), kValue);
+}
+
TEST(DataSizeTest, GetBackSameValues) {
const int64_t kValue = 123 * 8;
EXPECT_EQ(DataSize::bytes(kValue).bytes(), kValue);
diff --git a/api/units/time_delta.cc b/api/units/time_delta.cc
index 398df77..d38387a 100644
--- a/api/units/time_delta.cc
+++ b/api/units/time_delta.cc
@@ -22,7 +22,12 @@
} else if (value.IsMinusInfinity()) {
sb << "-inf ms";
} else {
- sb << value.ms() << " ms";
+ if (value.us() == 0 || (value.us() % 1000) != 0)
+ sb << value.us() << " us";
+ else if (value.ms() % 1000 != 0)
+ sb << value.ms() << " ms";
+ else
+ sb << value.seconds() << " s";
}
return sb.str();
}
diff --git a/api/units/time_delta.h b/api/units/time_delta.h
index 0f99e80..b820472 100644
--- a/api/units/time_delta.h
+++ b/api/units/time_delta.h
@@ -11,6 +11,10 @@
#ifndef API_UNITS_TIME_DELTA_H_
#define API_UNITS_TIME_DELTA_H_
+#ifdef UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // UNIT_TEST
+
#include <stdint.h>
#include <cmath>
#include <limits>
@@ -35,13 +39,31 @@
class TimeDelta {
public:
TimeDelta() = delete;
- static TimeDelta Zero() { return TimeDelta(0); }
- static TimeDelta PlusInfinity() {
+ static constexpr TimeDelta Zero() { return TimeDelta(0); }
+ static constexpr TimeDelta PlusInfinity() {
return TimeDelta(timedelta_impl::kPlusInfinityVal);
}
- static TimeDelta MinusInfinity() {
+ static constexpr TimeDelta MinusInfinity() {
return TimeDelta(timedelta_impl::kMinusInfinityVal);
}
+ template <int64_t seconds>
+ static constexpr TimeDelta Seconds() {
+ static_assert(seconds > timedelta_impl::kMinusInfinityVal / 1000000, "");
+ static_assert(seconds < timedelta_impl::kPlusInfinityVal / 1000000, "");
+ return TimeDelta(seconds * 1000000);
+ }
+ template <int64_t ms>
+ static constexpr TimeDelta Millis() {
+ static_assert(ms > timedelta_impl::kMinusInfinityVal / 1000, "");
+ static_assert(ms < timedelta_impl::kPlusInfinityVal / 1000, "");
+ return TimeDelta(ms * 1000);
+ }
+ template <int64_t us>
+ static constexpr TimeDelta Micros() {
+ static_assert(us > timedelta_impl::kMinusInfinityVal, "");
+ static_assert(us < timedelta_impl::kPlusInfinityVal, "");
+ return TimeDelta(us);
+ }
template <
typename T,
@@ -98,12 +120,13 @@
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type seconds() const {
- return rtc::dchecked_cast<T>((us() + (us() >= 0 ? 500000 : -500000)) /
- 1000000);
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(UnsafeSeconds());
}
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type ms() const {
- return rtc::dchecked_cast<T>((us() + (us() >= 0 ? 500 : -500)) / 1000);
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(UnsafeMillis());
}
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type us() const {
@@ -118,43 +141,50 @@
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type seconds()
- const {
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ seconds() const {
return us<T>() * 1e-6;
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type ms()
- const {
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ ms() const {
return us<T>() * 1e-3;
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type us()
- const {
- if (IsPlusInfinity()) {
- return std::numeric_limits<T>::infinity();
- } else if (IsMinusInfinity()) {
- return -std::numeric_limits<T>::infinity();
- } else {
- return microseconds_;
- }
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ us() const {
+ return IsPlusInfinity()
+ ? std::numeric_limits<T>::infinity()
+ : IsMinusInfinity() ? -std::numeric_limits<T>::infinity()
+ : microseconds_;
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type ns()
- const {
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ ns() const {
return us<T>() * 1e3;
}
+ constexpr int64_t seconds_or(int64_t fallback_value) const {
+ return IsFinite() ? UnsafeSeconds() : fallback_value;
+ }
+ constexpr int64_t ms_or(int64_t fallback_value) const {
+ return IsFinite() ? UnsafeMillis() : fallback_value;
+ }
+ constexpr int64_t us_or(int64_t fallback_value) const {
+ return IsFinite() ? microseconds_ : fallback_value;
+ }
+
TimeDelta Abs() const { return TimeDelta::us(std::abs(us())); }
- bool IsZero() const { return microseconds_ == 0; }
- bool IsFinite() const { return !IsInfinite(); }
- bool IsInfinite() const {
+ constexpr bool IsZero() const { return microseconds_ == 0; }
+ constexpr bool IsFinite() const { return !IsInfinite(); }
+ constexpr bool IsInfinite() const {
return microseconds_ == timedelta_impl::kPlusInfinityVal ||
microseconds_ == timedelta_impl::kMinusInfinityVal;
}
- bool IsPlusInfinity() const {
+ constexpr bool IsPlusInfinity() const {
return microseconds_ == timedelta_impl::kPlusInfinityVal;
}
- bool IsMinusInfinity() const {
+ constexpr bool IsMinusInfinity() const {
return microseconds_ == timedelta_impl::kMinusInfinityVal;
}
TimeDelta operator+(const TimeDelta& other) const {
@@ -171,30 +201,36 @@
microseconds_ += other.us();
return *this;
}
- double operator/(const TimeDelta& other) const {
+ constexpr double operator/(const TimeDelta& other) const {
return us<double>() / other.us<double>();
}
- bool operator==(const TimeDelta& other) const {
+ constexpr bool operator==(const TimeDelta& other) const {
return microseconds_ == other.microseconds_;
}
- bool operator!=(const TimeDelta& other) const {
+ constexpr bool operator!=(const TimeDelta& other) const {
return microseconds_ != other.microseconds_;
}
- bool operator<=(const TimeDelta& other) const {
+ constexpr bool operator<=(const TimeDelta& other) const {
return microseconds_ <= other.microseconds_;
}
- bool operator>=(const TimeDelta& other) const {
+ constexpr bool operator>=(const TimeDelta& other) const {
return microseconds_ >= other.microseconds_;
}
- bool operator>(const TimeDelta& other) const {
+ constexpr bool operator>(const TimeDelta& other) const {
return microseconds_ > other.microseconds_;
}
- bool operator<(const TimeDelta& other) const {
+ constexpr bool operator<(const TimeDelta& other) const {
return microseconds_ < other.microseconds_;
}
private:
- explicit TimeDelta(int64_t us) : microseconds_(us) {}
+ explicit constexpr TimeDelta(int64_t us) : microseconds_(us) {}
+ constexpr int64_t UnsafeSeconds() const {
+ return (microseconds_ + (microseconds_ >= 0 ? 500000 : -500000)) / 1000000;
+ }
+ constexpr int64_t UnsafeMillis() const {
+ return (microseconds_ + (microseconds_ >= 0 ? 500 : -500)) / 1000;
+ }
int64_t microseconds_;
};
@@ -220,8 +256,16 @@
inline TimeDelta operator/(const TimeDelta& delta, const int64_t& scalar) {
return TimeDelta::us(delta.us() / scalar);
}
-
std::string ToString(const TimeDelta& value);
+
+#ifdef UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ TimeDelta value) {
+ return stream << ToString(value);
+}
+#endif // UNIT_TEST
+
} // namespace webrtc
#endif // API_UNITS_TIME_DELTA_H_
diff --git a/api/units/time_delta_unittest.cc b/api/units/time_delta_unittest.cc
index 94a27f2..9eddee7 100644
--- a/api/units/time_delta_unittest.cc
+++ b/api/units/time_delta_unittest.cc
@@ -14,6 +14,26 @@
namespace webrtc {
namespace test {
+TEST(TimeDeltaTest, ConstExpr) {
+ constexpr int64_t kValue = -12345;
+ constexpr TimeDelta kTimeDeltaZero = TimeDelta::Zero();
+ constexpr TimeDelta kTimeDeltaPlusInf = TimeDelta::PlusInfinity();
+ constexpr TimeDelta kTimeDeltaMinusInf = TimeDelta::MinusInfinity();
+ static_assert(kTimeDeltaZero.IsZero(), "");
+ static_assert(kTimeDeltaPlusInf.IsPlusInfinity(), "");
+ static_assert(kTimeDeltaMinusInf.IsMinusInfinity(), "");
+ static_assert(kTimeDeltaPlusInf.ms_or(-1) == -1, "");
+
+ static_assert(kTimeDeltaPlusInf > kTimeDeltaZero, "");
+
+ constexpr TimeDelta kTimeDeltaSeconds = TimeDelta::Seconds<kValue>();
+ constexpr TimeDelta kTimeDeltaMs = TimeDelta::Millis<kValue>();
+ constexpr TimeDelta kTimeDeltaUs = TimeDelta::Micros<kValue>();
+
+ static_assert(kTimeDeltaSeconds.seconds_or(0) == kValue, "");
+ static_assert(kTimeDeltaMs.ms_or(0) == kValue, "");
+ static_assert(kTimeDeltaUs.us_or(0) == kValue, "");
+}
TEST(TimeDeltaTest, GetBackSameValues) {
const int64_t kValue = 499;
diff --git a/api/units/timestamp.cc b/api/units/timestamp.cc
index 4b2c44b..feb1447 100644
--- a/api/units/timestamp.cc
+++ b/api/units/timestamp.cc
@@ -19,7 +19,10 @@
if (value.IsInfinite()) {
sb << "inf ms";
} else {
- sb << value.ms() << " ms";
+ if (value.ms() % 1000 == 0)
+ sb << value.seconds() << " s";
+ else
+ sb << value.ms() << " ms";
}
return sb.str();
}
diff --git a/api/units/timestamp.h b/api/units/timestamp.h
index a66e061..6e5e392 100644
--- a/api/units/timestamp.h
+++ b/api/units/timestamp.h
@@ -11,6 +11,10 @@
#ifndef API_UNITS_TIMESTAMP_H_
#define API_UNITS_TIMESTAMP_H_
+#ifdef UNIT_TEST
+#include <ostream> // no-presubmit-check TODO(webrtc:8982)
+#endif // UNIT_TEST
+
#include <stdint.h>
#include <limits>
#include <string>
@@ -32,9 +36,27 @@
class Timestamp {
public:
Timestamp() = delete;
- static Timestamp Infinity() {
+ static constexpr Timestamp Infinity() {
return Timestamp(timestamp_impl::kPlusInfinityVal);
}
+ template <int64_t seconds>
+ static constexpr Timestamp Seconds() {
+ static_assert(seconds >= 0, "");
+ static_assert(seconds < timestamp_impl::kPlusInfinityVal / 1000000, "");
+ return Timestamp(seconds * 1000000);
+ }
+ template <int64_t ms>
+ static constexpr Timestamp Millis() {
+ static_assert(ms >= 0, "");
+ static_assert(ms < timestamp_impl::kPlusInfinityVal / 1000, "");
+ return Timestamp(ms * 1000);
+ }
+ template <int64_t us>
+ static constexpr Timestamp Micros() {
+ static_assert(us >= 0, "");
+ static_assert(us < timestamp_impl::kPlusInfinityVal, "");
+ return Timestamp(us);
+ }
template <
typename T,
@@ -92,11 +114,13 @@
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type seconds() const {
- return rtc::dchecked_cast<T>((us() + 500000) / 1000000);
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(UnsafeSeconds());
}
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type ms() const {
- return rtc::dchecked_cast<T>((us() + 500) / 1000);
+ RTC_DCHECK(IsFinite());
+ return rtc::dchecked_cast<T>(UnsafeMillis());
}
template <typename T = int64_t>
typename std::enable_if<std::is_integral<T>::value, T>::type us() const {
@@ -105,29 +129,35 @@
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type seconds()
- const {
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ seconds() const {
return us<T>() * 1e-6;
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type ms()
- const {
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ ms() const {
return us<T>() * 1e-3;
}
template <typename T>
- typename std::enable_if<std::is_floating_point<T>::value, T>::type us()
- const {
- if (IsInfinite()) {
- return std::numeric_limits<T>::infinity();
- } else {
- return microseconds_;
- }
+ constexpr typename std::enable_if<std::is_floating_point<T>::value, T>::type
+ us() const {
+ return IsInfinite() ? std::numeric_limits<T>::infinity() : microseconds_;
}
- bool IsInfinite() const {
+ constexpr int64_t seconds_or(int64_t fallback_value) const {
+ return IsFinite() ? UnsafeSeconds() : fallback_value;
+ }
+ constexpr int64_t ms_or(int64_t fallback_value) const {
+ return IsFinite() ? UnsafeMillis() : fallback_value;
+ }
+ constexpr int64_t us_or(int64_t fallback_value) const {
+ return IsFinite() ? microseconds_ : fallback_value;
+ }
+
+ constexpr bool IsInfinite() const {
return microseconds_ == timestamp_impl::kPlusInfinityVal;
}
- bool IsFinite() const { return !IsInfinite(); }
+ constexpr bool IsFinite() const { return !IsInfinite(); }
TimeDelta operator-(const Timestamp& other) const {
return TimeDelta::us(us() - other.us());
}
@@ -145,32 +175,46 @@
microseconds_ += other.us();
return *this;
}
- bool operator==(const Timestamp& other) const {
+ constexpr bool operator==(const Timestamp& other) const {
return microseconds_ == other.microseconds_;
}
- bool operator!=(const Timestamp& other) const {
+ constexpr bool operator!=(const Timestamp& other) const {
return microseconds_ != other.microseconds_;
}
- bool operator<=(const Timestamp& other) const {
+ constexpr bool operator<=(const Timestamp& other) const {
return microseconds_ <= other.microseconds_;
}
- bool operator>=(const Timestamp& other) const {
+ constexpr bool operator>=(const Timestamp& other) const {
return microseconds_ >= other.microseconds_;
}
- bool operator>(const Timestamp& other) const {
+ constexpr bool operator>(const Timestamp& other) const {
return microseconds_ > other.microseconds_;
}
- bool operator<(const Timestamp& other) const {
+ constexpr bool operator<(const Timestamp& other) const {
return microseconds_ < other.microseconds_;
}
private:
- explicit Timestamp(int64_t us) : microseconds_(us) {}
+ explicit constexpr Timestamp(int64_t us) : microseconds_(us) {}
+ constexpr int64_t UnsafeSeconds() const {
+ return (microseconds_ + 500000) / 1000000;
+ }
+ constexpr int64_t UnsafeMillis() const {
+ return (microseconds_ + 500) / 1000;
+ }
int64_t microseconds_;
};
std::string ToString(const Timestamp& value);
+#ifdef UNIT_TEST
+inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
+ std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
+ Timestamp value) {
+ return stream << ToString(value);
+}
+#endif // UNIT_TEST
+
} // namespace webrtc
#endif // API_UNITS_TIMESTAMP_H_
diff --git a/api/units/timestamp_unittest.cc b/api/units/timestamp_unittest.cc
index eecfe02..db894cc 100644
--- a/api/units/timestamp_unittest.cc
+++ b/api/units/timestamp_unittest.cc
@@ -13,6 +13,27 @@
namespace webrtc {
namespace test {
+TEST(TimestampTest, ConstExpr) {
+ constexpr int64_t kValue = 12345;
+ constexpr Timestamp kTimestampInf = Timestamp::Infinity();
+ static_assert(kTimestampInf.IsInfinite(), "");
+ static_assert(kTimestampInf.ms_or(-1) == -1, "");
+
+ constexpr Timestamp kTimestampSeconds = Timestamp::Seconds<kValue>();
+ constexpr Timestamp kTimestampMs = Timestamp::Millis<kValue>();
+ constexpr Timestamp kTimestampUs = Timestamp::Micros<kValue>();
+
+ static_assert(kTimestampSeconds.seconds_or(0) == kValue, "");
+ static_assert(kTimestampMs.ms_or(0) == kValue, "");
+ static_assert(kTimestampUs.us_or(0) == kValue, "");
+
+ static_assert(kTimestampMs > kTimestampUs, "");
+
+ EXPECT_EQ(kTimestampSeconds.seconds(), kValue);
+ EXPECT_EQ(kTimestampMs.ms(), kValue);
+ EXPECT_EQ(kTimestampUs.us(), kValue);
+}
+
TEST(TimestampTest, GetBackSameValues) {
const int64_t kValue = 499;
EXPECT_EQ(Timestamp::ms(kValue).ms(), kValue);
diff --git a/api/video/color_space.h b/api/video/color_space.h
index 736a170..8102647 100644
--- a/api/video/color_space.h
+++ b/api/video/color_space.h
@@ -30,27 +30,50 @@
enum class PrimaryID {
kInvalid,
kBT709,
+ kBT470M,
+ kBT470BG,
kSMPTE170M, // Identical to BT601
kSMPTE240M,
+ kFILM,
kBT2020,
+ kSMPTEST428,
+ kSMPTEST431,
+ kSMPTEST432,
+ kJEDECP22,
};
enum class TransferID {
kInvalid,
kBT709,
+ kGAMMA22,
+ kGAMMA28,
kSMPTE170M,
kSMPTE240M,
- kBT2020,
- kBT2020_10,
+ kLINEAR,
+ kLOG,
+ kLOG_SQRT,
+ kIEC61966_2_4,
+ kBT1361_ECG,
kIEC61966_2_1,
+ kBT2020_10,
+ kBT2020_12,
+ kSMPTEST2084,
+ kSMPTEST428,
+ kARIB_STD_B67,
};
enum class MatrixID {
kInvalid,
+ kRGB,
kBT709,
+ kFCC,
+ kBT470BG,
kSMPTE170M,
kSMPTE240M,
+ kYCOCG,
kBT2020_NCL,
+ kBT2020_CL,
+ kSMPTE2085,
};
enum class RangeID {
diff --git a/api/video/encoded_frame.cc b/api/video/encoded_frame.cc
index f9152b2..26a794e 100644
--- a/api/video/encoded_frame.cc
+++ b/api/video/encoded_frame.cc
@@ -17,13 +17,5 @@
return 0;
}
-uint32_t EncodedFrame::Timestamp() const {
- return timestamp;
-}
-
-void EncodedFrame::SetTimestamp(uint32_t rtp_timestamp) {
- timestamp = rtp_timestamp;
-}
-
} // namespace video_coding
} // namespace webrtc
diff --git a/api/video/encoded_frame.h b/api/video/encoded_frame.h
index 1b0a26a..b8462c6 100644
--- a/api/video/encoded_frame.h
+++ b/api/video/encoded_frame.h
@@ -58,10 +58,6 @@
virtual bool GetBitstream(uint8_t* destination) const = 0;
- // The capture timestamp of this frame, using the 90 kHz RTP clock.
- virtual uint32_t Timestamp() const;
- virtual void SetTimestamp(uint32_t rtp_timestamp);
-
// When this frame was received.
virtual int64_t ReceivedTime() const = 0;
@@ -78,7 +74,6 @@
bool is_keyframe() const { return num_references == 0; }
VideoLayerFrameId id;
- uint32_t timestamp = 0;
// TODO(philipel): Add simple modify/access functions to prevent adding too
// many |references|.
diff --git a/api/video/video_bitrate_allocation.h b/api/video/video_bitrate_allocation.h
index ce61734..9e2501d 100644
--- a/api/video/video_bitrate_allocation.h
+++ b/api/video/video_bitrate_allocation.h
@@ -16,7 +16,6 @@
#include <vector>
#include "absl/types/optional.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/api/video/video_bitrate_allocator.h b/api/video/video_bitrate_allocator.h
new file mode 100644
index 0000000..f85c633
--- /dev/null
+++ b/api/video/video_bitrate_allocator.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 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_VIDEO_VIDEO_BITRATE_ALLOCATOR_H_
+#define API_VIDEO_VIDEO_BITRATE_ALLOCATOR_H_
+
+#include "api/video/video_bitrate_allocation.h"
+
+namespace webrtc {
+
+class VideoBitrateAllocator {
+ public:
+ VideoBitrateAllocator() {}
+ virtual ~VideoBitrateAllocator() {}
+
+ virtual VideoBitrateAllocation GetAllocation(uint32_t total_bitrate_bps,
+ uint32_t framerate) = 0;
+};
+
+class VideoBitrateAllocationObserver {
+ public:
+ VideoBitrateAllocationObserver() {}
+ virtual ~VideoBitrateAllocationObserver() {}
+
+ virtual void OnBitrateAllocationUpdated(
+ const VideoBitrateAllocation& allocation) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_BITRATE_ALLOCATOR_H_
diff --git a/api/video/video_bitrate_allocator_factory.h b/api/video/video_bitrate_allocator_factory.h
new file mode 100644
index 0000000..897c34f
--- /dev/null
+++ b/api/video/video_bitrate_allocator_factory.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018 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_VIDEO_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+#define API_VIDEO_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
+
+#include <memory>
+#include "api/video/video_bitrate_allocator.h"
+#include "api/video_codecs/video_codec.h"
+
+namespace webrtc {
+
+// A factory that creates VideoBitrateAllocator.
+// NOTE: This class is still under development and may change without notice.
+class VideoBitrateAllocatorFactory {
+ public:
+ virtual ~VideoBitrateAllocatorFactory() = default;
+ // Creates a VideoBitrateAllocator for a specific video codec.
+ virtual std::unique_ptr<VideoBitrateAllocator> CreateVideoBitrateAllocator(
+ const VideoCodec& codec) = 0;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_BITRATE_ALLOCATOR_FACTORY_H_
diff --git a/api/video/video_stream_encoder_create.cc b/api/video/video_stream_encoder_create.cc
new file mode 100644
index 0000000..3147d34
--- /dev/null
+++ b/api/video/video_stream_encoder_create.cc
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018 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/video/video_stream_encoder_create.h"
+
+#include "absl/memory/memory.h"
+#include "video/video_stream_encoder.h"
+
+namespace webrtc {
+std::unique_ptr<VideoStreamEncoderInterface> CreateVideoStreamEncoder(
+ uint32_t number_of_cores,
+ VideoStreamEncoderObserver* encoder_stats_observer,
+ const VideoStreamEncoderSettings& settings,
+ // Deprecated, used for tests only.
+ rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback) {
+ return absl::make_unique<VideoStreamEncoder>(
+ number_of_cores, encoder_stats_observer, settings, pre_encode_callback,
+ absl::make_unique<OveruseFrameDetector>(encoder_stats_observer));
+}
+} // namespace webrtc
diff --git a/api/video/video_stream_encoder_create.h b/api/video/video_stream_encoder_create.h
new file mode 100644
index 0000000..9117273
--- /dev/null
+++ b/api/video/video_stream_encoder_create.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 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_VIDEO_VIDEO_STREAM_ENCODER_CREATE_H_
+#define API_VIDEO_VIDEO_STREAM_ENCODER_CREATE_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "api/video/video_stream_encoder_interface.h"
+#include "api/video/video_stream_encoder_observer.h"
+#include "api/video/video_stream_encoder_settings.h"
+
+namespace webrtc {
+
+std::unique_ptr<VideoStreamEncoderInterface> CreateVideoStreamEncoder(
+ uint32_t number_of_cores,
+ VideoStreamEncoderObserver* encoder_stats_observer,
+ const VideoStreamEncoderSettings& settings,
+ // Deprecated, used for tests only.
+ rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback);
+
+inline std::unique_ptr<VideoStreamEncoderInterface> CreateVideoStreamEncoder(
+ uint32_t number_of_cores,
+ VideoStreamEncoderObserver* encoder_stats_observer,
+ const VideoStreamEncoderSettings& settings) {
+ return CreateVideoStreamEncoder(number_of_cores, encoder_stats_observer,
+ settings, nullptr);
+}
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_STREAM_ENCODER_CREATE_H_
diff --git a/api/video/video_stream_encoder_interface.h b/api/video/video_stream_encoder_interface.h
index 44dc6f4..2f95e58 100644
--- a/api/video/video_stream_encoder_interface.h
+++ b/api/video/video_stream_encoder_interface.h
@@ -47,8 +47,6 @@
int min_transmit_bitrate_bps) = 0;
};
- ~VideoStreamEncoderInterface() override = default;
-
// Sets the source that will provide video frames to the VideoStreamEncoder's
// OnFrame method. |degradation_preference| control whether or not resolution
// or frame rate may be reduced. The VideoStreamEncoder registers itself with
diff --git a/api/video/video_stream_encoder_observer.cc b/api/video/video_stream_encoder_observer.cc
new file mode 100644
index 0000000..3b9bd52
--- /dev/null
+++ b/api/video/video_stream_encoder_observer.cc
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018 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/video/video_stream_encoder_observer.h"
+
+namespace webrtc {
+
+VideoStreamEncoderObserver::AdaptationSteps::AdaptationSteps() = default;
+
+} // namespace webrtc
diff --git a/api/video/video_stream_encoder_observer.h b/api/video/video_stream_encoder_observer.h
new file mode 100644
index 0000000..b940efd
--- /dev/null
+++ b/api/video/video_stream_encoder_observer.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2018 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_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
+#define API_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
+
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/video_codecs/video_encoder.h"
+#include "api/video_codecs/video_encoder_config.h"
+
+namespace webrtc {
+
+// TODO(nisse): Used for the OnSendEncodedImage callback below. The callback
+// wants metadata such as size, encode timing, qp, but doesn't need actual
+// encoded data. So use some other type to represent that.
+class EncodedImage;
+
+// Broken out into a base class, with public inheritance below, only to ease
+// unit testing of the internal class OveruseFrameDetector.
+class CpuOveruseMetricsObserver {
+ public:
+ virtual ~CpuOveruseMetricsObserver() = default;
+ virtual void OnEncodedFrameTimeMeasured(int encode_duration_ms,
+ int encode_usage_percent) = 0;
+};
+
+class VideoStreamEncoderObserver : public CpuOveruseMetricsObserver {
+ public:
+ // Number of resolution and framerate reductions (unset if disabled).
+ struct AdaptationSteps {
+ AdaptationSteps();
+ absl::optional<int> num_resolution_reductions = 0;
+ absl::optional<int> num_framerate_reductions = 0;
+ };
+
+ // TODO(nisse): There are too many enums to represent this. Besides
+ // this one, see AdaptationObserverInterface::AdaptReason and
+ // WebRtcVideoChannel::AdaptReason.
+ enum class AdaptationReason {
+ kNone, // Used for reset of counters.
+ kCpu,
+ kQuality,
+ };
+
+ // TODO(nisse): Duplicates enum EncodedImageCallback::DropReason.
+ enum class DropReason {
+ kSource,
+ kEncoderQueue,
+ kEncoder,
+ kMediaOptimization
+ };
+
+ ~VideoStreamEncoderObserver() override = default;
+
+ virtual void OnIncomingFrame(int width, int height) = 0;
+
+ // TODO(nisse): Merge into one callback per encoded frame.
+ using CpuOveruseMetricsObserver::OnEncodedFrameTimeMeasured;
+ virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
+ const CodecSpecificInfo* codec_info) = 0;
+
+ virtual void OnFrameDropped(DropReason reason) = 0;
+
+ // Used to indicate change in content type, which may require a change in
+ // how stats are collected and set the configured preferred media bitrate.
+ virtual void OnEncoderReconfigured(
+ const VideoEncoderConfig& encoder_config,
+ const std::vector<VideoStream>& streams) = 0;
+
+ virtual void OnAdaptationChanged(AdaptationReason reason,
+ const AdaptationSteps& cpu_steps,
+ const AdaptationSteps& quality_steps) = 0;
+ virtual void OnMinPixelLimitReached() = 0;
+ virtual void OnInitialQualityResolutionAdaptDown() = 0;
+
+ virtual void OnSuspendChange(bool is_suspended) = 0;
+
+ // TODO(nisse): VideoStreamEncoder wants to query the stats, which makes this
+ // not a pure observer. GetInputFrameRate is needed for the cpu adaptation, so
+ // can be deleted if that responsibility is moved out to a VideoStreamAdaptor
+ // class.
+ virtual int GetInputFrameRate() const = 0;
+};
+
+} // namespace webrtc
+#endif // API_VIDEO_VIDEO_STREAM_ENCODER_OBSERVER_H_
diff --git a/api/video/video_stream_encoder_settings.h b/api/video/video_stream_encoder_settings.h
new file mode 100644
index 0000000..b67f33c
--- /dev/null
+++ b/api/video/video_stream_encoder_settings.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 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_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
+#define API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
+
+#include "api/video_codecs/video_encoder_factory.h"
+
+namespace webrtc {
+
+struct VideoStreamEncoderSettings {
+ VideoStreamEncoderSettings() = default;
+
+ // Enables the new method to estimate the cpu load from encoding, used for
+ // cpu adaptation.
+ bool experiment_cpu_load_estimator = false;
+
+ // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
+ VideoEncoderFactory* encoder_factory = nullptr;
+};
+
+} // namespace webrtc
+
+#endif // API_VIDEO_VIDEO_STREAM_ENCODER_SETTINGS_H_
diff --git a/audio/BUILD.gn b/audio/BUILD.gn
index 22ceeb6..ae4c67e 100644
--- a/audio/BUILD.gn
+++ b/audio/BUILD.gn
@@ -54,7 +54,6 @@
"../api/audio:audio_frame_api",
"../api/audio:audio_mixer_api",
"../api/audio_codecs:audio_codecs_api",
- "../api/audio_codecs:builtin_audio_encoder_factory",
"../call:bitrate_allocator",
"../call:call_interfaces",
"../call:rtp_interfaces",
@@ -100,6 +99,9 @@
]
deps = [
":audio",
+ "../api:simulated_network_api",
+ "../call:fake_network",
+ "../call:simulated_network",
"../system_wrappers:system_wrappers",
"../test:test_common",
"../test:test_support",
@@ -121,6 +123,7 @@
"audio_state_unittest.cc",
"mock_voe_channel_proxy.h",
"remix_resample_unittest.cc",
+ "test/audio_stats_test.cc",
"time_interval_unittest.cc",
"transport_feedback_packet_loss_tracker_unittest.cc",
]
@@ -159,11 +162,6 @@
"//third_party/abseil-cpp/absl/memory",
]
- if (!rtc_use_memcheck) {
- # This test is timing dependent, which rules out running on memcheck bots.
- sources += [ "test/audio_stats_test.cc" ]
- }
-
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
@@ -180,6 +178,7 @@
deps = [
":audio_end_to_end_test",
+ "../api:simulated_network_api",
"../common_audio",
"../rtc_base:rtc_base_approved",
"../system_wrappers",
@@ -251,6 +250,9 @@
"test/audio_bwe_integration_test.h",
]
deps = [
+ "../api:simulated_network_api",
+ "../call:fake_network",
+ "../call:simulated_network",
"../common_audio",
"../rtc_base:rtc_base_approved",
"../system_wrappers",
diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc
index 6f43576..b507afc 100644
--- a/audio/audio_receive_stream.cc
+++ b/audio/audio_receive_stream.cc
@@ -20,7 +20,6 @@
#include "audio/conversion.h"
#include "call/rtp_stream_receiver_controller_interface.h"
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
-#include "modules/rtp_rtcp/include/rtp_receiver.h"
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
@@ -66,16 +65,16 @@
std::unique_ptr<voe::ChannelProxy> CreateChannelAndProxy(
webrtc::AudioState* audio_state,
ProcessThread* module_process_thread,
- const webrtc::AudioReceiveStream::Config& config) {
+ const webrtc::AudioReceiveStream::Config& config,
+ RtcEventLog* event_log) {
RTC_DCHECK(audio_state);
internal::AudioState* internal_audio_state =
static_cast<internal::AudioState*>(audio_state);
- return std::unique_ptr<voe::ChannelProxy>(
- new voe::ChannelProxy(std::unique_ptr<voe::Channel>(new voe::Channel(
- module_process_thread, internal_audio_state->audio_device_module(),
- nullptr /* RtcpRttStats */, config.jitter_buffer_max_packets,
- config.jitter_buffer_fast_accelerate, config.decoder_factory,
- config.codec_pair_id))));
+ return absl::make_unique<voe::ChannelProxy>(absl::make_unique<voe::Channel>(
+ module_process_thread, internal_audio_state->audio_device_module(),
+ nullptr /* RtcpRttStats */, event_log, config.rtp.remote_ssrc,
+ config.jitter_buffer_max_packets, config.jitter_buffer_fast_accelerate,
+ config.decoder_factory, config.codec_pair_id));
}
} // namespace
@@ -93,7 +92,8 @@
event_log,
CreateChannelAndProxy(audio_state.get(),
module_process_thread,
- config)) {}
+ config,
+ event_log)) {}
AudioReceiveStream::AudioReceiveStream(
RtpStreamReceiverControllerInterface* receiver_controller,
@@ -112,7 +112,6 @@
module_process_thread_checker_.DetachFromThread();
- channel_proxy_->SetRtcEventLog(event_log);
channel_proxy_->RegisterTransport(config.rtcp_send_transport);
// Configure bandwidth estimation.
@@ -132,7 +131,6 @@
channel_proxy_->DisassociateSendChannel();
channel_proxy_->RegisterTransport(nullptr);
channel_proxy_->ResetReceiverCongestionControlObjects();
- channel_proxy_->SetRtcEventLog(nullptr);
}
void AudioReceiveStream::Reconfigure(
@@ -257,26 +255,12 @@
absl::optional<Syncable::Info> AudioReceiveStream::GetInfo() const {
RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
- Syncable::Info info;
+ absl::optional<Syncable::Info> info = channel_proxy_->GetSyncInfo();
- RtpRtcp* rtp_rtcp = nullptr;
- RtpReceiver* rtp_receiver = nullptr;
- channel_proxy_->GetRtpRtcp(&rtp_rtcp, &rtp_receiver);
- RTC_DCHECK(rtp_rtcp);
- RTC_DCHECK(rtp_receiver);
-
- if (!rtp_receiver->GetLatestTimestamps(
- &info.latest_received_capture_timestamp,
- &info.latest_receive_time_ms)) {
+ if (!info)
return absl::nullopt;
- }
- if (rtp_rtcp->RemoteNTP(&info.capture_time_ntp_secs,
- &info.capture_time_ntp_frac, nullptr, nullptr,
- &info.capture_time_source_clock) != 0) {
- return absl::nullopt;
- }
- info.current_delay_ms = channel_proxy_->GetDelayEstimate();
+ info->current_delay_ms = channel_proxy_->GetDelayEstimate();
return info;
}
@@ -360,9 +344,7 @@
channel_proxy->SetLocalSSRC(new_config.rtp.local_ssrc);
}
- if (first_time) {
- channel_proxy->SetRemoteSSRC(new_config.rtp.remote_ssrc);
- } else {
+ if (!first_time) {
// Remote ssrc can't be changed mid-stream.
RTC_DCHECK_EQ(old_config.rtp.remote_ssrc, new_config.rtp.remote_ssrc);
}
diff --git a/audio/audio_receive_stream_unittest.cc b/audio/audio_receive_stream_unittest.cc
index 51635f6..eb93bd0 100644
--- a/audio/audio_receive_stream_unittest.cc
+++ b/audio/audio_receive_stream_unittest.cc
@@ -83,7 +83,6 @@
channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kLocalSsrc)).Times(1);
- EXPECT_CALL(*channel_proxy_, SetRemoteSSRC(kRemoteSsrc)).Times(1);
EXPECT_CALL(*channel_proxy_, SetNACKStatus(true, 15)).Times(1);
EXPECT_CALL(*channel_proxy_,
RegisterReceiverCongestionControlObjects(&packet_router_))
@@ -91,11 +90,6 @@
EXPECT_CALL(*channel_proxy_, ResetReceiverCongestionControlObjects())
.Times(1);
EXPECT_CALL(*channel_proxy_, RegisterTransport(nullptr)).Times(2);
- testing::Expectation expect_set =
- EXPECT_CALL(*channel_proxy_, SetRtcEventLog(&event_log_)).Times(1);
- EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull()))
- .Times(1)
- .After(expect_set);
EXPECT_CALL(*channel_proxy_, DisassociateSendChannel()).Times(1);
EXPECT_CALL(*channel_proxy_, SetReceiveCodecs(_))
.WillRepeatedly(Invoke([](const std::map<int, SdpAudioFormat>& codecs) {
@@ -236,11 +230,11 @@
const int kTransportSequenceNumberValue = 1234;
std::vector<uint8_t> rtp_packet = CreateRtpHeaderWithOneByteExtension(
kTransportSequenceNumberId, kTransportSequenceNumberValue, 2);
- PacketTime packet_time(5678000, 0);
+ constexpr int64_t packet_time_us = 5678000;
RtpPacketReceived parsed_packet;
ASSERT_TRUE(parsed_packet.Parse(&rtp_packet[0], rtp_packet.size()));
- parsed_packet.set_arrival_time_ms((packet_time.timestamp + 500) / 1000);
+ parsed_packet.set_arrival_time_ms((packet_time_us + 500) / 1000);
EXPECT_CALL(*helper.channel_proxy(),
OnRtpPacket(testing::Ref(parsed_packet)));
diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc
index de1be2c..0f725c4 100644
--- a/audio/audio_send_stream.cc
+++ b/audio/audio_send_stream.cc
@@ -14,6 +14,8 @@
#include <utility>
#include <vector>
+#include "absl/memory/memory.h"
+
#include "audio/audio_state.h"
#include "audio/channel_proxy.h"
#include "audio/conversion.h"
@@ -48,14 +50,14 @@
webrtc::AudioState* audio_state,
rtc::TaskQueue* worker_queue,
ProcessThread* module_process_thread,
- RtcpRttStats* rtcp_rtt_stats) {
+ RtcpRttStats* rtcp_rtt_stats,
+ RtcEventLog* event_log) {
RTC_DCHECK(audio_state);
internal::AudioState* internal_audio_state =
static_cast<internal::AudioState*>(audio_state);
- return std::unique_ptr<voe::ChannelProxy>(
- new voe::ChannelProxy(std::unique_ptr<voe::Channel>(new voe::Channel(
- worker_queue, module_process_thread,
- internal_audio_state->audio_device_module(), rtcp_rtt_stats))));
+ return absl::make_unique<voe::ChannelProxy>(absl::make_unique<voe::Channel>(
+ worker_queue, module_process_thread,
+ internal_audio_state->audio_device_module(), rtcp_rtt_stats, event_log));
}
} // namespace
@@ -105,7 +107,8 @@
CreateChannelAndProxy(audio_state.get(),
worker_queue,
module_process_thread,
- rtcp_rtt_stats)) {}
+ rtcp_rtt_stats,
+ event_log)) {}
AudioSendStream::AudioSendStream(
const webrtc::AudioSendStream::Config& config,
@@ -139,10 +142,8 @@
RTC_DCHECK(transport);
RTC_DCHECK(overall_call_lifetime_);
- channel_proxy_->SetRtcEventLog(event_log_);
channel_proxy_->SetRTCPStatus(true);
- RtpReceiver* rtpReceiver = nullptr; // Unused, but required for call.
- channel_proxy_->GetRtpRtcp(&rtp_rtcp_module_, &rtpReceiver);
+ rtp_rtcp_module_ = channel_proxy_->GetRtpRtcp();
RTC_DCHECK(rtp_rtcp_module_);
ConfigureStream(this, config, true);
@@ -159,7 +160,6 @@
transport_->DeRegisterPacketFeedbackObserver(this);
channel_proxy_->RegisterTransport(nullptr);
channel_proxy_->ResetSenderCongestionControlObjects();
- channel_proxy_->SetRtcEventLog(nullptr);
// Lifetime can only be updated after deregistering
// |timed_send_transport_adapter_| in the underlying channel object to avoid
// data races in |active_lifetime_|.
diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc
index 2341d4e..f5d6796 100644
--- a/audio/audio_send_stream_unittest.cc
+++ b/audio/audio_send_stream_unittest.cc
@@ -189,12 +189,9 @@
void SetupDefaultChannelProxy(bool audio_bwe_enabled) {
EXPECT_TRUE(channel_proxy_ == nullptr);
channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
- EXPECT_CALL(*channel_proxy_, GetRtpRtcp(_, _))
- .WillRepeatedly(Invoke(
- [this](RtpRtcp** rtp_rtcp_module, RtpReceiver** rtp_receiver) {
- *rtp_rtcp_module = &this->rtp_rtcp_;
- *rtp_receiver = nullptr; // Not deemed necessary for tests yet.
- }));
+ EXPECT_CALL(*channel_proxy_, GetRtpRtcp()).WillRepeatedly(Invoke([this]() {
+ return &this->rtp_rtcp_;
+ }));
EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1);
EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1);
EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1);
@@ -224,9 +221,6 @@
EXPECT_CALL(*channel_proxy_, RegisterTransport(_)).Times(1);
EXPECT_CALL(*channel_proxy_, RegisterTransport(nullptr)).Times(1);
}
- EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::NotNull())).Times(1);
- EXPECT_CALL(*channel_proxy_, SetRtcEventLog(testing::IsNull()))
- .Times(1); // Destructor resets the event log
}
void SetupMockForSetupSendCodec(bool expect_set_encoder_call) {
@@ -385,8 +379,7 @@
EXPECT_EQ(kSsrc, stats.local_ssrc);
EXPECT_EQ(static_cast<int64_t>(kCallStats.bytesSent), stats.bytes_sent);
EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
- EXPECT_EQ(static_cast<int32_t>(kReportBlock.cumulative_num_packets_lost),
- stats.packets_lost);
+ EXPECT_EQ(kReportBlock.cumulative_num_packets_lost, stats.packets_lost);
EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost);
EXPECT_EQ(std::string(kIsacCodec.plname), stats.codec_name);
EXPECT_EQ(static_cast<int32_t>(kReportBlock.extended_highest_sequence_number),
diff --git a/audio/audio_state.cc b/audio/audio_state.cc
index 35ea03d..7d473ae 100644
--- a/audio/audio_state.cc
+++ b/audio/audio_state.cc
@@ -39,6 +39,15 @@
RTC_DCHECK(sending_streams_.empty());
}
+AudioProcessing* AudioState::audio_processing() {
+ RTC_DCHECK(config_.audio_processing);
+ return config_.audio_processing.get();
+}
+
+AudioTransport* AudioState::audio_transport() {
+ return &audio_transport_;
+}
+
bool AudioState::typing_noise_detected() const {
RTC_DCHECK(thread_checker_.CalledOnValidThread());
return audio_transport_.typing_noise_detected();
diff --git a/audio/audio_state.h b/audio/audio_state.h
index 689534b..9e302c4 100644
--- a/audio/audio_state.h
+++ b/audio/audio_state.h
@@ -35,11 +35,8 @@
explicit AudioState(const AudioState::Config& config);
~AudioState() override;
- AudioProcessing* audio_processing() override {
- RTC_DCHECK(config_.audio_processing);
- return config_.audio_processing.get();
- }
- AudioTransport* audio_transport() override { return &audio_transport_; }
+ AudioProcessing* audio_processing() override;
+ AudioTransport* audio_transport() override;
void SetPlayout(bool enabled) override;
void SetRecording(bool enabled) override;
diff --git a/audio/channel.cc b/audio/channel.cc
index 6acc65e..d884e03 100644
--- a/audio/channel.cc
+++ b/audio/channel.cc
@@ -29,8 +29,6 @@
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/pacing/packet_router.h"
#include "modules/rtp_rtcp/include/receive_statistics.h"
-#include "modules/rtp_rtcp/include/rtp_payload_registry.h"
-#include "modules/rtp_rtcp/include/rtp_receiver.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "modules/utility/include/process_thread.h"
@@ -63,36 +61,6 @@
const int kTelephoneEventAttenuationdB = 10;
-class RtcEventLogProxy final : public webrtc::RtcEventLog {
- public:
- RtcEventLogProxy() : event_log_(nullptr) {}
-
- bool StartLogging(std::unique_ptr<RtcEventLogOutput> output,
- int64_t output_period_ms) override {
- RTC_NOTREACHED();
- return false;
- }
-
- void StopLogging() override { RTC_NOTREACHED(); }
-
- void Log(std::unique_ptr<RtcEvent> event) override {
- rtc::CritScope lock(&crit_);
- if (event_log_) {
- event_log_->Log(std::move(event));
- }
- }
-
- void SetEventLog(RtcEventLog* event_log) {
- rtc::CritScope lock(&crit_);
- event_log_ = event_log;
- }
-
- private:
- rtc::CriticalSection crit_;
- RtcEventLog* event_log_ RTC_GUARDED_BY(crit_);
- RTC_DISALLOW_COPY_AND_ASSIGN(RtcEventLogProxy);
-};
-
class TransportFeedbackProxy : public TransportFeedbackObserver {
public:
TransportFeedbackProxy() : feedback_observer_(nullptr) {
@@ -374,8 +342,7 @@
}
int64_t round_trip_time = 0;
- _rtpRtcpModule->RTT(rtp_receiver_->SSRC(), &round_trip_time, NULL, NULL,
- NULL);
+ _rtpRtcpModule->RTT(remote_ssrc_, &round_trip_time, NULL, NULL, NULL);
std::vector<uint16_t> nack_list = audio_coding_->GetNackList(round_trip_time);
if (!nack_list.empty()) {
@@ -393,7 +360,7 @@
unsigned int ssrc;
RTC_CHECK_EQ(GetRemoteSSRC(ssrc), 0);
- event_log_proxy_->Log(absl::make_unique<RtcEventAudioPlayout>(ssrc));
+ event_log_->Log(absl::make_unique<RtcEventAudioPlayout>(ssrc));
// Get 10ms raw PCM data from the ACM (mixer limits output frequency)
bool muted;
if (audio_coding_->PlayoutData10Ms(audio_frame->sample_rate_hz_, audio_frame,
@@ -502,10 +469,13 @@
Channel::Channel(rtc::TaskQueue* encoder_queue,
ProcessThread* module_process_thread,
AudioDeviceModule* audio_device_module,
- RtcpRttStats* rtcp_rtt_stats)
+ RtcpRttStats* rtcp_rtt_stats,
+ RtcEventLog* rtc_event_log)
: Channel(module_process_thread,
audio_device_module,
rtcp_rtt_stats,
+ rtc_event_log,
+ 0,
0,
false,
rtc::scoped_refptr<AudioDecoderFactory>(),
@@ -517,19 +487,16 @@
Channel::Channel(ProcessThread* module_process_thread,
AudioDeviceModule* audio_device_module,
RtcpRttStats* rtcp_rtt_stats,
+ RtcEventLog* rtc_event_log,
+ uint32_t remote_ssrc,
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
absl::optional<AudioCodecPairId> codec_pair_id)
- : event_log_proxy_(new RtcEventLogProxy()),
- rtp_payload_registry_(new RTPPayloadRegistry()),
+ : event_log_(rtc_event_log),
rtp_receive_statistics_(
ReceiveStatistics::Create(Clock::GetRealTimeClock())),
- rtp_receiver_(
- RtpReceiver::CreateAudioReceiver(Clock::GetRealTimeClock(),
- this,
- rtp_payload_registry_.get())),
- telephone_event_handler_(rtp_receiver_->GetTelephoneEventHandler()),
+ remote_ssrc_(remote_ssrc),
_outputAudioLevel(),
_timeStamp(0), // This is just an offset, RTP module will add it's own
// random offset
@@ -570,6 +537,7 @@
_outputAudioLevel.Clear();
+ rtp_receive_statistics_->EnableRetransmitDetection(remote_ssrc_, true);
RtpRtcp::Configuration configuration;
configuration.audio = true;
configuration.outgoing_transport = this;
@@ -582,14 +550,14 @@
seq_num_allocator_proxy_.get();
configuration.transport_feedback_callback = feedback_observer_proxy_.get();
}
- configuration.event_log = &(*event_log_proxy_);
+ configuration.event_log = event_log_;
configuration.rtt_stats = rtcp_rtt_stats;
configuration.retransmission_rate_limiter =
retransmission_rate_limiter_.get();
_rtpRtcpModule.reset(RtpRtcp::CreateRtpRtcp(configuration));
_rtpRtcpModule->SetSendingMediaStatus(false);
-
+ _rtpRtcpModule->SetRemoteSSRC(remote_ssrc_);
Init();
}
@@ -616,7 +584,6 @@
// disabled by the user.
// After StopListen (when no sockets exists), RTCP packets will no longer
// be transmitted since the Transport object will then be invalid.
- telephone_event_handler_->SetTelephoneEventForwardToDecoder(true);
// RTCP is enabled by default.
_rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound);
@@ -814,6 +781,22 @@
});
}
+std::vector<webrtc::RtpSource> Channel::GetSources() const {
+ int64_t now_ms = rtc::TimeMillis();
+ std::vector<RtpSource> sources;
+ {
+ rtc::CritScope cs(&rtp_sources_lock_);
+ sources = contributing_sources_.GetSources(now_ms);
+ if (last_received_rtp_system_time_ms_ >=
+ now_ms - ContributingSources::kHistoryMs) {
+ sources.emplace_back(*last_received_rtp_system_time_ms_, remote_ssrc_,
+ RtpSourceType::SSRC);
+ sources.back().set_audio_level(last_received_rtp_audio_level_);
+ }
+ }
+ return sources;
+}
+
void Channel::OnUplinkPacketLossRate(float packet_loss_rate) {
if (use_twcc_plr_for_ana_)
return;
@@ -825,7 +808,10 @@
}
void Channel::SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) {
- rtp_payload_registry_->SetAudioReceivePayloads(codecs);
+ for (const auto& kv : codecs) {
+ RTC_DCHECK_GE(kv.second.clockrate_hz, 1000);
+ payload_type_frequencies_[kv.first] = kv.second.clockrate_hz;
+ }
audio_coding_->SetReceiveCodecs(codecs);
}
@@ -833,8 +819,8 @@
bool success = false;
audio_coding_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
if (*encoder) {
- success = (*encoder)->EnableAudioNetworkAdaptor(config_string,
- event_log_proxy_.get());
+ success =
+ (*encoder)->EnableAudioNetworkAdaptor(config_string, event_log_);
}
});
return success;
@@ -862,21 +848,38 @@
_transportPtr = transport;
}
+// TODO(nisse): Move receive logic up to AudioReceiveStream.
void Channel::OnRtpPacket(const RtpPacketReceived& packet) {
+ int64_t now_ms = rtc::TimeMillis();
+ uint8_t audio_level;
+ bool voice_activity;
+ bool has_audio_level =
+ packet.GetExtension<::webrtc::AudioLevel>(&voice_activity, &audio_level);
+
+ {
+ rtc::CritScope cs(&rtp_sources_lock_);
+ last_received_rtp_timestamp_ = packet.Timestamp();
+ last_received_rtp_system_time_ms_ = now_ms;
+ if (has_audio_level)
+ last_received_rtp_audio_level_ = audio_level;
+ std::vector<uint32_t> csrcs = packet.Csrcs();
+ contributing_sources_.Update(now_ms, csrcs);
+ }
+
RTPHeader header;
packet.GetHeader(&header);
// Store playout timestamp for the received RTP packet
UpdatePlayoutTimestamp(false);
- header.payload_type_frequency =
- rtp_payload_registry_->GetPayloadTypeFrequency(header.payloadType);
- if (header.payload_type_frequency >= 0) {
- rtp_receive_statistics_->IncomingPacket(header, packet.size(),
- IsPacketRetransmitted(header));
+ const auto& it = payload_type_frequencies_.find(header.payloadType);
+ if (it == payload_type_frequencies_.end())
+ return;
+ header.payload_type_frequency = it->second;
- ReceivePacket(packet.data(), packet.size(), header);
- }
+ rtp_receive_statistics_->IncomingPacket(header, packet.size());
+
+ ReceivePacket(packet.data(), packet.size(), header);
}
bool Channel::ReceivePacket(const uint8_t* packet,
@@ -885,22 +888,16 @@
const uint8_t* payload = packet + header.headerLength;
assert(packet_length >= header.headerLength);
size_t payload_length = packet_length - header.headerLength;
- const auto pl =
- rtp_payload_registry_->PayloadTypeToPayload(header.payloadType);
- if (!pl) {
- return false;
- }
- return rtp_receiver_->IncomingRtpPacket(header, payload, payload_length,
- pl->typeSpecific);
-}
+ WebRtcRTPHeader webrtc_rtp_header = {};
+ webrtc_rtp_header.header = header;
-bool Channel::IsPacketRetransmitted(const RTPHeader& header) const {
- StreamStatistician* statistician =
- rtp_receive_statistics_->GetStatistician(header.ssrc);
- if (!statistician)
- return false;
- // Check if this is a retransmission.
- return statistician->IsRetransmitOfOldPacket(header);
+ const size_t payload_data_length = payload_length - header.paddingLength;
+ if (payload_data_length == 0) {
+ webrtc_rtp_header.frameType = kEmptyFrame;
+ return OnReceivedPayloadData(nullptr, 0, &webrtc_rtp_header);
+ }
+ return OnReceivedPayloadData(payload, payload_data_length,
+ &webrtc_rtp_header);
}
int32_t Channel::ReceivedRTCPPacket(const uint8_t* data, size_t length) {
@@ -1018,19 +1015,15 @@
return 0;
}
-void Channel::SetRemoteSSRC(uint32_t ssrc) {
- // Update ssrc so that NTP for AV sync can be updated.
- _rtpRtcpModule->SetRemoteSSRC(ssrc);
-}
-
void Channel::SetMid(const std::string& mid, int extension_id) {
int ret = SetSendRtpHeaderExtension(true, kRtpExtensionMid, extension_id);
RTC_DCHECK_EQ(0, ret);
_rtpRtcpModule->SetMid(mid);
}
+// TODO(nisse): Pass ssrc in return value instead.
int Channel::GetRemoteSSRC(unsigned int& ssrc) {
- ssrc = rtp_receiver_->SSRC();
+ ssrc = remote_ssrc_;
return 0;
}
@@ -1148,7 +1141,7 @@
// based on received packets.
RtcpStatistics statistics;
StreamStatistician* statistician =
- rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
+ rtp_receive_statistics_->GetStatistician(remote_ssrc_);
if (statistician) {
statistician->GetStatistics(&statistics,
_rtpRtcpModule->RTCP() == RtcpMode::kOff);
@@ -1270,10 +1263,6 @@
associated_send_channel_ = channel;
}
-void Channel::SetRtcEventLog(RtcEventLog* event_log) {
- event_log_proxy_->SetEventLog(event_log);
-}
-
void Channel::UpdateOverheadForEncoder() {
size_t overhead_per_packet =
transport_overhead_per_packet_ + rtp_overhead_per_packet_;
@@ -1342,11 +1331,26 @@
return 0;
}
-int Channel::GetRtpRtcp(RtpRtcp** rtpRtcpModule,
- RtpReceiver** rtp_receiver) const {
- *rtpRtcpModule = _rtpRtcpModule.get();
- *rtp_receiver = rtp_receiver_.get();
- return 0;
+RtpRtcp* Channel::GetRtpRtcp() const {
+ return _rtpRtcpModule.get();
+}
+
+absl::optional<Syncable::Info> Channel::GetSyncInfo() const {
+ Syncable::Info info;
+ if (_rtpRtcpModule->RemoteNTP(&info.capture_time_ntp_secs,
+ &info.capture_time_ntp_frac, nullptr, nullptr,
+ &info.capture_time_source_clock) != 0) {
+ return absl::nullopt;
+ }
+ {
+ rtc::CritScope cs(&rtp_sources_lock_);
+ if (!last_received_rtp_timestamp_ || !last_received_rtp_system_time_ms_) {
+ return absl::nullopt;
+ }
+ info.latest_received_capture_timestamp = *last_received_rtp_timestamp_;
+ info.latest_receive_time_ms = *last_received_rtp_system_time_ms_;
+ }
+ return info;
}
void Channel::UpdatePlayoutTimestamp(bool rtcp) {
@@ -1426,25 +1430,23 @@
return rtt;
}
- uint32_t remoteSSRC = rtp_receiver_->SSRC();
std::vector<RTCPReportBlock>::const_iterator it = report_blocks.begin();
for (; it != report_blocks.end(); ++it) {
- if (it->sender_ssrc == remoteSSRC)
+ if (it->sender_ssrc == remote_ssrc_)
break;
}
- if (it == report_blocks.end()) {
- // We have not received packets with SSRC matching the report blocks.
- // To calculate RTT we try with the SSRC of the first report block.
- // This is very important for send-only channels where we don't know
- // the SSRC of the other end.
- remoteSSRC = report_blocks[0].sender_ssrc;
- }
+
+ // If we have not received packets with SSRC matching the report blocks, use
+ // the SSRC of the first report block for calculating the RTT. This is very
+ // important for send-only channels where we don't know the SSRC of the other
+ // end.
+ uint32_t ssrc =
+ (it == report_blocks.end()) ? report_blocks[0].sender_ssrc : remote_ssrc_;
int64_t avg_rtt = 0;
int64_t max_rtt = 0;
int64_t min_rtt = 0;
- if (_rtpRtcpModule->RTT(remoteSSRC, &rtt, &avg_rtt, &min_rtt, &max_rtt) !=
- 0) {
+ if (_rtpRtcpModule->RTT(ssrc, &rtt, &avg_rtt, &min_rtt, &max_rtt) != 0) {
return 0;
}
return rtt;
diff --git a/audio/channel.h b/audio/channel.h
index 8d1a26b..562e79e 100644
--- a/audio/channel.h
+++ b/audio/channel.h
@@ -21,14 +21,16 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/call/audio_sink.h"
#include "api/call/transport.h"
+#include "api/rtpreceiverinterface.h"
#include "audio/audio_level.h"
+#include "call/syncable.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_processing/rms_level.h"
#include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
-#include "modules/rtp_rtcp/include/rtp_receiver.h"
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
+#include "modules/rtp_rtcp/source/contributing_sources.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/event.h"
#include "rtc_base/task_queue.h"
@@ -51,12 +53,9 @@
class ReceiveStatistics;
class RemoteNtpTimeEstimator;
class RtcEventLog;
-class RTPPayloadRegistry;
-class RTPReceiverAudio;
class RtpPacketReceived;
class RtpRtcp;
class RtpTransportControllerSendInterface;
-class TelephoneEventHandler;
struct SenderInfo;
@@ -80,7 +79,7 @@
uint32_t sender_SSRC; // SSRC of sender
uint32_t source_SSRC;
uint8_t fraction_lost;
- uint32_t cumulative_num_packets_lost;
+ int32_t cumulative_num_packets_lost;
uint32_t extended_highest_sequence_number;
uint32_t interarrival_jitter;
uint32_t last_SR_timestamp;
@@ -89,7 +88,6 @@
namespace voe {
-class RtcEventLogProxy;
class RtpPacketSenderProxy;
class TransportFeedbackProxy;
class TransportSequenceNumberProxy;
@@ -150,11 +148,14 @@
Channel(rtc::TaskQueue* encoder_queue,
ProcessThread* module_process_thread,
AudioDeviceModule* audio_device_module,
- RtcpRttStats* rtcp_rtt_stats);
+ RtcpRttStats* rtcp_rtt_stats,
+ RtcEventLog* rtc_event_log);
// Used for receive streams.
Channel(ProcessThread* module_process_thread,
AudioDeviceModule* audio_device_module,
RtcpRttStats* rtcp_rtt_stats,
+ RtcEventLog* rtc_event_log,
+ uint32_t remote_ssrc,
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout,
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
@@ -210,15 +211,18 @@
uint32_t GetDelayEstimate() const;
int SetMinimumPlayoutDelay(int delayMs);
int GetPlayoutTimestamp(unsigned int& timestamp); // NOLINT
- int GetRtpRtcp(RtpRtcp** rtpRtcpModule, RtpReceiver** rtp_receiver) const;
+ // Used by AudioSendStream.
+ RtpRtcp* GetRtpRtcp() const;
+
+ // Produces the transport-related timestamps; current_delay_ms is left unset.
+ absl::optional<Syncable::Info> GetSyncInfo() const;
// DTMF.
int SendTelephoneEventOutband(int event, int duration_ms);
int SetSendTelephoneEventPayloadType(int payload_type, int payload_frequency);
// RTP+RTCP
int SetLocalSSRC(unsigned int ssrc);
- void SetRemoteSSRC(uint32_t ssrc);
void SetMid(const std::string& mid, int extension_id);
int SetSendAudioLevelIndicationStatus(bool enable, unsigned char id);
@@ -281,9 +285,6 @@
// Used for obtaining RTT for a receive-only channel.
void SetAssociatedSendChannel(Channel* channel);
- // Set a RtcEventLog logging object.
- void SetRtcEventLog(RtcEventLog* event_log);
-
void SetTransportOverhead(size_t transport_overhead_per_packet);
// From OverheadObserver in the RTP/RTCP module
@@ -297,9 +298,7 @@
void OnRecoverableUplinkPacketLossRate(float recoverable_packet_loss_rate);
- std::vector<RtpSource> GetSources() const {
- return rtp_receiver_->GetSources();
- }
+ std::vector<RtpSource> GetSources() const;
private:
class ProcessAndEncodeAudioTask;
@@ -314,7 +313,6 @@
bool ReceivePacket(const uint8_t* packet,
size_t packet_length,
const RTPHeader& header);
- bool IsPacketRetransmitted(const RTPHeader& header) const;
int ResendPackets(const uint16_t* sequence_numbers, int length);
void UpdatePlayoutTimestamp(bool rtcp);
@@ -337,13 +335,26 @@
ChannelState channel_state_;
- std::unique_ptr<voe::RtcEventLogProxy> event_log_proxy_;
+ RtcEventLog* const event_log_;
- std::unique_ptr<RTPPayloadRegistry> rtp_payload_registry_;
+ // Indexed by payload type.
+ std::map<uint8_t, int> payload_type_frequencies_;
+
std::unique_ptr<ReceiveStatistics> rtp_receive_statistics_;
- std::unique_ptr<RtpReceiver> rtp_receiver_;
- TelephoneEventHandler* telephone_event_handler_;
std::unique_ptr<RtpRtcp> _rtpRtcpModule;
+ const uint32_t remote_ssrc_;
+
+ // Info for GetSources and GetSyncInfo is updated on network or worker thread,
+ // queried on the worker thread.
+ rtc::CriticalSection rtp_sources_lock_;
+ ContributingSources contributing_sources_ RTC_GUARDED_BY(&rtp_sources_lock_);
+ absl::optional<uint32_t> last_received_rtp_timestamp_
+ RTC_GUARDED_BY(&rtp_sources_lock_);
+ absl::optional<int64_t> last_received_rtp_system_time_ms_
+ RTC_GUARDED_BY(&rtp_sources_lock_);
+ absl::optional<uint8_t> last_received_rtp_audio_level_
+ RTC_GUARDED_BY(&rtp_sources_lock_);
+
std::unique_ptr<AudioCodingModule> audio_coding_;
AudioSinkInterface* audio_sink_ = nullptr;
AudioLevel _outputAudioLevel;
diff --git a/audio/channel_proxy.cc b/audio/channel_proxy.cc
index bac681f..5e8181a 100644
--- a/audio/channel_proxy.cc
+++ b/audio/channel_proxy.cc
@@ -53,11 +53,6 @@
RTC_DCHECK_EQ(0, error);
}
-void ChannelProxy::SetRemoteSSRC(uint32_t ssrc) {
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- channel_->SetRemoteSSRC(ssrc);
-}
-
void ChannelProxy::SetMid(const std::string& mid, int extension_id) {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
channel_->SetMid(mid, extension_id);
@@ -226,11 +221,6 @@
channel_->SetChannelOutputVolumeScaling(scaling);
}
-void ChannelProxy::SetRtcEventLog(RtcEventLog* event_log) {
- RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
- channel_->SetRtcEventLog(event_log);
-}
-
AudioMixer::Source::AudioFrameInfo ChannelProxy::GetAudioFrameWithInfo(
int sample_rate_hz,
AudioFrame* audio_frame) {
@@ -265,13 +255,14 @@
channel_->SetAssociatedSendChannel(nullptr);
}
-void ChannelProxy::GetRtpRtcp(RtpRtcp** rtp_rtcp,
- RtpReceiver** rtp_receiver) const {
+RtpRtcp* ChannelProxy::GetRtpRtcp() const {
RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
- RTC_DCHECK(rtp_rtcp);
- RTC_DCHECK(rtp_receiver);
- int error = channel_->GetRtpRtcp(rtp_rtcp, rtp_receiver);
- RTC_DCHECK_EQ(0, error);
+ return channel_->GetRtpRtcp();
+}
+
+absl::optional<Syncable::Info> ChannelProxy::GetSyncInfo() const {
+ RTC_DCHECK(module_process_thread_checker_.CalledOnValidThread());
+ return channel_->GetSyncInfo();
}
uint32_t ChannelProxy::GetPlayoutTimestamp() const {
diff --git a/audio/channel_proxy.h b/audio/channel_proxy.h
index 0029851..f82c1fd 100644
--- a/audio/channel_proxy.h
+++ b/audio/channel_proxy.h
@@ -34,7 +34,6 @@
class RtcpRttStats;
class RtpPacketSender;
class RtpPacketReceived;
-class RtpReceiver;
class RtpRtcp;
class RtpTransportControllerSendInterface;
class Transport;
@@ -62,7 +61,6 @@
virtual void SetRTCPStatus(bool enable);
virtual void SetLocalSSRC(uint32_t ssrc);
- virtual void SetRemoteSSRC(uint32_t ssrc);
virtual void SetMid(const std::string& mid, int extension_id);
virtual void SetRTCP_CNAME(const std::string& c_name);
virtual void SetNACKStatus(bool enable, int max_packets);
@@ -99,7 +97,6 @@
void OnRtpPacket(const RtpPacketReceived& packet) override;
virtual bool ReceivedRTCPPacket(const uint8_t* packet, size_t length);
virtual void SetChannelOutputVolumeScaling(float scaling);
- virtual void SetRtcEventLog(RtcEventLog* event_log);
virtual AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo(
int sample_rate_hz,
AudioFrame* audio_frame);
@@ -108,7 +105,10 @@
virtual void SetTransportOverhead(int transport_overhead_per_packet);
virtual void AssociateSendChannel(const ChannelProxy& send_channel_proxy);
virtual void DisassociateSendChannel();
- virtual void GetRtpRtcp(RtpRtcp** rtp_rtcp, RtpReceiver** rtp_receiver) const;
+ virtual RtpRtcp* GetRtpRtcp() const;
+
+ // Produces the transport-related timestamps; current_delay_ms is left unset.
+ absl::optional<Syncable::Info> GetSyncInfo() const;
virtual uint32_t GetPlayoutTimestamp() const;
virtual void SetMinimumPlayoutDelay(int delay_ms);
virtual bool GetRecCodec(CodecInst* codec_inst) const;
diff --git a/audio/mock_voe_channel_proxy.h b/audio/mock_voe_channel_proxy.h
index 7396dd1..f6a2637 100644
--- a/audio/mock_voe_channel_proxy.h
+++ b/audio/mock_voe_channel_proxy.h
@@ -37,7 +37,6 @@
void(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier));
MOCK_METHOD1(SetRTCPStatus, void(bool enable));
MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc));
- MOCK_METHOD1(SetRemoteSSRC, void(uint32_t ssrc));
MOCK_METHOD1(SetRTCP_CNAME, void(const std::string& c_name));
MOCK_METHOD2(SetNACKStatus, void(bool enable, int max_packets));
MOCK_METHOD2(SetSendAudioLevelIndicationStatus, void(bool enable, int id));
@@ -68,7 +67,6 @@
MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived& packet));
MOCK_METHOD2(ReceivedRTCPPacket, bool(const uint8_t* packet, size_t length));
MOCK_METHOD1(SetChannelOutputVolumeScaling, void(float scaling));
- MOCK_METHOD1(SetRtcEventLog, void(RtcEventLog* event_log));
MOCK_METHOD2(GetAudioFrameWithInfo,
AudioMixer::Source::AudioFrameInfo(int sample_rate_hz,
AudioFrame* audio_frame));
@@ -83,8 +81,7 @@
MOCK_METHOD1(AssociateSendChannel,
void(const ChannelProxy& send_channel_proxy));
MOCK_METHOD0(DisassociateSendChannel, void());
- MOCK_CONST_METHOD2(GetRtpRtcp,
- void(RtpRtcp** rtp_rtcp, RtpReceiver** rtp_receiver));
+ MOCK_CONST_METHOD0(GetRtpRtcp, RtpRtcp*());
MOCK_CONST_METHOD0(GetPlayoutTimestamp, uint32_t());
MOCK_METHOD1(SetMinimumPlayoutDelay, void(int delay_ms));
MOCK_CONST_METHOD1(GetRecCodec, bool(CodecInst* codec_inst));
diff --git a/audio/null_audio_poller.h b/audio/null_audio_poller.h
index b6ddf17..afb6edb 100644
--- a/audio/null_audio_poller.h
+++ b/audio/null_audio_poller.h
@@ -21,7 +21,7 @@
class NullAudioPoller final : public rtc::MessageHandler {
public:
explicit NullAudioPoller(AudioTransport* audio_transport);
- ~NullAudioPoller();
+ ~NullAudioPoller() override;
protected:
void OnMessage(rtc::Message* msg) override;
diff --git a/audio/transport_feedback_packet_loss_tracker.cc b/audio/transport_feedback_packet_loss_tracker.cc
index 7e0c5c5..c7acd76 100644
--- a/audio/transport_feedback_packet_loss_tracker.cc
+++ b/audio/transport_feedback_packet_loss_tracker.cc
@@ -47,6 +47,9 @@
Reset();
}
+TransportFeedbackPacketLossTracker::~TransportFeedbackPacketLossTracker() =
+ default;
+
void TransportFeedbackPacketLossTracker::Reset() {
acked_packets_ = 0;
plr_state_.Reset();
diff --git a/audio/transport_feedback_packet_loss_tracker.h b/audio/transport_feedback_packet_loss_tracker.h
index 7d58d6c..180b64a 100644
--- a/audio/transport_feedback_packet_loss_tracker.h
+++ b/audio/transport_feedback_packet_loss_tracker.h
@@ -35,6 +35,7 @@
TransportFeedbackPacketLossTracker(int64_t max_window_size_ms,
size_t plr_min_num_acked_packets,
size_t rplr_min_num_acked_pairs);
+ ~TransportFeedbackPacketLossTracker();
void OnPacketAdded(uint16_t seq_num, int64_t send_time_ms);
diff --git a/audio/utility/BUILD.gn b/audio/utility/BUILD.gn
index fe39b7f..76c09a5 100644
--- a/audio/utility/BUILD.gn
+++ b/audio/utility/BUILD.gn
@@ -22,7 +22,6 @@
deps = [
"../..:webrtc_common",
- "../../:typedefs",
"../../api/audio:audio_frame_api",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
diff --git a/audio/utility/audio_frame_operations.h b/audio/utility/audio_frame_operations.h
index 65a2bad..5993523 100644
--- a/audio/utility/audio_frame_operations.h
+++ b/audio/utility/audio_frame_operations.h
@@ -14,7 +14,6 @@
#include <stddef.h>
#include "api/audio/audio_frame.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn
index 57cf699..50bd0f4 100644
--- a/common_audio/BUILD.gn
+++ b/common_audio/BUILD.gn
@@ -10,14 +10,6 @@
visibility = [ ":*" ]
-config("common_audio_config") {
- include_dirs = [
- "resampler/include",
- "signal_processing/include",
- "vad/include",
- ]
-}
-
rtc_static_library("common_audio") {
visibility += [ "*" ]
sources = [
@@ -60,17 +52,17 @@
deps = [
":common_audio_c",
- ":fft4g",
":sinc_resampler",
"..:webrtc_common",
- "../:typedefs",
"../rtc_base:checks",
"../rtc_base:gtest_prod",
"../rtc_base:rtc_base_approved",
"../rtc_base/memory:aligned_array",
"../rtc_base/memory:aligned_malloc",
+ "../rtc_base/system:arch",
"../system_wrappers",
"../system_wrappers:cpu_features_api",
+ "third_party/fft4g:fft4g",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -80,8 +72,6 @@
deps += [ ":common_audio_neon" ]
}
- public_configs = [ ":common_audio_config" ]
-
if (current_cpu == "x86" || current_cpu == "x64") {
deps += [ ":common_audio_sse2" ]
}
@@ -104,10 +94,7 @@
sources = []
deps = []
if (current_cpu == "arm") {
- sources += [
- "signal_processing/complex_bit_reverse_arm.S",
- "signal_processing/spl_sqrt_floor_arm.S",
- ]
+ sources += [ "signal_processing/complex_bit_reverse_arm.S" ]
if (arm_version >= 7) {
sources += [ "signal_processing/filter_ar_fast_q12_armv7.S" ]
@@ -180,7 +167,6 @@
"signal_processing/include/spl_inl_mips.h",
"signal_processing/min_max_operations_mips.c",
"signal_processing/resample_by_2_mips.c",
- "signal_processing/spl_sqrt_floor_mips.c",
]
if (mips_dsp_rev > 0) {
sources += [ "signal_processing/vector_scaling_operations_mips.c" ]
@@ -193,31 +179,22 @@
sources += [
"signal_processing/complex_bit_reverse.c",
"signal_processing/filter_ar_fast_q12.c",
- "signal_processing/spl_sqrt_floor.c",
]
}
- public_configs = [ ":common_audio_config" ]
deps = [
":common_audio_c_arm_asm",
":common_audio_cc",
- ":fft4g",
"..:webrtc_common",
- "../:typedefs",
"../rtc_base:checks",
"../rtc_base:compile_assert_c",
"../rtc_base:rtc_base_approved",
"../rtc_base:sanitizer",
+ "../rtc_base/system:arch",
"../system_wrappers",
"../system_wrappers:cpu_features_api",
- ]
-}
-
-rtc_source_set("fft4g") {
- visibility += webrtc_default_visibility
- sources = [
- "fft4g.c",
- "fft4g.h",
+ "third_party/fft4g:fft4g",
+ "third_party/spl_sqrt_floor",
]
}
@@ -227,10 +204,8 @@
"signal_processing/dot_product_with_scale.h",
]
- public_configs = [ ":common_audio_config" ]
deps = [
"..:webrtc_common",
- "../:typedefs",
"../rtc_base:rtc_base_approved",
"../system_wrappers",
]
@@ -242,10 +217,10 @@
]
deps = [
"..:webrtc_common",
- "../:typedefs",
"../rtc_base:gtest_prod",
"../rtc_base:rtc_base_approved",
"../rtc_base/memory:aligned_malloc",
+ "../rtc_base/system:arch",
"../system_wrappers",
]
}
@@ -269,6 +244,7 @@
":fir_filter",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
+ "../rtc_base/system:arch",
"../system_wrappers:cpu_features_api",
]
if (current_cpu == "x86" || current_cpu == "x64") {
@@ -310,9 +286,7 @@
]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags = [ "-mfpu=neon" ]
}
@@ -345,9 +319,7 @@
]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags = [ "-mfpu=neon" ]
}
@@ -365,6 +337,7 @@
":common_audio_c",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
+ "../rtc_base/system:arch",
]
}
}
@@ -416,10 +389,10 @@
":fir_filter_factory",
":sinc_resampler",
"..:webrtc_common",
- "../:typedefs",
"../rtc_base:checks",
"../rtc_base:rtc_base_approved",
"../rtc_base:rtc_base_tests_utils",
+ "../rtc_base/system:arch",
"../system_wrappers:cpu_features_api",
"../test:fileutils",
"../test:test_main",
diff --git a/common_audio/audio_util.cc b/common_audio/audio_util.cc
index b442a14..735ba5f 100644
--- a/common_audio/audio_util.cc
+++ b/common_audio/audio_util.cc
@@ -10,8 +10,6 @@
#include "common_audio/include/audio_util.h"
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
void FloatToS16(const float* src, size_t size, int16_t* dest) {
diff --git a/common_audio/audio_util_unittest.cc b/common_audio/audio_util_unittest.cc
index 230669e..cf85a2d 100644
--- a/common_audio/audio_util_unittest.cc
+++ b/common_audio/audio_util_unittest.cc
@@ -13,7 +13,6 @@
#include "rtc_base/arraysize.h"
#include "test/gmock.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/common_audio/fir_filter_factory.cc b/common_audio/fir_filter_factory.cc
index c15c2e0..3243b27 100644
--- a/common_audio/fir_filter_factory.cc
+++ b/common_audio/fir_filter_factory.cc
@@ -12,6 +12,7 @@
#include "common_audio/fir_filter_c.h"
#include "rtc_base/checks.h"
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#if defined(WEBRTC_HAS_NEON)
diff --git a/common_audio/include/audio_util.h b/common_audio/include/audio_util.h
index e4ea9a1..de242a4 100644
--- a/common_audio/include/audio_util.h
+++ b/common_audio/include/audio_util.h
@@ -17,7 +17,6 @@
#include <limits>
#include "rtc_base/checks.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/common_audio/module.mk b/common_audio/module.mk
index 65acd74..dab66c1 100644
--- a/common_audio/module.mk
+++ b/common_audio/module.mk
@@ -32,7 +32,7 @@
# TODO(hychao): figure out if common_audio/real_fourier_openmax.o
# is needed. Build it requires linking openmax dl library.
common_audio_c_C_OBJECTS = \
- common_audio/fft4g.o \
+ common_audio/third_party/fft4g/fft4g.o \
common_audio/ring_buffer.o \
common_audio/signal_processing/auto_corr_to_refl_coef.o \
common_audio/signal_processing/auto_correlation.o \
@@ -71,7 +71,7 @@
common_audio/signal_processing/complex_fft.o \
common_audio/signal_processing/complex_bit_reverse.o \
common_audio/signal_processing/filter_ar_fast_q12.o \
- common_audio/signal_processing/spl_sqrt_floor.o
+ common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.o
ifeq (${USE_NEON},1)
common_audio_CXX_OBJECTS += \
diff --git a/common_audio/real_fourier_ooura.cc b/common_audio/real_fourier_ooura.cc
index db65d26..89694c1 100644
--- a/common_audio/real_fourier_ooura.cc
+++ b/common_audio/real_fourier_ooura.cc
@@ -13,7 +13,7 @@
#include <algorithm>
#include <cmath>
-#include "common_audio/fft4g.h"
+#include "common_audio/third_party/fft4g/fft4g.h"
#include "rtc_base/checks.h"
namespace webrtc {
diff --git a/common_audio/resampler/include/push_resampler.h b/common_audio/resampler/include/push_resampler.h
index 05b93d1..082cdc6 100644
--- a/common_audio/resampler/include/push_resampler.h
+++ b/common_audio/resampler/include/push_resampler.h
@@ -13,8 +13,6 @@
#include <memory>
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
class PushSincResampler;
diff --git a/common_audio/resampler/include/resampler.h b/common_audio/resampler/include/resampler.h
index f923b46..04c487b 100644
--- a/common_audio/resampler/include/resampler.h
+++ b/common_audio/resampler/include/resampler.h
@@ -16,8 +16,7 @@
#define COMMON_AUDIO_RESAMPLER_INCLUDE_RESAMPLER_H_
#include <stddef.h>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
namespace webrtc {
diff --git a/common_audio/resampler/push_sinc_resampler.h b/common_audio/resampler/push_sinc_resampler.h
index ad51471..1ffe73f 100644
--- a/common_audio/resampler/push_sinc_resampler.h
+++ b/common_audio/resampler/push_sinc_resampler.h
@@ -15,7 +15,6 @@
#include "common_audio/resampler/sinc_resampler.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/common_audio/resampler/push_sinc_resampler_unittest.cc b/common_audio/resampler/push_sinc_resampler_unittest.cc
index 487a09f..2f53a74 100644
--- a/common_audio/resampler/push_sinc_resampler_unittest.cc
+++ b/common_audio/resampler/push_sinc_resampler_unittest.cc
@@ -19,7 +19,6 @@
#include "rtc_base/timeutils.h"
#include "test/gmock.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/common_audio/resampler/sinc_resampler.cc b/common_audio/resampler/sinc_resampler.cc
index c3d1ea4..5aa2061 100644
--- a/common_audio/resampler/sinc_resampler.cc
+++ b/common_audio/resampler/sinc_resampler.cc
@@ -93,8 +93,8 @@
#include <limits>
#include "rtc_base/checks.h"
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/common_audio/resampler/sinc_resampler.h b/common_audio/resampler/sinc_resampler.h
index 6306bc9..8a833ce 100644
--- a/common_audio/resampler/sinc_resampler.h
+++ b/common_audio/resampler/sinc_resampler.h
@@ -19,7 +19,7 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/gtest_prod_util.h"
#include "rtc_base/memory/aligned_malloc.h"
-#include "typedefs.h" // NOLINT(build/include)
+#include "rtc_base/system/arch.h"
namespace webrtc {
diff --git a/common_audio/resampler/sinc_resampler_unittest.cc b/common_audio/resampler/sinc_resampler_unittest.cc
index 90bdf31..eb5424d 100644
--- a/common_audio/resampler/sinc_resampler_unittest.cc
+++ b/common_audio/resampler/sinc_resampler_unittest.cc
@@ -23,6 +23,7 @@
#include "common_audio/resampler/sinc_resampler.h"
#include "common_audio/resampler/sinusoidal_linear_chirp_source.h"
#include "rtc_base/stringize_macros.h"
+#include "rtc_base/system/arch.h"
#include "rtc_base/timeutils.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gmock.h"
diff --git a/common_audio/signal_processing/complex_fft.c b/common_audio/signal_processing/complex_fft.c
index e2ac206..ddc9a97 100644
--- a/common_audio/signal_processing/complex_fft.c
+++ b/common_audio/signal_processing/complex_fft.c
@@ -17,6 +17,7 @@
#include "common_audio/signal_processing/complex_fft_tables.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "rtc_base/system/arch.h"
#define CFFTSFT 14
#define CFFTRND 1
diff --git a/common_audio/signal_processing/complex_fft_tables.h b/common_audio/signal_processing/complex_fft_tables.h
index 5171040..90fac07 100644
--- a/common_audio/signal_processing/complex_fft_tables.h
+++ b/common_audio/signal_processing/complex_fft_tables.h
@@ -11,7 +11,7 @@
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
static const int16_t kSinTable1024[] = {
0, 201, 402, 603, 804, 1005, 1206, 1406, 1607,
diff --git a/common_audio/signal_processing/cross_correlation_neon.c b/common_audio/signal_processing/cross_correlation_neon.c
index fdd03f1..f2afbdf 100644
--- a/common_audio/signal_processing/cross_correlation_neon.c
+++ b/common_audio/signal_processing/cross_correlation_neon.c
@@ -9,6 +9,7 @@
*/
#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "rtc_base/system/arch.h"
#include <arm_neon.h>
diff --git a/common_audio/signal_processing/dot_product_with_scale.h b/common_audio/signal_processing/dot_product_with_scale.h
index ff3c525..bb892d4 100644
--- a/common_audio/signal_processing/dot_product_with_scale.h
+++ b/common_audio/signal_processing/dot_product_with_scale.h
@@ -11,10 +11,9 @@
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
+#include <stdint.h>
#include <string.h>
-#include "typedefs.h" // NOLINT(build/include)
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/common_audio/signal_processing/include/real_fft.h b/common_audio/signal_processing/include/real_fft.h
index 8da243d..8445066 100644
--- a/common_audio/signal_processing/include/real_fft.h
+++ b/common_audio/signal_processing/include/real_fft.h
@@ -11,7 +11,7 @@
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
// For ComplexFFT(), the maximum fft order is 10;
// WebRTC APM uses orders of only 7 and 8.
diff --git a/common_audio/signal_processing/include/signal_processing_library.h b/common_audio/signal_processing/include/signal_processing_library.h
index 4d6edbf..33469d4 100644
--- a/common_audio/signal_processing/include/signal_processing_library.h
+++ b/common_audio/signal_processing/include/signal_processing_library.h
@@ -19,7 +19,6 @@
#include <string.h>
#include "common_audio/signal_processing/dot_product_with_scale.h"
-#include "typedefs.h" // NOLINT(build/include)
// Macros specific for the fixed point implementation
#define WEBRTC_SPL_WORD16_MAX 32767
@@ -97,6 +96,9 @@
// inline functions:
#include "common_audio/signal_processing/include/spl_inl.h"
+// third party math functions
+#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
+
// Initialize SPL. Currently it contains only function pointer initialization.
// If the underlying platform is known to be ARM-Neon (WEBRTC_HAS_NEON defined),
// the pointers will be assigned to code optimized for Neon; otherwise, generic
@@ -574,7 +576,6 @@
// Math functions
int32_t WebRtcSpl_Sqrt(int32_t value);
-int32_t WebRtcSpl_SqrtFloor(int32_t value);
// Divisions. Implementations collected in division_operations.c and
// descriptions at bottom of this file.
@@ -1336,23 +1337,6 @@
//
//
-// WebRtcSpl_SqrtFloor(...)
-//
-// Returns the square root of the input value |value|. The precision of this
-// function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer.
-// If |value| is a negative number then 0 is returned.
-//
-// Algorithm:
-//
-// An iterative 4 cylce/bit routine
-//
-// Input:
-// - value : Value to calculate sqrt of
-//
-// Return value : Result of the sqrt calculation
-//
-
-//
// WebRtcSpl_DivU32U16(...)
//
// Divides a uint32_t |num| by a uint16_t |den|.
diff --git a/common_audio/signal_processing/real_fft_unittest.cc b/common_audio/signal_processing/real_fft_unittest.cc
index 2d6b7d1..3b43123 100644
--- a/common_audio/signal_processing/real_fft_unittest.cc
+++ b/common_audio/signal_processing/real_fft_unittest.cc
@@ -11,7 +11,6 @@
#include "common_audio/signal_processing/include/real_fft.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/common_audio/signal_processing/resample_by_2_internal.h b/common_audio/signal_processing/resample_by_2_internal.h
index 5483e2e..145395a 100644
--- a/common_audio/signal_processing/resample_by_2_internal.h
+++ b/common_audio/signal_processing/resample_by_2_internal.h
@@ -16,7 +16,7 @@
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/*******************************************************************
* resample_by_2_fast.c
diff --git a/common_audio/third_party/fft4g/BUILD.gn b/common_audio/third_party/fft4g/BUILD.gn
new file mode 100644
index 0000000..ae0d5f6
--- /dev/null
+++ b/common_audio/third_party/fft4g/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("fft4g") {
+ sources = [
+ "fft4g.c",
+ "fft4g.h",
+ ]
+}
diff --git a/common_audio/third_party/fft4g/LICENSE b/common_audio/third_party/fft4g/LICENSE
new file mode 100644
index 0000000..3bf870a
--- /dev/null
+++ b/common_audio/third_party/fft4g/LICENSE
@@ -0,0 +1,8 @@
+/*
+ * http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html
+ * Copyright Takuya OOURA, 1996-2001
+ *
+ * You may use, copy, modify and distribute this code for any purpose (include
+ * commercial use) and without fee. Please refer to this package when you modify
+ * this code.
+ */
diff --git a/common_audio/third_party/fft4g/README.chromium b/common_audio/third_party/fft4g/README.chromium
new file mode 100644
index 0000000..9df2ddb
--- /dev/null
+++ b/common_audio/third_party/fft4g/README.chromium
@@ -0,0 +1,13 @@
+Name: General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package
+Short Name: fft4g
+URL: http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html
+Version: 0
+Date: 2018-06-19
+License: Custome license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+This is a package to calculate Discrete Fourier/Cosine/Sine Transforms of
+1-dimensional sequences of length 2^N. This package contains C and Fortran
+FFT codes.
diff --git a/common_audio/fft4g.c b/common_audio/third_party/fft4g/fft4g.c
similarity index 100%
rename from common_audio/fft4g.c
rename to common_audio/third_party/fft4g/fft4g.c
diff --git a/common_audio/fft4g.h b/common_audio/third_party/fft4g/fft4g.h
similarity index 61%
rename from common_audio/fft4g.h
rename to common_audio/third_party/fft4g/fft4g.h
index 1750e27..f1f31a1 100644
--- a/common_audio/fft4g.h
+++ b/common_audio/third_party/fft4g/fft4g.h
@@ -1,15 +1,15 @@
/*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ * Copyright (c) 2018 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
+ * 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 COMMON_AUDIO_FFT4G_H_
-#define COMMON_AUDIO_FFT4G_H_
+#ifndef COMMON_AUDIO_THIRD_PARTY_FFT4G_FFT4G_H_
+#define COMMON_AUDIO_THIRD_PARTY_FFT4G_FFT4G_H_
#if defined(__cplusplus)
extern "C" {
@@ -22,4 +22,4 @@
}
#endif
-#endif // COMMON_AUDIO_FFT4G_H_
+#endif /* COMMON_AUDIO_THIRD_PARTY_FFT4G_FFT4G_H_ */
diff --git a/common_audio/third_party/fft4g/module.mk b/common_audio/third_party/fft4g/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/common_audio/third_party/fft4g/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/common_audio/third_party/module.mk b/common_audio/third_party/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/common_audio/third_party/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/common_audio/third_party/spl_sqrt_floor/BUILD.gn b/common_audio/third_party/spl_sqrt_floor/BUILD.gn
new file mode 100644
index 0000000..194899e
--- /dev/null
+++ b/common_audio/third_party/spl_sqrt_floor/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("spl_sqrt_floor") {
+ visibility = [ "../..:common_audio_c" ]
+ sources = [
+ "spl_sqrt_floor.h",
+ ]
+ deps = []
+ if (current_cpu == "arm") {
+ sources += [ "spl_sqrt_floor_arm.S" ]
+
+ deps += [ "../../../rtc_base/system:asm_defines" ]
+ } else if (current_cpu == "mipsel") {
+ sources += [ "spl_sqrt_floor_mips.c" ]
+ } else {
+ sources += [ "spl_sqrt_floor.c" ]
+ }
+}
diff --git a/common_audio/third_party/spl_sqrt_floor/LICENSE b/common_audio/third_party/spl_sqrt_floor/LICENSE
new file mode 100644
index 0000000..fdf17a2
--- /dev/null
+++ b/common_audio/third_party/spl_sqrt_floor/LICENSE
@@ -0,0 +1,27 @@
+/*
+ * Written by Wilco Dijkstra, 1996. The following email exchange establishes the
+ * license.
+ *
+ * From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
+ * Date: Fri, Jun 24, 2011 at 3:20 AM
+ * Subject: Re: sqrt routine
+ * To: Kevin Ma <kma@google.com>
+ * Hi Kevin,
+ * Thanks for asking. Those routines are public domain (originally posted to
+ * comp.sys.arm a long time ago), so you can use them freely for any purpose.
+ * Cheers,
+ * Wilco
+ *
+ * ----- Original Message -----
+ * From: "Kevin Ma" <kma@google.com>
+ * To: <Wilco.Dijkstra@ntlworld.com>
+ * Sent: Thursday, June 23, 2011 11:44 PM
+ * Subject: Fwd: sqrt routine
+ * Hi Wilco,
+ * I saw your sqrt routine from several web sites, including
+ * http://www.finesse.demon.co.uk/steven/sqrt.html.
+ * Just wonder if there's any copyright information with your Successive
+ * approximation routines, or if I can freely use it for any purpose.
+ * Thanks.
+ * Kevin
+ */
diff --git a/common_audio/third_party/spl_sqrt_floor/README.chromium b/common_audio/third_party/spl_sqrt_floor/README.chromium
new file mode 100644
index 0000000..b226490
--- /dev/null
+++ b/common_audio/third_party/spl_sqrt_floor/README.chromium
@@ -0,0 +1,12 @@
+Name: sql sqrt floor
+Short Name: sql_sqrt_floor
+URL: http://www.pertinentdetail.org/sqrt
+Version: 0
+Date: 2018-03-22
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+Sqrt routine, originally was posted to the USENET group comp.sys.arm on
+20 Jun 1996.
diff --git a/common_audio/third_party/spl_sqrt_floor/module.mk b/common_audio/third_party/spl_sqrt_floor/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/common_audio/third_party/spl_sqrt_floor/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/common_audio/signal_processing/spl_sqrt_floor.c b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c
similarity index 96%
rename from common_audio/signal_processing/spl_sqrt_floor.c
rename to common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c
index 7141386..b478a41 100644
--- a/common_audio/signal_processing/spl_sqrt_floor.c
+++ b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c
@@ -28,7 +28,7 @@
// Minor modifications in code style for WebRTC, 2012.
-#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
/*
* Algorithm:
diff --git a/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h
new file mode 100644
index 0000000..eaa58e3
--- /dev/null
+++ b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 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 <stdint.h>
+
+//
+// WebRtcSpl_SqrtFloor(...)
+//
+// Returns the square root of the input value |value|. The precision of this
+// function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer.
+// If |value| is a negative number then 0 is returned.
+//
+// Algorithm:
+//
+// An iterative 4 cylce/bit routine
+//
+// Input:
+// - value : Value to calculate sqrt of
+//
+// Return value : Result of the sqrt calculation
+//
+int32_t WebRtcSpl_SqrtFloor(int32_t value);
diff --git a/common_audio/signal_processing/spl_sqrt_floor_arm.S b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_arm.S
similarity index 100%
rename from common_audio/signal_processing/spl_sqrt_floor_arm.S
rename to common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_arm.S
diff --git a/common_audio/signal_processing/spl_sqrt_floor_mips.c b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_mips.c
similarity index 98%
rename from common_audio/signal_processing/spl_sqrt_floor_mips.c
rename to common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_mips.c
index 7128fbd..04033c1 100644
--- a/common_audio/signal_processing/spl_sqrt_floor_mips.c
+++ b/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor_mips.c
@@ -29,7 +29,7 @@
// Minor modifications in code style for WebRTC, 2012.
// Code optimizations for MIPS, 2013.
-#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
/*
* Algorithm:
diff --git a/common_audio/vad/include/vad.h b/common_audio/vad/include/vad.h
index bd10756..b15275b 100644
--- a/common_audio/vad/include/vad.h
+++ b/common_audio/vad/include/vad.h
@@ -15,7 +15,6 @@
#include "common_audio/vad/include/webrtc_vad.h"
#include "rtc_base/checks.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/common_audio/vad/include/webrtc_vad.h b/common_audio/vad/include/webrtc_vad.h
index a6c539c..f5bbadf 100644
--- a/common_audio/vad/include/webrtc_vad.h
+++ b/common_audio/vad/include/webrtc_vad.h
@@ -17,8 +17,7 @@
#define COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_
#include <stddef.h>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
typedef struct WebRtcVadInst VadInst;
diff --git a/common_audio/vad/vad_core.c b/common_audio/vad/vad_core.c
index 7316b45..55927ce 100644
--- a/common_audio/vad/vad_core.c
+++ b/common_audio/vad/vad_core.c
@@ -15,7 +15,6 @@
#include "common_audio/vad/vad_filterbank.h"
#include "common_audio/vad/vad_gmm.h"
#include "common_audio/vad/vad_sp.h"
-#include "typedefs.h" // NOLINT(build/include)
// Spectrum Weighting
static const int16_t kSpectrumWeight[kNumChannels] = { 6, 8, 10, 12, 14, 16 };
diff --git a/common_audio/vad/vad_core.h b/common_audio/vad/vad_core.h
index 0eb8de3..e79696c 100644
--- a/common_audio/vad/vad_core.h
+++ b/common_audio/vad/vad_core.h
@@ -16,7 +16,6 @@
#define COMMON_AUDIO_VAD_VAD_CORE_H_
#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "typedefs.h" // NOLINT(build/include)
enum { kNumChannels = 6 }; // Number of frequency bands (named channels).
enum { kNumGaussians = 2 }; // Number of Gaussians per channel in the GMM.
diff --git a/common_audio/vad/vad_core_unittest.cc b/common_audio/vad/vad_core_unittest.cc
index 0587878..3131a86 100644
--- a/common_audio/vad/vad_core_unittest.cc
+++ b/common_audio/vad/vad_core_unittest.cc
@@ -12,7 +12,6 @@
#include "common_audio/vad/vad_unittest.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
extern "C" {
#include "common_audio/vad/vad_core.h"
diff --git a/common_audio/vad/vad_filterbank.c b/common_audio/vad/vad_filterbank.c
index 82cff25..1513153 100644
--- a/common_audio/vad/vad_filterbank.c
+++ b/common_audio/vad/vad_filterbank.c
@@ -12,7 +12,6 @@
#include "rtc_base/checks.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "typedefs.h" // NOLINT(build/include)
// Constants used in LogOfEnergy().
static const int16_t kLogConst = 24660; // 160*log10(2) in Q9.
diff --git a/common_audio/vad/vad_filterbank.h b/common_audio/vad/vad_filterbank.h
index 60b785b..53bbbe1 100644
--- a/common_audio/vad/vad_filterbank.h
+++ b/common_audio/vad/vad_filterbank.h
@@ -16,7 +16,6 @@
#define COMMON_AUDIO_VAD_VAD_FILTERBANK_H_
#include "common_audio/vad/vad_core.h"
-#include "typedefs.h" // NOLINT(build/include)
// Takes |data_length| samples of |data_in| and calculates the logarithm of the
// energy of each of the |kNumChannels| = 6 frequency bands used by the VAD:
diff --git a/common_audio/vad/vad_filterbank_unittest.cc b/common_audio/vad/vad_filterbank_unittest.cc
index b800044..51d8d0f 100644
--- a/common_audio/vad/vad_filterbank_unittest.cc
+++ b/common_audio/vad/vad_filterbank_unittest.cc
@@ -12,7 +12,6 @@
#include "common_audio/vad/vad_unittest.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
extern "C" {
#include "common_audio/vad/vad_core.h"
diff --git a/common_audio/vad/vad_gmm.c b/common_audio/vad/vad_gmm.c
index b746fd5..ddc87b6 100644
--- a/common_audio/vad/vad_gmm.c
+++ b/common_audio/vad/vad_gmm.c
@@ -11,7 +11,6 @@
#include "common_audio/vad/vad_gmm.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "typedefs.h" // NOLINT(build/include)
static const int32_t kCompVar = 22005;
static const int16_t kLog2Exp = 5909; // log2(exp(1)) in Q12.
diff --git a/common_audio/vad/vad_gmm.h b/common_audio/vad/vad_gmm.h
index 79f15c8..6b2d11b 100644
--- a/common_audio/vad/vad_gmm.h
+++ b/common_audio/vad/vad_gmm.h
@@ -13,7 +13,7 @@
#ifndef COMMON_AUDIO_VAD_VAD_GMM_H_
#define COMMON_AUDIO_VAD_VAD_GMM_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
// Calculates the probability for |input|, given that |input| comes from a
// normal distribution with mean and standard deviation (|mean|, |std|).
diff --git a/common_audio/vad/vad_gmm_unittest.cc b/common_audio/vad/vad_gmm_unittest.cc
index e77603d..be61f7f 100644
--- a/common_audio/vad/vad_gmm_unittest.cc
+++ b/common_audio/vad/vad_gmm_unittest.cc
@@ -10,7 +10,6 @@
#include "common_audio/vad/vad_unittest.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
extern "C" {
#include "common_audio/vad/vad_gmm.h"
diff --git a/common_audio/vad/vad_sp.c b/common_audio/vad/vad_sp.c
index 915fb37..d367c8b 100644
--- a/common_audio/vad/vad_sp.c
+++ b/common_audio/vad/vad_sp.c
@@ -13,7 +13,6 @@
#include "rtc_base/checks.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "common_audio/vad/vad_core.h"
-#include "typedefs.h" // NOLINT(build/include)
// Allpass filter coefficients, upper and lower, in Q13.
// Upper: 0.64, Lower: 0.17.
diff --git a/common_audio/vad/vad_sp.h b/common_audio/vad/vad_sp.h
index 8586ccd..ff36760 100644
--- a/common_audio/vad/vad_sp.h
+++ b/common_audio/vad/vad_sp.h
@@ -14,7 +14,6 @@
#define COMMON_AUDIO_VAD_VAD_SP_H_
#include "common_audio/vad/vad_core.h"
-#include "typedefs.h" // NOLINT(build/include)
// Downsamples the signal by a factor 2, eg. 32->16 or 16->8.
//
diff --git a/common_audio/vad/vad_sp_unittest.cc b/common_audio/vad/vad_sp_unittest.cc
index ebe25cf..cdde56d 100644
--- a/common_audio/vad/vad_sp_unittest.cc
+++ b/common_audio/vad/vad_sp_unittest.cc
@@ -12,7 +12,6 @@
#include "common_audio/vad/vad_unittest.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
extern "C" {
#include "common_audio/vad/vad_core.h"
diff --git a/common_audio/vad/vad_unittest.cc b/common_audio/vad/vad_unittest.cc
index 1cef8e9..c54014e 100644
--- a/common_audio/vad/vad_unittest.cc
+++ b/common_audio/vad/vad_unittest.cc
@@ -17,7 +17,6 @@
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
VadTest::VadTest() {}
diff --git a/common_audio/vad/vad_unittest.h b/common_audio/vad/vad_unittest.h
index 5521983..ee64206 100644
--- a/common_audio/vad/vad_unittest.h
+++ b/common_audio/vad/vad_unittest.h
@@ -14,7 +14,6 @@
#include <stddef.h> // size_t
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/common_audio/vad/webrtc_vad.c b/common_audio/vad/webrtc_vad.c
index 7fc4d65..d8457ee 100644
--- a/common_audio/vad/webrtc_vad.c
+++ b/common_audio/vad/webrtc_vad.c
@@ -15,7 +15,6 @@
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "common_audio/vad/vad_core.h"
-#include "typedefs.h" // NOLINT(build/include)
static const int kInitCheck = 42;
static const int kValidRates[] = { 8000, 16000, 32000, 48000 };
diff --git a/common_audio/wav_file.cc b/common_audio/wav_file.cc
index 21b64a8..008891f 100644
--- a/common_audio/wav_file.cc
+++ b/common_audio/wav_file.cc
@@ -19,6 +19,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
diff --git a/common_audio/wav_header.cc b/common_audio/wav_header.cc
index d093fa0..8fc5fef 100644
--- a/common_audio/wav_header.cc
+++ b/common_audio/wav_header.cc
@@ -21,6 +21,7 @@
#include "common_audio/include/audio_util.h"
#include "rtc_base/checks.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
namespace {
diff --git a/common_types.h b/common_types.h
index 919a947..60d88b3 100644
--- a/common_types.h
+++ b/common_types.h
@@ -21,7 +21,6 @@
#include "api/video/video_bitrate_allocation.h"
#include "rtc_base/checks.h"
#include "rtc_base/deprecation.h"
-#include "typedefs.h" // NOLINT(build/include)
#if defined(_MSC_VER)
// Disable "new behavior: elements of array will be default initialized"
@@ -60,14 +59,8 @@
jitter(0) {}
uint8_t fraction_lost;
- union {
- int32_t packets_lost; // Defined as a 24 bit signed integer in RTCP
- RTC_DEPRECATED uint32_t cumulative_lost;
- };
- union {
- uint32_t extended_highest_sequence_number;
- RTC_DEPRECATED uint32_t extended_max_sequence_number;
- };
+ int32_t packets_lost; // Defined as a 24 bit signed integer in RTCP
+ uint32_t extended_highest_sequence_number;
uint32_t jitter;
};
@@ -340,21 +333,13 @@
// Video codec types
enum VideoCodecType {
// There are various memset(..., 0, ...) calls in the code that rely on
- // kVideoCodecUnknown being zero.
- kVideoCodecUnknown = 0,
+ // kVideoCodecGeneric being zero.
+ kVideoCodecGeneric = 0,
kVideoCodecVP8,
kVideoCodecVP9,
kVideoCodecH264,
kVideoCodecI420,
- kVideoCodecGeneric,
kVideoCodecMultiplex,
-
- // TODO(nisse): Deprecated aliases, for code expecting RtpVideoCodecTypes.
- kRtpVideoNone = kVideoCodecUnknown,
- kRtpVideoGeneric = kVideoCodecGeneric,
- kRtpVideoVp8 = kVideoCodecVP8,
- kRtpVideoVp9 = kVideoCodecVP9,
- kRtpVideoH264 = kVideoCodecH264,
};
// Translates from name of codec to codec type and vice versa.
@@ -367,6 +352,7 @@
unsigned short width;
unsigned short height;
+ float maxFramerate; // fps.
unsigned char numberOfTemporalLayers;
unsigned int maxBitrate; // kilobits/sec.
unsigned int targetBitrate; // kilobits/sec.
@@ -410,21 +396,6 @@
double initial_var_noise;
};
-// This structure will have the information about when packet is actually
-// received by socket.
-struct PacketTime {
- PacketTime() : timestamp(-1), not_before(-1) {}
- PacketTime(int64_t timestamp, int64_t not_before)
- : timestamp(timestamp), not_before(not_before) {}
-
- int64_t timestamp; // Receive time after socket delivers the data.
- int64_t not_before; // Earliest possible time the data could have arrived,
- // indicating the potential error in the |timestamp|
- // value,in case the system is busy.
- // For example, the time of the last select() call.
- // If unknown, this value will be set to zero.
-};
-
// Minimum and maximum playout delay values from capture to render.
// These are best effort values.
//
diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn
index 82cde8e..de2aeb7 100644
--- a/modules/audio_coding/BUILD.gn
+++ b/modules/audio_coding/BUILD.gn
@@ -66,7 +66,6 @@
"acm2/rent_a_codec.h",
]
deps = [
- "../..:typedefs",
"../../rtc_base:checks",
"../../api:array_view",
"//third_party/abseil-cpp/absl/types:optional",
@@ -84,19 +83,11 @@
defines = audio_codec_defines
}
-config("audio_coding_config") {
- include_dirs = [
- "include",
- "../include",
- ]
-}
-
rtc_source_set("audio_coding_module_typedefs") {
sources = [
"include/audio_coding_module_typedefs.h",
]
deps = [
- "../..:typedefs",
"../..:webrtc_common",
]
}
@@ -119,8 +110,6 @@
defines = []
- public_configs = [ ":audio_coding_config" ]
-
if (rtc_include_opus) {
public_deps = [
":webrtc_opus",
@@ -131,7 +120,6 @@
"../../api/audio:audio_frame_api",
"..:module_api",
"../../common_audio:common_audio_c",
- "../..:typedefs",
"../../rtc_base:deprecation",
"../../rtc_base:checks",
"../../system_wrappers:metrics_api",
@@ -160,10 +148,6 @@
]
}
-config("cng_config") {
- include_dirs = [ "codecs/cng/include" ]
-}
-
rtc_static_library("cng") {
visibility += [ "*" ]
sources = [
@@ -173,10 +157,7 @@
"codecs/cng/webrtc_cng.h",
]
- public_configs = [ ":cng_config" ]
-
deps = [
- "../..:typedefs",
"../..:webrtc_common",
"../../api:array_view",
"../../api/audio_codecs:audio_codecs_api",
@@ -186,10 +167,6 @@
]
}
-config("red_config") {
- include_dirs = [ "codecs/red" ]
-}
-
rtc_static_library("red") {
visibility += [ "*" ]
sources = [
@@ -197,8 +174,6 @@
"codecs/red/audio_encoder_copy_red.h",
]
- public_configs = [ ":red_config" ]
-
deps = [
"../../api/audio_codecs:audio_codecs_api",
"../../common_audio",
@@ -207,10 +182,6 @@
]
}
-config("g711_config") {
- include_dirs = [ "codecs/g711/include" ]
-}
-
rtc_static_library("g711") {
visibility += [ "*" ]
poisonous = [ "audio_codecs" ]
@@ -221,8 +192,6 @@
"codecs/g711/audio_encoder_pcm.h",
]
- public_configs = [ ":g711_config" ]
-
deps = [
":legacy_encoded_audio_frame",
"../..:webrtc_common",
@@ -242,24 +211,11 @@
"codecs/g711/g711_interface.h",
]
deps = [
- ":g711_3p",
- "../..:typedefs",
"../..:webrtc_common",
+ "../third_party/g711:g711_3p",
]
}
-rtc_source_set("g711_3p") {
- poisonous = [ "audio_codecs" ]
- sources = [
- "codecs/g711/g711.c",
- "codecs/g711/g711.h",
- ]
-}
-
-config("g722_config") {
- include_dirs = [ "codecs/g722/include" ]
-}
-
rtc_static_library("g722") {
visibility += [ "*" ]
poisonous = [ "audio_codecs" ]
@@ -270,8 +226,6 @@
"codecs/g722/audio_encoder_g722.h",
]
- public_configs = [ ":g722_config" ]
-
deps = [
":legacy_encoded_audio_frame",
"../..:webrtc_common",
@@ -292,25 +246,11 @@
"codecs/g722/g722_interface.h",
]
deps = [
- ":g722_3p",
- "../..:typedefs",
"../..:webrtc_common",
+ "../third_party/g722:g722_3p",
]
}
-rtc_source_set("g722_3p") {
- poisonous = [ "audio_codecs" ]
- sources = [
- "codecs/g722/g722_decode.c",
- "codecs/g722/g722_enc_dec.h",
- "codecs/g722/g722_encode.c",
- ]
-}
-
-config("ilbc_config") {
- include_dirs = [ "codecs/ilbc/include" ]
-}
-
rtc_static_library("ilbc") {
visibility += webrtc_default_visibility
poisonous = [ "audio_codecs" ]
@@ -321,8 +261,6 @@
"codecs/ilbc/audio_encoder_ilbc.h",
]
- public_configs = [ ":ilbc_config" ]
-
deps = [
":legacy_encoded_audio_frame",
"../..:webrtc_common",
@@ -481,10 +419,7 @@
"codecs/ilbc/xcorr_coef.h",
]
- public_configs = [ ":ilbc_config" ]
-
deps = [
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio_codecs:audio_codecs_api",
"../../common_audio",
@@ -492,6 +427,8 @@
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:sanitizer",
+ "../../rtc_base/system:arch",
+ "../../rtc_base/system:unused",
]
}
@@ -507,7 +444,6 @@
]
deps = [
":isac_bwinfo",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio_codecs:audio_codecs_api",
"../../rtc_base:checks",
@@ -516,10 +452,6 @@
]
}
-config("isac_config") {
- include_dirs = [ "codecs/isac/main/include" ]
-}
-
rtc_static_library("isac") {
visibility += [ "*" ]
poisonous = [ "audio_codecs" ]
@@ -543,9 +475,7 @@
sources = [
"codecs/isac/bandwidth_info.h",
]
- deps = [
- "../..:typedefs",
- ]
+ deps = []
}
rtc_source_set("isac_vad") {
@@ -565,9 +495,10 @@
]
deps = [
":isac_bwinfo",
- "../..:typedefs",
"../../rtc_base:compile_assert_c",
+ "../../rtc_base/system:arch",
"../../rtc_base/system:ignore_warnings",
+ "../third_party/fft",
]
}
@@ -619,37 +550,20 @@
libs = [ "m" ]
}
- public_configs = [ ":isac_config" ]
-
deps = [
- ":fft",
":isac_bwinfo",
":isac_vad",
- "../..:typedefs",
"../..:webrtc_common",
"../../common_audio",
"../../common_audio:common_audio_c",
"../../rtc_base:checks",
"../../rtc_base:compile_assert_c",
"../../rtc_base:rtc_base_approved",
+ "../../rtc_base/system:arch",
+ "../third_party/fft",
]
}
-rtc_source_set("fft") {
- poisonous = [ "audio_codecs" ]
- sources = [
- "codecs/isac/main/source/fft.c",
- "codecs/isac/main/source/fft.h",
- ]
- deps = [
- ":isac_vad",
- ]
-}
-
-config("isac_fix_config") {
- include_dirs = [ "codecs/isac/fix/include" ]
-}
-
rtc_static_library("isac_fix") {
visibility += [ "*" ]
poisonous = [ "audio_codecs" ]
@@ -658,8 +572,6 @@
"codecs/isac/fix/source/audio_encoder_isacfix.cc",
]
- public_configs = [ ":isac_fix_config" ]
-
deps = [
":isac_common",
"../../api/audio_codecs:audio_codecs_api",
@@ -687,10 +599,8 @@
"codecs/isac/fix/source/structs.h",
"codecs/isac/fix/source/transform_tables.c",
]
- public_configs = [ ":isac_fix_config" ]
deps = [
":isac_bwinfo",
- "../..:typedefs",
"../../common_audio",
"../../common_audio:common_audio_c",
]
@@ -755,12 +665,9 @@
"codecs/isac/fix/source/transform.c",
]
- public_configs = [ ":isac_fix_config" ]
-
deps = [
":isac_bwinfo",
":isac_common",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio_codecs:audio_codecs_api",
"../../common_audio",
@@ -770,6 +677,7 @@
"../../rtc_base:rtc_base_approved",
"../../rtc_base:sanitizer",
"../../system_wrappers:cpu_features_api",
+ "../third_party/fft",
]
public_deps = [
@@ -778,6 +686,13 @@
if (rtc_build_with_neon) {
deps += [ ":isac_neon" ]
+
+ # TODO(bugs.webrtc.org/9579): Consider moving the usage of NEON from
+ # pitch_estimator_c.c into the "isac_neon" target and delete this flag:
+ if (current_cpu != "arm64") {
+ suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
+ cflags = [ "-mfpu=neon" ]
+ }
}
if (current_cpu == "arm" && arm_version >= 7) {
@@ -825,9 +740,7 @@
]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags = [ "-mfpu=neon" ]
}
@@ -851,10 +764,6 @@
}
}
-config("pcm16b_config") {
- include_dirs = [ "codecs/pcm16b/include" ]
-}
-
rtc_static_library("pcm16b") {
visibility += [ "*" ]
poisonous = [ "audio_codecs" ]
@@ -878,7 +787,6 @@
public_deps = [
":pcm16b_c",
]
- public_configs = [ ":pcm16b_config" ]
}
rtc_source_set("pcm16b_c") {
@@ -888,9 +796,7 @@
"codecs/pcm16b/pcm16b.h",
]
- public_configs = [ ":pcm16b_config" ]
deps = [
- "../..:typedefs",
"../..:webrtc_common",
]
}
@@ -952,7 +858,6 @@
}
deps = [
- "../..:typedefs",
"../..:webrtc_common",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
@@ -1140,7 +1045,6 @@
":cng",
":neteq_decoder_enum",
"..:module_api",
- "../..:typedefs",
"../..:webrtc_common",
"../../api:libjingle_peerconnection_api",
"../../api/audio:audio_frame_api",
@@ -1181,14 +1085,8 @@
"neteq/tools/packet_source.h",
]
- if (!build_with_chromium && is_clang) {
- # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
- suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
- }
-
deps = [
":neteq",
- "../..:typedefs",
"../..:webrtc_common",
"../../api:libjingle_peerconnection_api",
"../../api/audio:audio_frame_api",
@@ -1220,8 +1118,6 @@
"neteq/tools/rtp_generator.h",
]
- public_configs = [ ":neteq_tools_config" ]
-
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
@@ -1229,7 +1125,6 @@
deps = [
":pcm16b",
- "../..:typedefs",
"../..:webrtc_common",
"../../api:array_view",
"../../api:libjingle_peerconnection_api",
@@ -1238,6 +1133,7 @@
"../../rtc_base:rtc_base",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_base_tests_utils",
+ "../../rtc_base/system:arch",
"../../test:rtp_test_utils",
"../rtp_rtcp",
"../rtp_rtcp:rtp_rtcp_format",
@@ -1257,10 +1153,6 @@
}
}
-config("neteq_tools_config") {
- include_dirs = [ "tools" ]
-}
-
rtc_source_set("neteq_tools") {
visibility += webrtc_default_visibility
sources = [
@@ -1274,8 +1166,6 @@
"neteq/tools/neteq_stats_getter.h",
]
- public_configs = [ ":neteq_tools_config" ]
-
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
@@ -1283,7 +1173,6 @@
deps = [
"..:module_api",
- "../..:typedefs",
"../..:webrtc_common",
"../../api:array_view",
"../../api/audio_codecs:audio_codecs_api",
@@ -1310,7 +1199,6 @@
]
deps = [
- "../..:typedefs",
"../..:webrtc_common",
"../../common_audio",
"../../rtc_base:checks",
@@ -1436,10 +1324,10 @@
":audio_format_conversion",
":pcm16b_c",
"..:module_api",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio:audio_frame_api",
"../../api/audio_codecs:builtin_audio_decoder_factory",
+ "../../api/audio_codecs:builtin_audio_encoder_factory",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../rtc_base/synchronization:rw_lock_wrapper",
@@ -1466,7 +1354,6 @@
deps = [
":neteq_test_support",
":neteq_test_tools",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio_codecs/opus:audio_encoder_opus",
"../../rtc_base:protobuf_utils",
@@ -1519,8 +1406,10 @@
"../../api/audio:audio_frame_api",
"../../rtc_base:checks",
":audio_coding",
+ ":audio_format_conversion",
":neteq_tools",
"../../api/audio_codecs:builtin_audio_decoder_factory",
+ "../../api/audio_codecs:builtin_audio_encoder_factory",
"../../api/audio_codecs:audio_codecs_api",
"../../rtc_base:rtc_base_approved",
"../../test:test_support",
@@ -1545,7 +1434,6 @@
":audio_coding_module_typedefs",
":audio_format_conversion",
"..:module_api",
- "../..:typedefs",
"../../:webrtc_common",
"../../api/audio:audio_frame_api",
"../../api/audio_codecs:builtin_audio_decoder_factory",
@@ -1580,31 +1468,23 @@
"neteq/audio_decoder_unittest.cc",
]
- if (!build_with_chromium && is_clang) {
- # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
- suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
- }
-
- deps = [
- "../../test:fileutils",
- ]
-
defines = neteq_defines
- deps += audio_coding_deps
- deps += [
- ":ilbc",
- ":isac",
- ":isac_fix",
- ":neteq",
- ":neteq_tools",
- "../../api/audio_codecs:audio_codecs_api",
- "../../api/audio_codecs/opus:audio_encoder_opus",
- "../../common_audio",
- "../../rtc_base:protobuf_utils",
- "../../test:test_main",
- "//testing/gtest",
- ]
+ deps = [
+ ":ilbc",
+ ":isac",
+ ":isac_fix",
+ ":neteq",
+ ":neteq_tools",
+ "../../test:fileutils",
+ "../../api/audio_codecs:audio_codecs_api",
+ "../../api/audio_codecs/opus:audio_encoder_opus",
+ "../../common_audio",
+ "../../rtc_base:protobuf_utils",
+ "../../rtc_base/system:arch",
+ "../../test:test_main",
+ "//testing/gtest",
+ ] + audio_coding_deps
data = audio_decoder_unittests_resources
@@ -1615,7 +1495,7 @@
if (is_ios) {
deps += [ ":audio_decoder_unittests_bundle_data" ]
}
- } # audio_decoder_unittests
+ }
if (rtc_enable_protobuf) {
proto_library("neteq_unittest_proto") {
@@ -1629,8 +1509,8 @@
testonly = true
defines = []
deps = [
- "../..:typedefs",
"../../rtc_base:checks",
+ "../../test:field_trial",
"../../test:fileutils",
]
sources = [
@@ -1673,7 +1553,6 @@
testonly = true
defines = []
deps = [
- "../..:typedefs",
"../../test:fileutils",
]
sources = [
@@ -1732,7 +1611,6 @@
":neteq",
":neteq_test_tools",
":pcm16b",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio:audio_frame_api",
"../../api/audio_codecs:audio_codecs_api",
@@ -1761,7 +1639,6 @@
deps = [
":neteq",
":neteq_test_tools",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio_codecs:builtin_audio_decoder_factory",
"../../rtc_base:checks",
@@ -1777,7 +1654,6 @@
deps = audio_coding_deps + [
"//third_party/abseil-cpp/absl/memory",
- "../..:typedefs",
":audio_coding",
":neteq_input_audio_tools",
"../../api/audio:audio_frame_api",
@@ -1802,7 +1678,6 @@
testonly = true
deps = audio_coding_deps + [
- "../..:typedefs",
"../../system_wrappers:system_wrappers_default",
"../rtp_rtcp:rtp_rtcp_format",
"../../api:array_view",
@@ -1847,11 +1722,6 @@
"../../system_wrappers:system_wrappers_default",
"//testing/gtest",
]
-
- if (!build_with_chromium && is_clang) {
- # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
- suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
- }
}
rtc_executable("neteq_opus_quality_test") {
@@ -1882,7 +1752,6 @@
deps = [
":neteq",
":neteq_test_support",
- "../..:typedefs",
"../..:webrtc_common",
"../../rtc_base:rtc_base_approved",
"../../system_wrappers:system_wrappers_default",
@@ -2001,12 +1870,6 @@
"codecs/isac/main/test/simpleKenny.c",
]
- include_dirs = [
- "codecs/isac/main/include",
- "codecs/isac/main/test",
- "codecs/isac/main/util",
- ]
-
deps = [
":isac",
":isac_test_util",
@@ -2035,7 +1898,6 @@
deps = [
":g722",
- "../..:typedefs",
"../..:webrtc_common",
]
}
@@ -2052,12 +1914,6 @@
":isac_test_util",
"../../rtc_base:rtc_base_approved",
]
-
- include_dirs = [
- "codecs/isac/main/include",
- "codecs/isac/main/test",
- "codecs/isac/main/util",
- ]
}
rtc_executable("isac_switch_samprate_test") {
@@ -2073,13 +1929,6 @@
"../../common_audio",
"../../common_audio:common_audio_c",
]
-
- include_dirs = [
- "codecs/isac/main/include",
- "codecs/isac/main/test",
- "codecs/isac/main/util",
- "../../common_audio/signal_processing/include",
- ]
}
rtc_executable("ilbc_test") {
@@ -2109,11 +1958,6 @@
"../../test:test_main",
"//testing/gtest",
]
-
- if (!build_with_chromium && is_clang) {
- # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
- suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
- }
}
rtc_source_set("audio_coding_unittests") {
@@ -2221,7 +2065,6 @@
":rent_a_codec",
":webrtc_opus",
"..:module_api",
- "../..:typedefs",
"../..:webrtc_common",
"../../api/audio:audio_frame_api",
"../../api/audio_codecs:audio_codecs_api",
@@ -2241,6 +2084,7 @@
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_base_tests_utils",
"../../rtc_base:sanitizer",
+ "../../rtc_base/system:arch",
"../../system_wrappers",
"../../system_wrappers:cpu_features_api",
"../../test:audio_codec_mocks",
diff --git a/modules/audio_coding/acm2/acm_codec_database.h b/modules/audio_coding/acm2/acm_codec_database.h
index 8b7c68a..ee6bb46 100644
--- a/modules/audio_coding/acm2/acm_codec_database.h
+++ b/modules/audio_coding/acm2/acm_codec_database.h
@@ -18,7 +18,6 @@
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/acm2/rent_a_codec.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc
index 0a88e70..892abe5 100644
--- a/modules/audio_coding/acm2/acm_receiver.cc
+++ b/modules/audio_coding/acm2/acm_receiver.cc
@@ -60,10 +60,6 @@
return -1;
}
-int AcmReceiver::LeastRequiredDelayMs() const {
- return neteq_->LeastRequiredDelayMs();
-}
-
absl::optional<int> AcmReceiver::last_packet_sample_rate_hz() const {
rtc::CritScope lock(&crit_sect_);
return last_packet_sample_rate_hz_;
diff --git a/modules/audio_coding/acm2/acm_receiver.h b/modules/audio_coding/acm2/acm_receiver.h
index c0afbb1..0731677 100644
--- a/modules/audio_coding/acm2/acm_receiver.h
+++ b/modules/audio_coding/acm2/acm_receiver.h
@@ -26,7 +26,6 @@
#include "modules/audio_coding/neteq/include/neteq.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/thread_annotations.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -144,13 +143,6 @@
int SetMaximumDelay(int delay_ms);
//
- // Get least required delay computed based on channel conditions. Note that
- // this is before applying any user-defined limits (specified by calling
- // (SetMinimumDelay() and/or SetMaximumDelay()).
- //
- int LeastRequiredDelayMs() const;
-
- //
// Resets the initial delay to zero.
//
void ResetInitialDelay();
diff --git a/modules/audio_coding/acm2/acm_resampler.h b/modules/audio_coding/acm2/acm_resampler.h
index d7d7bcf..904ea52 100644
--- a/modules/audio_coding/acm2/acm_resampler.h
+++ b/modules/audio_coding/acm2/acm_resampler.h
@@ -12,7 +12,6 @@
#define MODULES_AUDIO_CODING_ACM2_ACM_RESAMPLER_H_
#include "common_audio/resampler/include/push_resampler.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace acm2 {
diff --git a/modules/audio_coding/acm2/acm_send_test.cc b/modules/audio_coding/acm2/acm_send_test.cc
index b1a3e98..c5e010c 100644
--- a/modules/audio_coding/acm2/acm_send_test.cc
+++ b/modules/audio_coding/acm2/acm_send_test.cc
@@ -16,10 +16,13 @@
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
+#include "api/audio_codecs/builtin_audio_encoder_factory.h"
+#include "modules/audio_coding/codecs/audio_format_conversion.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "modules/audio_coding/neteq/tools/packet.h"
#include "rtc_base/checks.h"
+#include "rtc_base/stringencode.h"
#include "test/gtest.h"
namespace webrtc {
@@ -65,20 +68,26 @@
sampling_freq_hz, channels));
codec.pltype = payload_type;
codec.pacsize = frame_size_samples;
- codec_registered_ = (acm_->RegisterSendCodec(codec) == 0);
+ auto factory = CreateBuiltinAudioEncoderFactory();
+ SdpAudioFormat format = CodecInstToSdp(codec);
+ format.parameters["ptime"] = rtc::ToString(rtc::CheckedDivExact(
+ frame_size_samples, rtc::CheckedDivExact(sampling_freq_hz, 1000)));
+ acm_->SetEncoder(
+ factory->MakeAudioEncoder(payload_type, format, absl::nullopt));
+ codec_registered_ = true;
input_frame_.num_channels_ = channels;
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
AudioFrame::kMaxDataSizeSamples);
return codec_registered_;
}
-bool AcmSendTestOldApi::RegisterExternalCodec(
- AudioEncoder* external_speech_encoder) {
- acm_->RegisterExternalSendCodec(external_speech_encoder);
+void AcmSendTestOldApi::RegisterExternalCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder) {
input_frame_.num_channels_ = external_speech_encoder->NumChannels();
+ acm_->SetEncoder(std::move(external_speech_encoder));
assert(input_block_size_samples_ * input_frame_.num_channels_ <=
AudioFrame::kMaxDataSizeSamples);
- return codec_registered_ = true;
+ codec_registered_ = true;
}
std::unique_ptr<Packet> AcmSendTestOldApi::NextPacket() {
diff --git a/modules/audio_coding/acm2/acm_send_test.h b/modules/audio_coding/acm2/acm_send_test.h
index 68ba9e1..3479de0 100644
--- a/modules/audio_coding/acm2/acm_send_test.h
+++ b/modules/audio_coding/acm2/acm_send_test.h
@@ -42,8 +42,9 @@
int payload_type,
int frame_size_samples);
- // Registers an external send codec. Returns true on success, false otherwise.
- bool RegisterExternalCodec(AudioEncoder* external_speech_encoder);
+ // Registers an external send codec.
+ void RegisterExternalCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder);
// Inherited from PacketSource.
std::unique_ptr<Packet> NextPacket() override;
diff --git a/modules/audio_coding/acm2/audio_coding_module.cc b/modules/audio_coding/acm2/audio_coding_module.cc
index 7f652a2..f0b35ca 100644
--- a/modules/audio_coding/acm2/audio_coding_module.cc
+++ b/modules/audio_coding/acm2/audio_coding_module.cc
@@ -50,15 +50,9 @@
void ModifyEncoder(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)>
modifier) override;
- void QueryEncoder(
- rtc::FunctionView<void(const AudioEncoder*)> query) override;
-
// Get current send codec.
absl::optional<CodecInst> SendCodec() const override;
- // Get current send frequency.
- int SendFrequency() const override;
-
// Sets the bitrate to the specified value in bits/sec. In case the codec does
// not support the requested value it will choose an appropriate value
// instead.
@@ -155,11 +149,6 @@
// Maximum playout delay.
int SetMaximumPlayoutDelay(int time_ms) override;
- // Smallest latency NetEq will maintain.
- int LeastRequiredDelayMs() const override;
-
- RTC_DEPRECATED int32_t PlayoutTimestamp(uint32_t* timestamp) override;
-
absl::optional<uint32_t> PlayoutTimestamp() override;
int FilteredCurrentDelayMs() const override;
@@ -171,7 +160,6 @@
int PlayoutData10Ms(int desired_freq_hz,
AudioFrame* audio_frame,
bool* muted) override;
- int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame) override;
/////////////////////////////////////////
// Statistics
@@ -598,12 +586,6 @@
modifier(&encoder_stack_);
}
-void AudioCodingModuleImpl::QueryEncoder(
- rtc::FunctionView<void(const AudioEncoder*)> query) {
- rtc::CritScope lock(&acm_crit_sect_);
- query(encoder_stack_.get());
-}
-
// Get current send codec.
absl::optional<CodecInst> AudioCodingModuleImpl::SendCodec() const {
rtc::CritScope lock(&acm_crit_sect_);
@@ -627,18 +609,6 @@
}
}
-// Get current send frequency.
-int AudioCodingModuleImpl::SendFrequency() const {
- rtc::CritScope lock(&acm_crit_sect_);
-
- if (!encoder_stack_) {
- RTC_LOG(LS_ERROR) << "SendFrequency Failed, no codec is registered";
- return -1;
- }
-
- return encoder_stack_->SampleRateHz();
-}
-
void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) {
rtc::CritScope lock(&acm_crit_sect_);
if (encoder_stack_) {
@@ -1109,14 +1079,6 @@
return 0;
}
-int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz,
- AudioFrame* audio_frame) {
- bool muted;
- int ret = PlayoutData10Ms(desired_freq_hz, audio_frame, &muted);
- RTC_DCHECK(!muted);
- return ret;
-}
-
/////////////////////////////////////////
// Statistics
//
@@ -1181,14 +1143,6 @@
return encoder_stack_->SetDtx(false) ? 0 : -1;
}
-int32_t AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) {
- absl::optional<uint32_t> ts = PlayoutTimestamp();
- if (!ts)
- return -1;
- *timestamp = *ts;
- return 0;
-}
-
absl::optional<uint32_t> AudioCodingModuleImpl::PlayoutTimestamp() {
return receiver_.GetPlayoutTimestamp();
}
@@ -1226,10 +1180,6 @@
return receiver_.GetNackList(round_trip_time_ms);
}
-int AudioCodingModuleImpl::LeastRequiredDelayMs() const {
- return receiver_.LeastRequiredDelayMs();
-}
-
void AudioCodingModuleImpl::GetDecodingCallStatistics(
AudioDecodingCallStats* call_stats) const {
receiver_.GetDecodingCallStatistics(call_stats);
@@ -1310,12 +1260,4 @@
return i ? *i : -1;
}
-// Checks the validity of the parameters of the given codec
-bool AudioCodingModule::IsCodecValid(const CodecInst& codec) {
- bool valid = acm2::RentACodec::IsCodecValid(codec);
- if (!valid)
- RTC_LOG(LS_ERROR) << "Invalid codec setting";
- return valid;
-}
-
} // namespace webrtc
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index ce2832a..924a4a6 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -37,6 +37,7 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/refcountedobject.h"
+#include "rtc_base/system/arch.h"
#include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/event_wrapper.h"
@@ -1147,13 +1148,14 @@
payload_type, frame_size_samples);
}
- bool RegisterExternalSendCodec(AudioEncoder* external_speech_encoder,
- int payload_type) {
+ void RegisterExternalSendCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder,
+ int payload_type) {
payload_type_ = payload_type;
frame_size_rtp_timestamps_ = rtc::checked_cast<uint32_t>(
external_speech_encoder->Num10MsFramesInNextPacket() *
external_speech_encoder->RtpTimestampRateHz() / 100);
- return send_test_->RegisterExternalCodec(external_speech_encoder);
+ send_test_->RegisterExternalCodec(std::move(external_speech_encoder));
}
// Runs the test. SetUpSender() and RegisterSendCodec() must have been called
@@ -1248,11 +1250,11 @@
codec_frame_size_rtp_timestamps));
}
- void SetUpTestExternalEncoder(AudioEncoder* external_speech_encoder,
- int payload_type) {
+ void SetUpTestExternalEncoder(
+ std::unique_ptr<AudioEncoder> external_speech_encoder,
+ int payload_type) {
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(
- RegisterExternalSendCodec(external_speech_encoder, payload_type));
+ RegisterExternalSendCodec(std::move(external_speech_encoder), payload_type);
}
std::unique_ptr<test::AcmSendTestOldApi> send_test_;
@@ -1459,8 +1461,8 @@
TEST_F(AcmSenderBitExactnessNewApi, MAYBE_OpusFromFormat_stereo_20ms) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 120);
- ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(encoder.get(), 120));
+ ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(
+ AudioEncoderOpus::MakeAudioEncoder(*config, 120), 120));
Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
"3e285b74510e62062fbd8142dacd16e9",
"3e285b74510e62062fbd8142dacd16e9",
@@ -1498,8 +1500,8 @@
TEST_F(AcmSenderBitExactnessNewApi, OpusFromFormat_stereo_20ms_voip) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"stereo", "1"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 120);
- ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(encoder.get(), 120));
+ ASSERT_NO_FATAL_FAILURE(SetUpTestExternalEncoder(
+ AudioEncoderOpus::MakeAudioEncoder(*config, 120), 120));
// If not set, default will be kAudio in case of stereo.
EXPECT_EQ(0, send_test_->acm()->SetOpusApplication(kVoip));
Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
@@ -1549,9 +1551,10 @@
payload_type, frame_size_samples);
}
- bool RegisterExternalSendCodec(AudioEncoder* external_speech_encoder,
- int payload_type) {
- return send_test_->RegisterExternalCodec(external_speech_encoder);
+ void RegisterExternalSendCodec(
+ std::unique_ptr<AudioEncoder> external_speech_encoder,
+ int payload_type) {
+ send_test_->RegisterExternalCodec(std::move(external_speech_encoder));
}
void RunInner(int min_expected_total_bits, int max_expected_total_bits) {
@@ -1610,9 +1613,9 @@
TEST_F(AcmSetBitRateNewApi, OpusFromFormat_48khz_20ms_10kbps) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "10000"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 107);
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(RegisterExternalSendCodec(encoder.get(), 107));
+ RegisterExternalSendCodec(AudioEncoderOpus::MakeAudioEncoder(*config, 107),
+ 107);
RunInner(8000, 12000);
}
@@ -1624,9 +1627,9 @@
TEST_F(AcmSetBitRateNewApi, OpusFromFormat_48khz_20ms_50kbps) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "50000"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 107);
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(RegisterExternalSendCodec(encoder.get(), 107));
+ RegisterExternalSendCodec(AudioEncoderOpus::MakeAudioEncoder(*config, 107),
+ 107);
RunInner(40000, 60000);
}
@@ -1649,9 +1652,9 @@
TEST_F(AcmSetBitRateNewApi, MAYBE_OpusFromFormat_48khz_20ms_100kbps) {
const auto config = AudioEncoderOpus::SdpToConfig(
SdpAudioFormat("opus", 48000, 2, {{"maxaveragebitrate", "100000"}}));
- const auto encoder = AudioEncoderOpus::MakeAudioEncoder(*config, 107);
ASSERT_TRUE(SetUpSender());
- ASSERT_TRUE(RegisterExternalSendCodec(encoder.get(), 107));
+ RegisterExternalSendCodec(AudioEncoderOpus::MakeAudioEncoder(*config, 107),
+ 107);
RunInner(80000, 120000);
}
@@ -1723,17 +1726,17 @@
TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_10kbps_2) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
- Run(10000, 32200, 5208);
+ Run(10000, 14096, 4232);
}
TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_50kbps_2) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
- Run(50000, 32200, 23928);
+ Run(50000, 14096, 22552);
}
TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_100kbps_2) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960));
- Run(100000, 32200, 50448);
+ Run(100000, 14096, 49472);
}
// These next 2 tests ensure that the SetBitRate function has no effect on PCM
@@ -1753,36 +1756,33 @@
codec_inst.pacsize = 160;
codec_inst.pltype = 0;
AudioEncoderPcmU encoder(codec_inst);
- MockAudioEncoder mock_encoder;
+ auto mock_encoder = absl::make_unique<MockAudioEncoder>();
// Set expectations on the mock encoder and also delegate the calls to the
// real encoder.
- EXPECT_CALL(mock_encoder, SampleRateHz())
+ EXPECT_CALL(*mock_encoder, SampleRateHz())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SampleRateHz));
- EXPECT_CALL(mock_encoder, NumChannels())
+ EXPECT_CALL(*mock_encoder, NumChannels())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::NumChannels));
- EXPECT_CALL(mock_encoder, RtpTimestampRateHz())
+ EXPECT_CALL(*mock_encoder, RtpTimestampRateHz())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::RtpTimestampRateHz));
- EXPECT_CALL(mock_encoder, Num10MsFramesInNextPacket())
+ EXPECT_CALL(*mock_encoder, Num10MsFramesInNextPacket())
.Times(AtLeast(1))
.WillRepeatedly(
Invoke(&encoder, &AudioEncoderPcmU::Num10MsFramesInNextPacket));
- EXPECT_CALL(mock_encoder, GetTargetBitrate())
+ EXPECT_CALL(*mock_encoder, GetTargetBitrate())
.Times(AtLeast(1))
.WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::GetTargetBitrate));
- EXPECT_CALL(mock_encoder, EncodeImpl(_, _, _))
+ EXPECT_CALL(*mock_encoder, EncodeImpl(_, _, _))
.Times(AtLeast(1))
.WillRepeatedly(Invoke(
&encoder, static_cast<AudioEncoder::EncodedInfo (AudioEncoder::*)(
uint32_t, rtc::ArrayView<const int16_t>, rtc::Buffer*)>(
&AudioEncoderPcmU::Encode)));
- EXPECT_CALL(mock_encoder, SetFec(_))
- .Times(AtLeast(1))
- .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SetFec));
ASSERT_NO_FATAL_FAILURE(
- SetUpTestExternalEncoder(&mock_encoder, codec_inst.pltype));
+ SetUpTestExternalEncoder(std::move(mock_encoder), codec_inst.pltype));
Run("81a9d4c0bb72e9becc43aef124c981e9", "8f9b8750bd80fe26b6cbf6659b89f0f9",
50, test::AcmReceiveTestOldApi::kMonoOutput);
}
diff --git a/modules/audio_coding/acm2/codec_manager.cc b/modules/audio_coding/acm2/codec_manager.cc
index a101d3d..f29e0f1 100644
--- a/modules/audio_coding/acm2/codec_manager.cc
+++ b/modules/audio_coding/acm2/codec_manager.cc
@@ -14,7 +14,6 @@
//#include "rtc_base/format_macros.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "rtc_base/logging.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace acm2 {
diff --git a/modules/audio_coding/acm2/rent_a_codec.cc b/modules/audio_coding/acm2/rent_a_codec.cc
index 818e17f..264c2a8 100644
--- a/modules/audio_coding/acm2/rent_a_codec.cc
+++ b/modules/audio_coding/acm2/rent_a_codec.cc
@@ -80,10 +80,6 @@
return ci;
}
-bool RentACodec::IsCodecValid(const CodecInst& codec_inst) {
- return ACMCodecDB::CodecNumber(codec_inst) >= 0;
-}
-
absl::optional<bool> RentACodec::IsSupportedNumChannels(CodecId codec_id,
size_t num_channels) {
auto i = CodecIndexFromId(codec_id);
diff --git a/modules/audio_coding/acm2/rent_a_codec.h b/modules/audio_coding/acm2/rent_a_codec.h
index 02f9d03..b0ad382 100644
--- a/modules/audio_coding/acm2/rent_a_codec.h
+++ b/modules/audio_coding/acm2/rent_a_codec.h
@@ -23,7 +23,6 @@
#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -129,7 +128,6 @@
static absl::optional<CodecInst> CodecInstByParams(const char* payload_name,
int sampling_freq_hz,
size_t channels);
- static bool IsCodecValid(const CodecInst& codec_inst);
static inline bool IsPayloadTypeValid(int payload_type) {
return payload_type >= 0 && payload_type <= 127;
diff --git a/modules/audio_coding/audio_network_adaptor/parse_ana_dump.py b/modules/audio_coding/audio_network_adaptor/parse_ana_dump.py
index a52b065..1bd5f0c 100755
--- a/modules/audio_coding/audio_network_adaptor/parse_ana_dump.py
+++ b/modules/audio_coding/audio_network_adaptor/parse_ana_dump.py
@@ -66,9 +66,9 @@
first_time_stamp = None
while True:
event = GetNextMessageFromFile(file_to_parse)
- if event == None:
+ if event is None:
break
- if first_time_stamp == None:
+ if first_time_stamp is None:
first_time_stamp = event.timestamp
if event.type == debug_dump_pb2.Event.ENCODER_RUNTIME_CONFIG:
for decision in event.encoder_runtime_config.DESCRIPTOR.fields:
@@ -110,7 +110,7 @@
action='append')
options = parser.parse_args()[0]
- if options.dump_file_to_parse == None:
+ if options.dump_file_to_parse is None:
print "No dump file to parse is set.\n"
parser.print_help()
exit()
diff --git a/modules/audio_coding/codecs/cng/webrtc_cng.h b/modules/audio_coding/codecs/cng/webrtc_cng.h
index 684480a..3f8fadc 100644
--- a/modules/audio_coding/codecs/cng/webrtc_cng.h
+++ b/modules/audio_coding/codecs/cng/webrtc_cng.h
@@ -15,7 +15,6 @@
#include "api/array_view.h"
#include "rtc_base/buffer.h"
-#include "typedefs.h" // NOLINT(build/include)
#define WEBRTC_CNG_MAX_LPC_ORDER 12
diff --git a/modules/audio_coding/codecs/g711/g711_interface.c b/modules/audio_coding/codecs/g711/g711_interface.c
index 9c31cbc..5fe1692 100644
--- a/modules/audio_coding/codecs/g711/g711_interface.c
+++ b/modules/audio_coding/codecs/g711/g711_interface.c
@@ -10,9 +10,8 @@
#include <string.h>
-#include "modules/audio_coding/codecs/g711/g711.h"
+#include "modules/third_party/g711/g711.h"
#include "modules/audio_coding/codecs/g711/g711_interface.h"
-#include "typedefs.h" // NOLINT(build/include)
size_t WebRtcG711_EncodeA(const int16_t* speechIn,
size_t len,
diff --git a/modules/audio_coding/codecs/g711/g711_interface.h b/modules/audio_coding/codecs/g711/g711_interface.h
index f206f30..83f9d37 100644
--- a/modules/audio_coding/codecs/g711/g711_interface.h
+++ b/modules/audio_coding/codecs/g711/g711_interface.h
@@ -11,7 +11,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
#define MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
// Comfort noise constants
#define G711_WEBRTC_SPEECH 1
diff --git a/modules/audio_coding/codecs/g722/g722_interface.c b/modules/audio_coding/codecs/g722/g722_interface.c
index fb25049..36ee6d9 100644
--- a/modules/audio_coding/codecs/g722/g722_interface.c
+++ b/modules/audio_coding/codecs/g722/g722_interface.c
@@ -11,9 +11,8 @@
#include <stdlib.h>
#include <string.h>
-#include "modules/audio_coding/codecs/g722/g722_enc_dec.h"
#include "modules/audio_coding/codecs/g722/g722_interface.h"
-#include "typedefs.h" // NOLINT(build/include)
+#include "modules/third_party/g722/g722_enc_dec.h"
int16_t WebRtcG722_CreateEncoder(G722EncInst **G722enc_inst)
{
diff --git a/modules/audio_coding/codecs/g722/g722_interface.h b/modules/audio_coding/codecs/g722/g722_interface.h
index 3b73f85..85c1cd0 100644
--- a/modules/audio_coding/codecs/g722/g722_interface.h
+++ b/modules/audio_coding/codecs/g722/g722_interface.h
@@ -11,7 +11,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_G722_G722_INTERFACE_H_
#define MODULES_AUDIO_CODING_CODECS_G722_G722_INTERFACE_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/*
* Solution to support multiple instances
diff --git a/modules/audio_coding/codecs/ilbc/cb_construct.h b/modules/audio_coding/codecs/ilbc/cb_construct.h
index b200990..f4df387 100644
--- a/modules/audio_coding/codecs/ilbc/cb_construct.h
+++ b/modules/audio_coding/codecs/ilbc/cb_construct.h
@@ -20,7 +20,10 @@
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CB_CONSTRUCT_H_
#include <stdbool.h>
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/ilbc/defines.h"
+#include "rtc_base/system/unused.h"
/*----------------------------------------------------------------*
* Construct decoded vector from codebook and gains.
diff --git a/modules/audio_coding/codecs/ilbc/constants.h b/modules/audio_coding/codecs/ilbc/constants.h
index 3c32c62..07369a3 100644
--- a/modules/audio_coding/codecs/ilbc/constants.h
+++ b/modules/audio_coding/codecs/ilbc/constants.h
@@ -20,7 +20,6 @@
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_CONSTANTS_H_
#include "modules/audio_coding/codecs/ilbc/defines.h"
-#include "typedefs.h" // NOLINT(build/include)
/* high pass filters */
diff --git a/modules/audio_coding/codecs/ilbc/decode.c b/modules/audio_coding/codecs/ilbc/decode.c
index 7cba418..3848bc7 100644
--- a/modules/audio_coding/codecs/ilbc/decode.c
+++ b/modules/audio_coding/codecs/ilbc/decode.c
@@ -16,6 +16,9 @@
******************************************************************/
+// Defines WEBRTC_ARCH_BIG_ENDIAN, used below.
+#include "rtc_base/system/arch.h"
+
#include "modules/audio_coding/codecs/ilbc/defines.h"
#include "modules/audio_coding/codecs/ilbc/simple_lsf_dequant.h"
#include "modules/audio_coding/codecs/ilbc/decoder_interpolate_lsf.h"
diff --git a/modules/audio_coding/codecs/ilbc/decode.h b/modules/audio_coding/codecs/ilbc/decode.h
index c5f35f4..d73f798 100644
--- a/modules/audio_coding/codecs/ilbc/decode.h
+++ b/modules/audio_coding/codecs/ilbc/decode.h
@@ -19,7 +19,10 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_H_
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_H_
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/ilbc/defines.h"
+#include "rtc_base/system/unused.h"
/*----------------------------------------------------------------*
* main decoder function
diff --git a/modules/audio_coding/codecs/ilbc/decode_residual.h b/modules/audio_coding/codecs/ilbc/decode_residual.h
index 7468e5f..d54aada 100644
--- a/modules/audio_coding/codecs/ilbc/decode_residual.h
+++ b/modules/audio_coding/codecs/ilbc/decode_residual.h
@@ -20,7 +20,10 @@
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_DECODE_RESIDUAL_H_
#include <stdbool.h>
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/ilbc/defines.h"
+#include "rtc_base/system/unused.h"
/*----------------------------------------------------------------*
* frame residual decoder function (subrutine to iLBC_decode)
diff --git a/modules/audio_coding/codecs/ilbc/defines.h b/modules/audio_coding/codecs/ilbc/defines.h
index 9a4a196..43948a2 100644
--- a/modules/audio_coding/codecs/ilbc/defines.h
+++ b/modules/audio_coding/codecs/ilbc/defines.h
@@ -21,7 +21,6 @@
#include <string.h>
#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "typedefs.h" // NOLINT(build/include)
/* general codec settings */
diff --git a/modules/audio_coding/codecs/ilbc/encode.c b/modules/audio_coding/codecs/ilbc/encode.c
index 3631c65..912e23c 100644
--- a/modules/audio_coding/codecs/ilbc/encode.c
+++ b/modules/audio_coding/codecs/ilbc/encode.c
@@ -18,6 +18,9 @@
#include <string.h>
+// Defines WEBRTC_ARCH_BIG_ENDIAN, used below.
+#include "rtc_base/system/arch.h"
+
#include "modules/audio_coding/codecs/ilbc/defines.h"
#include "modules/audio_coding/codecs/ilbc/lpc_encode.h"
#include "modules/audio_coding/codecs/ilbc/frame_classify.h"
diff --git a/modules/audio_coding/codecs/ilbc/get_cd_vec.h b/modules/audio_coding/codecs/ilbc/get_cd_vec.h
index 76e1a56..647b063 100644
--- a/modules/audio_coding/codecs/ilbc/get_cd_vec.h
+++ b/modules/audio_coding/codecs/ilbc/get_cd_vec.h
@@ -20,8 +20,11 @@
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_GET_CD_VEC_H_
#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
#include "modules/audio_coding/codecs/ilbc/defines.h"
+#include "rtc_base/system/unused.h"
// Returns true on success, false on failure. In case of failure, the decoder
// state may be corrupted and needs resetting.
diff --git a/modules/audio_coding/codecs/ilbc/ilbc.h b/modules/audio_coding/codecs/ilbc/ilbc.h
index 4c12665..de8cfde 100644
--- a/modules/audio_coding/codecs/ilbc/ilbc.h
+++ b/modules/audio_coding/codecs/ilbc/ilbc.h
@@ -19,12 +19,7 @@
#define MODULES_AUDIO_CODING_CODECS_ILBC_ILBC_H_
#include <stddef.h>
-
-/*
- * Define the fixpoint numeric formats
- */
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/*
* Solution to support multiple instances
diff --git a/modules/audio_coding/codecs/ilbc/vq3.h b/modules/audio_coding/codecs/ilbc/vq3.h
index ceaff8d..c946478 100644
--- a/modules/audio_coding/codecs/ilbc/vq3.h
+++ b/modules/audio_coding/codecs/ilbc/vq3.h
@@ -19,7 +19,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ3_H_
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ3_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/*----------------------------------------------------------------*
* Vector quantization of order 3 (based on MSE)
diff --git a/modules/audio_coding/codecs/ilbc/vq4.h b/modules/audio_coding/codecs/ilbc/vq4.h
index 8dbedc9..6d14830 100644
--- a/modules/audio_coding/codecs/ilbc/vq4.h
+++ b/modules/audio_coding/codecs/ilbc/vq4.h
@@ -19,7 +19,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ4_H_
#define MODULES_AUDIO_CODING_CODECS_ILBC_MAIN_SOURCE_VQ4_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/*----------------------------------------------------------------*
* Vector quantization of order 4 (based on MSE)
diff --git a/modules/audio_coding/codecs/isac/bandwidth_info.h b/modules/audio_coding/codecs/isac/bandwidth_info.h
index 0539780..c3830a5 100644
--- a/modules/audio_coding/codecs/isac/bandwidth_info.h
+++ b/modules/audio_coding/codecs/isac/bandwidth_info.h
@@ -11,7 +11,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_BANDWIDTH_INFO_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_BANDWIDTH_INFO_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
typedef struct {
int in_use;
diff --git a/modules/audio_coding/codecs/isac/fix/include/isacfix.h b/modules/audio_coding/codecs/isac/fix/include/isacfix.h
index 626b3c7..8fcfebb 100644
--- a/modules/audio_coding/codecs/isac/fix/include/isacfix.h
+++ b/modules/audio_coding/codecs/isac/fix/include/isacfix.h
@@ -14,7 +14,6 @@
#include <stddef.h>
#include "modules/audio_coding/codecs/isac/bandwidth_info.h"
-#include "typedefs.h" // NOLINT(build/include)
typedef struct { void* dummy; } ISACFIX_MainStruct;
diff --git a/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h b/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h
index 8d97347..6b99914 100644
--- a/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h
+++ b/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h
@@ -11,7 +11,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_INTERNAL_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_INTERNAL_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
diff --git a/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h b/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h
index 55e1f44..01e5a7b 100644
--- a/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h
+++ b/modules/audio_coding/codecs/isac/fix/source/filterbank_tables.h
@@ -19,7 +19,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_FILTERBANK_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
diff --git a/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc b/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc
index 0727d58..b7456a7 100644
--- a/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc
+++ b/modules/audio_coding/codecs/isac/fix/source/filterbanks_unittest.cc
@@ -15,7 +15,6 @@
#include "rtc_base/sanitizer.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
class FilterBanksTest : public testing::Test {
protected:
diff --git a/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc b/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc
index 2ab8d6a..471fa57 100644
--- a/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc
+++ b/modules/audio_coding/codecs/isac/fix/source/filters_unittest.cc
@@ -11,7 +11,6 @@
#include "modules/audio_coding/codecs/isac/fix/source/codec.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
class FiltersTest : public testing::Test {
protected:
diff --git a/modules/audio_coding/codecs/isac/fix/source/lattice_c.c b/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
index d9849d6..4340661 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
+++ b/modules/audio_coding/codecs/isac/fix/source/lattice_c.c
@@ -16,7 +16,6 @@
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/* Filter ar_g_Q0[] and ar_f_Q0[] through an AR filter with coefficients
* cth_Q15[] and sth_Q15[].
diff --git a/modules/audio_coding/codecs/isac/fix/source/lattice_mips.c b/modules/audio_coding/codecs/isac/fix/source/lattice_mips.c
index 613c07c..3189726 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lattice_mips.c
+++ b/modules/audio_coding/codecs/isac/fix/source/lattice_mips.c
@@ -9,9 +9,9 @@
*/
#include <stddef.h>
+#include <stdint.h>
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
// Filter ar_g_Q0[] and ar_f_Q0[] through an AR filter with coefficients
// cth_Q15[] and sth_Q15[].
diff --git a/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc b/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc
index dbcf420..fab0a04 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc
+++ b/modules/audio_coding/codecs/isac/fix/source/lpc_masking_model_unittest.cc
@@ -11,7 +11,6 @@
#include "modules/audio_coding/codecs/isac/fix/source/lpc_masking_model.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
class LpcMaskingModelTest : public testing::Test {
protected:
diff --git a/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h b/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h
index c51f2ca..2d68fa6 100644
--- a/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h
+++ b/modules/audio_coding/codecs/isac/fix/source/lpc_tables.h
@@ -18,7 +18,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_LPC_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/* indices of KLT coefficients used */
extern const uint16_t WebRtcIsacfix_kSelIndGain[12];
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h b/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h
index 2b5f54e..59e1738 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_gain_tables.h
@@ -19,7 +19,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_GAIN_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/********************* Pitch Filter Gain Coefficient Tables
* ************************/
diff --git a/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h b/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h
index f834eab..228da26 100644
--- a/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h
+++ b/modules/audio_coding/codecs/isac/fix/source/pitch_lag_tables.h
@@ -19,7 +19,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_PITCH_LAG_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/********************* Pitch Filter Lag Coefficient Tables
* ************************/
diff --git a/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h b/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h
index 4ac5c0b..2282a36 100644
--- a/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h
+++ b/modules/audio_coding/codecs/isac/fix/source/spectrum_ar_model_tables.h
@@ -19,8 +19,9 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_FIX_SOURCE_SPECTRUM_AR_MODEL_TABLES_H_
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/********************* AR Coefficient Tables ************************/
/* cdf for quantized reflection coefficient 1 */
diff --git a/modules/audio_coding/codecs/isac/fix/source/structs.h b/modules/audio_coding/codecs/isac/fix/source/structs.h
index 352eef0..59226ac 100644
--- a/modules/audio_coding/codecs/isac/fix/source/structs.h
+++ b/modules/audio_coding/codecs/isac/fix/source/structs.h
@@ -21,7 +21,6 @@
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "modules/audio_coding/codecs/isac/bandwidth_info.h"
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/* Bitstream struct for decoder */
typedef struct Bitstreamstruct_dec {
diff --git a/modules/audio_coding/codecs/isac/fix/source/transform.c b/modules/audio_coding/codecs/isac/fix/source/transform.c
index 2f1275d..80b244b 100644
--- a/modules/audio_coding/codecs/isac/fix/source/transform.c
+++ b/modules/audio_coding/codecs/isac/fix/source/transform.c
@@ -18,6 +18,7 @@
#include "modules/audio_coding/codecs/isac/fix/source/codec.h"
#include "modules/audio_coding/codecs/isac/fix/source/fft.h"
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
+#include "modules/third_party/fft/fft.h"
/* Tables are defined in transform_tables.c file or ARM assembly files. */
/* Cosine table 1 in Q14 */
diff --git a/modules/audio_coding/codecs/isac/fix/source/transform_tables.c b/modules/audio_coding/codecs/isac/fix/source/transform_tables.c
index eed88e4..e661eff 100644
--- a/modules/audio_coding/codecs/isac/fix/source/transform_tables.c
+++ b/modules/audio_coding/codecs/isac/fix/source/transform_tables.c
@@ -13,8 +13,9 @@
* transform functions WebRtcIsacfix_Time2Spec and WebRtcIsacfix_Spec2Time.
*/
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/isac/fix/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/* Cosine table 1 in Q14. */
const int16_t WebRtcIsacfix_kCosTab1[FRAMESAMPLES/2] = {
diff --git a/modules/audio_coding/codecs/isac/main/include/isac.h b/modules/audio_coding/codecs/isac/main/include/isac.h
index 1d7e075..6cd70a6 100644
--- a/modules/audio_coding/codecs/isac/main/include/isac.h
+++ b/modules/audio_coding/codecs/isac/main/include/isac.h
@@ -14,7 +14,6 @@
#include <stddef.h>
#include "modules/audio_coding/codecs/isac/bandwidth_info.h"
-#include "typedefs.h" // NOLINT(build/include)
typedef struct WebRtcISACStruct ISACStruct;
diff --git a/modules/audio_coding/codecs/isac/main/source/codec.h b/modules/audio_coding/codecs/isac/main/source/codec.h
index c386704..a7c7ddc 100644
--- a/modules/audio_coding/codecs/isac/main/source/codec.h
+++ b/modules/audio_coding/codecs/isac/main/source/codec.h
@@ -22,6 +22,7 @@
#include <stddef.h>
#include "modules/audio_coding/codecs/isac/main/source/structs.h"
+#include "modules/third_party/fft/fft.h"
void WebRtcIsac_ResetBitstream(Bitstr* bit_stream);
diff --git a/modules/audio_coding/codecs/isac/main/source/crc.h b/modules/audio_coding/codecs/isac/main/source/crc.h
index 19adbda..f031019 100644
--- a/modules/audio_coding/codecs/isac/main/source/crc.h
+++ b/modules/audio_coding/codecs/isac/main/source/crc.h
@@ -18,7 +18,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_CRC_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/****************************************************************************
* WebRtcIsac_GetCrc(...)
diff --git a/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c b/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c
index 0ab2dc1..7b02e64 100644
--- a/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c
+++ b/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c
@@ -25,7 +25,6 @@
#include "modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.h"
#include "modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h"
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/******************************************************************************
* WebRtcIsac_RemoveLarMean()
diff --git a/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.h b/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.h
index b8d918b..8bc3d75 100644
--- a/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.h
+++ b/modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.h
@@ -21,7 +21,6 @@
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
#include "modules/audio_coding/codecs/isac/main/source/structs.h"
-#include "typedefs.h" // NOLINT(build/include)
/******************************************************************************
* WebRtcIsac_RemoveLarMean()
diff --git a/modules/audio_coding/codecs/isac/main/source/isac.c b/modules/audio_coding/codecs/isac/main/source/isac.c
index 45eb598..8669596 100644
--- a/modules/audio_coding/codecs/isac/main/source/isac.c
+++ b/modules/audio_coding/codecs/isac/main/source/isac.c
@@ -32,6 +32,7 @@
#include "modules/audio_coding/codecs/isac/main/source/os_specific_inline.h"
#include "modules/audio_coding/codecs/isac/main/source/structs.h"
#include "modules/audio_coding/codecs/isac/main/source/isac_vad.h"
+#include "rtc_base/system/arch.h"
#define BIT_MASK_DEC_INIT 0x0001
#define BIT_MASK_ENC_INIT 0x0002
diff --git a/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c b/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c
index d6e65f3..6707540 100644
--- a/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c
+++ b/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c
@@ -18,7 +18,6 @@
#include "modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.h"
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
const double WebRtcIsac_kQSizeLpcGain = 0.100000;
diff --git a/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.h b/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.h
index 84913dd..39c4a24 100644
--- a/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.h
+++ b/modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.h
@@ -19,8 +19,9 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_GAIN_SWB_TABLES_H_
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
extern const double WebRtcIsac_kQSizeLpcGain;
diff --git a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c
index 490866c..e3600a7 100644
--- a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c
+++ b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c
@@ -18,7 +18,6 @@
#include "modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.h"
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/*
* Mean value of LAR
diff --git a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.h b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.h
index e21e15a..7448a1e 100644
--- a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.h
+++ b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.h
@@ -19,8 +19,9 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB12_TABLES_H_
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
extern const double WebRtcIsac_kMeanLarUb12[UB_LPC_ORDER];
diff --git a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c
index d03c7b7..59617fd 100644
--- a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c
+++ b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c
@@ -18,7 +18,6 @@
#include "modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h"
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
/*
* Mean value of LAR
diff --git a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h
index 4d5403d..51101db 100644
--- a/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h
+++ b/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h
@@ -19,8 +19,9 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_LPC_SHAPE_SWB16_TABLES_H_
+#include <stdint.h>
+
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
extern const double WebRtcIsac_kMeanLarUb16[UB_LPC_ORDER];
diff --git a/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h b/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h
index f72236d..fe9afa4 100644
--- a/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h
+++ b/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h
@@ -12,7 +12,8 @@
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_OS_SPECIFIC_INLINE_H_
#include <math.h>
-#include "typedefs.h" // NOLINT(build/include)
+
+#include "rtc_base/system/arch.h"
#if defined(WEBRTC_POSIX)
#define WebRtcIsac_lrint lrint
diff --git a/modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.h b/modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.h
index 891bcef..145fd4e 100644
--- a/modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.h
+++ b/modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.h
@@ -19,7 +19,7 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_GAIN_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
/* header file for coding tables for the pitch filter side-info in the entropy
* coder */
diff --git a/modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.h b/modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.h
index b662ab5..b48e358 100644
--- a/modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.h
+++ b/modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.h
@@ -19,7 +19,8 @@
#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_
#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_PITCH_LAG_TABLES_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
+
/* header file for coding tables for the pitch filter side-info in the entropy
* coder */
/********************* Pitch Filter Lag Coefficient Tables
diff --git a/modules/audio_coding/codecs/isac/main/source/settings.h b/modules/audio_coding/codecs/isac/main/source/settings.h
index 14a5be8..abce90c 100644
--- a/modules/audio_coding/codecs/isac/main/source/settings.h
+++ b/modules/audio_coding/codecs/isac/main/source/settings.h
@@ -24,9 +24,6 @@
/* number of samples per frame (either 320 (20ms), 480 (30ms) or 960 (60ms)) */
#define INITIAL_FRAMESAMPLES 960
-#define MAXFFTSIZE 2048
-#define NFACTOR 11
-
/* do not modify the following; this will have to be modified if we
* have a 20ms framesize option */
/**********************************************************************/
diff --git a/modules/audio_coding/codecs/isac/main/source/structs.h b/modules/audio_coding/codecs/isac/main/source/structs.h
index f8ac9c7..1255d5b 100644
--- a/modules/audio_coding/codecs/isac/main/source/structs.h
+++ b/modules/audio_coding/codecs/isac/main/source/structs.h
@@ -20,7 +20,7 @@
#include "modules/audio_coding/codecs/isac/bandwidth_info.h"
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "typedefs.h" // NOLINT(build/include)
+#include "modules/third_party/fft/fft.h"
typedef struct Bitstreamstruct {
uint8_t stream[STREAM_SIZE_MAX];
@@ -229,18 +229,6 @@
} RateModel;
-typedef struct {
- unsigned int SpaceAlloced;
- unsigned int MaxPermAlloced;
- double Tmp0[MAXFFTSIZE];
- double Tmp1[MAXFFTSIZE];
- double Tmp2[MAXFFTSIZE];
- double Tmp3[MAXFFTSIZE];
- int Perm[MAXFFTSIZE];
- int factor[NFACTOR];
-
-} FFTstr;
-
/* The following strutc is used to store data from encoding, to make it
fast and easy to construct a new bitstream with a different Bandwidth
estimate. All values (except framelength and minBytes) is double size to
diff --git a/modules/audio_coding/codecs/isac/main/source/transform.c b/modules/audio_coding/codecs/isac/main/source/transform.c
index bfbfecb..082ad94 100644
--- a/modules/audio_coding/codecs/isac/main/source/transform.c
+++ b/modules/audio_coding/codecs/isac/main/source/transform.c
@@ -11,9 +11,9 @@
#include <math.h>
#include "modules/audio_coding/codecs/isac/main/source/settings.h"
-#include "modules/audio_coding/codecs/isac/main/source/fft.h"
#include "modules/audio_coding/codecs/isac/main/source/codec.h"
#include "modules/audio_coding/codecs/isac/main/source/os_specific_inline.h"
+#include "modules/third_party/fft/fft.h"
void WebRtcIsac_InitTransform(TransformTables* tables) {
int k;
diff --git a/modules/audio_coding/codecs/opus/opus_fec_test.cc b/modules/audio_coding/codecs/opus/opus_fec_test.cc
index f1983ae..4fab8a7 100644
--- a/modules/audio_coding/codecs/opus/opus_fec_test.cc
+++ b/modules/audio_coding/codecs/opus/opus_fec_test.cc
@@ -38,8 +38,8 @@
protected:
OpusFecTest();
- virtual void SetUp();
- virtual void TearDown();
+ void SetUp() override;
+ void TearDown() override;
virtual void EncodeABlock();
diff --git a/modules/audio_coding/codecs/opus/opus_interface.h b/modules/audio_coding/codecs/opus/opus_interface.h
index 0b1c64d..ddb4ff9 100644
--- a/modules/audio_coding/codecs/opus/opus_interface.h
+++ b/modules/audio_coding/codecs/opus/opus_interface.h
@@ -12,9 +12,9 @@
#define MODULES_AUDIO_CODING_CODECS_OPUS_OPUS_INTERFACE_H_
#include <stddef.h>
+#include <stdint.h>
#include "modules/audio_coding/codecs/opus/opus_inst.h"
-#include "typedefs.h" // NOLINT(build/include)
#ifdef __cplusplus
extern "C" {
diff --git a/modules/audio_coding/codecs/pcm16b/pcm16b.c b/modules/audio_coding/codecs/pcm16b/pcm16b.c
index abcff4f..2f6dce5 100644
--- a/modules/audio_coding/codecs/pcm16b/pcm16b.c
+++ b/modules/audio_coding/codecs/pcm16b/pcm16b.c
@@ -10,8 +10,6 @@
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
-#include "typedefs.h" // NOLINT(build/include)
-
size_t WebRtcPcm16b_Encode(const int16_t* speech,
size_t len,
uint8_t* encoded) {
diff --git a/modules/audio_coding/codecs/pcm16b/pcm16b.h b/modules/audio_coding/codecs/pcm16b/pcm16b.h
index 9a3bfe9..75d1efd 100644
--- a/modules/audio_coding/codecs/pcm16b/pcm16b.h
+++ b/modules/audio_coding/codecs/pcm16b/pcm16b.h
@@ -15,8 +15,7 @@
*/
#include <stddef.h>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
#ifdef __cplusplus
extern "C" {
diff --git a/modules/audio_coding/codecs/tools/audio_codec_speed_test.h b/modules/audio_coding/codecs/tools/audio_codec_speed_test.h
index 0214a7d..c626bfa 100644
--- a/modules/audio_coding/codecs/tools/audio_codec_speed_test.h
+++ b/modules/audio_coding/codecs/tools/audio_codec_speed_test.h
@@ -15,7 +15,6 @@
#include <string>
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/include/audio_coding_module.h b/modules/audio_coding/include/audio_coding_module.h
index a5ad4ff..840a719 100644
--- a/modules/audio_coding/include/audio_coding_module.h
+++ b/modules/audio_coding/include/audio_coding_module.h
@@ -21,10 +21,8 @@
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "modules/audio_coding/neteq/include/neteq.h"
-#include "rtc_base/deprecation.h"
#include "rtc_base/function_view.h"
#include "system_wrappers/include/clock.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -153,20 +151,6 @@
size_t channels);
///////////////////////////////////////////////////////////////////////////
- // bool IsCodecValid()
- // Checks the validity of the parameters of the given codec.
- //
- // Input:
- // -codec : the structure which keeps the parameters of the
- // codec.
- //
- // Return value:
- // true if the parameters are valid,
- // false if any parameter is not valid.
- //
- static bool IsCodecValid(const CodecInst& codec);
-
- ///////////////////////////////////////////////////////////////////////////
// Sender
//
@@ -212,11 +196,6 @@
virtual void ModifyEncoder(
rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier) = 0;
- // |modifier| is called exactly once with one argument: a const pointer to the
- // current encoder (which is null if there is no current encoder).
- virtual void QueryEncoder(
- rtc::FunctionView<void(AudioEncoder const*)> query) = 0;
-
// Utility method for simply replacing the existing encoder with a new one.
void SetEncoder(std::unique_ptr<AudioEncoder> new_encoder) {
ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder) {
@@ -234,16 +213,6 @@
virtual absl::optional<CodecInst> SendCodec() const = 0;
///////////////////////////////////////////////////////////////////////////
- // int32_t SendFrequency()
- // Get the sampling frequency of the current encoder in Hertz.
- //
- // Return value:
- // positive; sampling frequency [Hz] of the current encoder.
- // -1 if an error has happened.
- //
- virtual int32_t SendFrequency() const = 0;
-
- ///////////////////////////////////////////////////////////////////////////
// Sets the bitrate to the specified value in bits/sec. If the value is not
// supported by the codec, it will choose another appropriate value.
//
@@ -604,29 +573,6 @@
//
virtual int SetMaximumPlayoutDelay(int time_ms) = 0;
- // TODO(kwiberg): Consider if this is needed anymore, now that voe::Channel
- // doesn't use it.
- // The shortest latency, in milliseconds, required by jitter buffer. This
- // is computed based on inter-arrival times and playout mode of NetEq. The
- // actual delay is the maximum of least-required-delay and the minimum-delay
- // specified by SetMinumumPlayoutDelay() API.
- //
- virtual int LeastRequiredDelayMs() const = 0;
-
- // int32_t PlayoutTimestamp()
- // The send timestamp of an RTP packet is associated with the decoded
- // audio of the packet in question. This function returns the timestamp of
- // the latest audio obtained by calling PlayoutData10ms().
- //
- // Input:
- // -timestamp : a reference to a uint32_t to receive the
- // timestamp.
- // Return value:
- // 0 if the output is a correct timestamp.
- // -1 if failed to output the correct timestamp.
- //
- RTC_DEPRECATED virtual int32_t PlayoutTimestamp(uint32_t* timestamp) = 0;
-
///////////////////////////////////////////////////////////////////////////
// int32_t PlayoutTimestamp()
// The send timestamp of an RTP packet is associated with the decoded
@@ -675,14 +621,6 @@
AudioFrame* audio_frame,
bool* muted) = 0;
- /////////////////////////////////////////////////////////////////////////////
- // Same as above, but without the muted parameter. This methods should not be
- // used if enable_fast_accelerate was set to true in NetEq::Config.
- // TODO(henrik.lundin) Remove this method when downstream dependencies are
- // ready.
- virtual int32_t PlayoutData10Ms(int32_t desired_freq_hz,
- AudioFrame* audio_frame) = 0;
-
///////////////////////////////////////////////////////////////////////////
// Codec specific
//
diff --git a/modules/audio_coding/include/audio_coding_module_typedefs.h b/modules/audio_coding/include/audio_coding_module_typedefs.h
index e8f80dc..cd4351b 100644
--- a/modules/audio_coding/include/audio_coding_module_typedefs.h
+++ b/modules/audio_coding/include/audio_coding_module_typedefs.h
@@ -13,8 +13,6 @@
#include <map>
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
///////////////////////////////////////////////////////////////////////////
diff --git a/modules/audio_coding/module.mk b/modules/audio_coding/module.mk
index b49e8aa..02f2a06 100644
--- a/modules/audio_coding/module.mk
+++ b/modules/audio_coding/module.mk
@@ -22,7 +22,6 @@
modules/audio_coding/codecs/isac/main/source/encode.o \
modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.o \
modules/audio_coding/codecs/isac/main/source/entropy_coding.o \
- modules/audio_coding/codecs/isac/main/source/fft.o \
modules/audio_coding/codecs/isac/main/source/filterbanks.o \
modules/audio_coding/codecs/isac/main/source/intialize.o \
modules/audio_coding/codecs/isac/main/source/isac.o \
@@ -35,7 +34,8 @@
modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.o \
modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.o \
modules/audio_coding/codecs/isac/main/source/spectrum_ar_model_tables.o \
- modules/audio_coding/codecs/isac/main/source/transform.o
+ modules/audio_coding/codecs/isac/main/source/transform.o \
+ modules/third_party/fft/fft.o
CC_STATIC_LIBRARY(modules/audio_coding/libaudio_coding.pic.a): \
$(isac_c_C_OBJECTS) $(isac_vad_c_OBJECTS)
diff --git a/modules/audio_coding/neteq/accelerate.h b/modules/audio_coding/neteq/accelerate.h
index 6d5b115..b0bab32 100644
--- a/modules/audio_coding/neteq/accelerate.h
+++ b/modules/audio_coding/neteq/accelerate.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "modules/audio_coding/neteq/time_stretch.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/audio_decoder_unittest.cc b/modules/audio_coding/neteq/audio_decoder_unittest.cc
index 54ede6f..1ad4835 100644
--- a/modules/audio_coding/neteq/audio_decoder_unittest.cc
+++ b/modules/audio_coding/neteq/audio_decoder_unittest.cc
@@ -100,16 +100,16 @@
payload_type_(17),
decoder_(NULL) {}
- virtual ~AudioDecoderTest() {}
+ ~AudioDecoderTest() override {}
- virtual void SetUp() {
+ void SetUp() override {
if (audio_encoder_)
codec_input_rate_hz_ = audio_encoder_->SampleRateHz();
// Create arrays.
ASSERT_GT(data_length_, 0u) << "The test must set data_length_ > 0";
}
- virtual void TearDown() {
+ void TearDown() override {
delete decoder_;
decoder_ = NULL;
}
diff --git a/modules/audio_coding/neteq/audio_multi_vector.cc b/modules/audio_coding/neteq/audio_multi_vector.cc
index fee37cb..874633f 100644
--- a/modules/audio_coding/neteq/audio_multi_vector.cc
+++ b/modules/audio_coding/neteq/audio_multi_vector.cc
@@ -15,7 +15,6 @@
#include <algorithm>
#include "rtc_base/checks.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/audio_multi_vector.h b/modules/audio_coding/neteq/audio_multi_vector.h
index f54c98b..4a9ed48 100644
--- a/modules/audio_coding/neteq/audio_multi_vector.h
+++ b/modules/audio_coding/neteq/audio_multi_vector.h
@@ -17,7 +17,6 @@
#include "modules/audio_coding/neteq/audio_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/audio_multi_vector_unittest.cc b/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
index 7272dc2..3f3283e 100644
--- a/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
+++ b/modules/audio_coding/neteq/audio_multi_vector_unittest.cc
@@ -17,7 +17,6 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/audio_vector.cc b/modules/audio_coding/neteq/audio_vector.cc
index 0486416..b3ad48f 100644
--- a/modules/audio_coding/neteq/audio_vector.cc
+++ b/modules/audio_coding/neteq/audio_vector.cc
@@ -16,7 +16,6 @@
#include <memory>
#include "rtc_base/checks.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/audio_vector.h b/modules/audio_coding/neteq/audio_vector.h
index 65939ce..825a3bc 100644
--- a/modules/audio_coding/neteq/audio_vector.h
+++ b/modules/audio_coding/neteq/audio_vector.h
@@ -16,7 +16,6 @@
#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/audio_vector_unittest.cc b/modules/audio_coding/neteq/audio_vector_unittest.cc
index e70178c..1a16bb3 100644
--- a/modules/audio_coding/neteq/audio_vector_unittest.cc
+++ b/modules/audio_coding/neteq/audio_vector_unittest.cc
@@ -17,7 +17,6 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/background_noise.h b/modules/audio_coding/neteq/background_noise.h
index 26d42b5..58eecaa 100644
--- a/modules/audio_coding/neteq/background_noise.h
+++ b/modules/audio_coding/neteq/background_noise.h
@@ -17,7 +17,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "modules/audio_coding/neteq/include/neteq.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/comfort_noise.h b/modules/audio_coding/neteq/comfort_noise.h
index c8cc64a..5169124 100644
--- a/modules/audio_coding/neteq/comfort_noise.h
+++ b/modules/audio_coding/neteq/comfort_noise.h
@@ -13,7 +13,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index 20ba8af..00b8620 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -15,7 +15,6 @@
#include "modules/audio_coding/neteq/include/neteq.h"
#include "modules/audio_coding/neteq/tick_timer.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/decoder_database.h b/modules/audio_coding/neteq/decoder_database.h
index 107d2f3..131e769 100644
--- a/modules/audio_coding/neteq/decoder_database.h
+++ b/modules/audio_coding/neteq/decoder_database.h
@@ -23,7 +23,6 @@
#include "modules/audio_coding/neteq/packet.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/delay_manager.cc b/modules/audio_coding/neteq/delay_manager.cc
index a945cdc..84d457c 100644
--- a/modules/audio_coding/neteq/delay_manager.cc
+++ b/modules/audio_coding/neteq/delay_manager.cc
@@ -40,7 +40,6 @@
last_seq_no_(0),
last_timestamp_(0),
minimum_delay_ms_(0),
- least_required_delay_ms_(target_level_),
maximum_delay_ms_(target_level_),
iat_cumulative_sum_(0),
max_iat_cumulative_sum_(0),
@@ -234,8 +233,6 @@
// |least_required_level_| while the above limits are applied.
// TODO(hlundin): Move this check to the buffer logistics class.
void DelayManager::LimitTargetLevel() {
- least_required_delay_ms_ = (target_level_ * packet_len_ms_) >> 8;
-
if (packet_len_ms_ > 0 && minimum_delay_ms_ > 0) {
int minimum_delay_packet_q8 = (minimum_delay_ms_ << 8) / packet_len_ms_;
target_level_ = std::max(target_level_, minimum_delay_packet_q8);
@@ -467,10 +464,6 @@
return true;
}
-int DelayManager::least_required_delay_ms() const {
- return least_required_delay_ms_;
-}
-
int DelayManager::base_target_level() const {
return base_target_level_;
}
diff --git a/modules/audio_coding/neteq/delay_manager.h b/modules/audio_coding/neteq/delay_manager.h
index 08004ea..00e39af 100644
--- a/modules/audio_coding/neteq/delay_manager.h
+++ b/modules/audio_coding/neteq/delay_manager.h
@@ -18,7 +18,6 @@
#include "modules/audio_coding/neteq/tick_timer.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -110,7 +109,6 @@
// Assuming |delay| is in valid range.
virtual bool SetMinimumDelay(int delay_ms);
virtual bool SetMaximumDelay(int delay_ms);
- virtual int least_required_delay_ms() const;
virtual int base_target_level() const;
virtual void set_streaming_mode(bool value);
virtual int last_pack_cng_or_dtmf() const;
@@ -162,10 +160,6 @@
uint16_t last_seq_no_; // Sequence number for last received packet.
uint32_t last_timestamp_; // Timestamp for the last received packet.
int minimum_delay_ms_; // Externally set minimum delay.
- int least_required_delay_ms_; // Smallest preferred buffer level (same unit
- // as |target_level_|), before applying
- // |minimum_delay_ms_| and/or
- // |maximum_delay_ms_|.
int maximum_delay_ms_; // Externally set maximum allowed delay.
int iat_cumulative_sum_; // Cumulative sum of delta inter-arrival times.
int max_iat_cumulative_sum_; // Max of |iat_cumulative_sum_|.
diff --git a/modules/audio_coding/neteq/delay_manager_unittest.cc b/modules/audio_coding/neteq/delay_manager_unittest.cc
index f9c5680..6afed66 100644
--- a/modules/audio_coding/neteq/delay_manager_unittest.cc
+++ b/modules/audio_coding/neteq/delay_manager_unittest.cc
@@ -200,7 +200,7 @@
EXPECT_EQ(lower + (20 << 8) / kFrameSizeMs, higher);
}
-TEST_F(DelayManagerTest, MaxAndRequiredDelay) {
+TEST_F(DelayManagerTest, MaxDelay) {
const int kExpectedTarget = 5;
const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
SetPacketAudioLength(kFrameSizeMs);
@@ -224,14 +224,13 @@
EXPECT_TRUE(dm_->SetMaximumDelay(kMaxDelayMs));
IncreaseTime(kTimeIncrement);
InsertNextPacket();
- EXPECT_EQ(kExpectedTarget * kFrameSizeMs, dm_->least_required_delay_ms());
EXPECT_EQ(kMaxDelayPackets << 8, dm_->TargetLevel());
// Target level at least should be one packet.
EXPECT_FALSE(dm_->SetMaximumDelay(kFrameSizeMs - 1));
}
-TEST_F(DelayManagerTest, MinAndRequiredDelay) {
+TEST_F(DelayManagerTest, MinDelay) {
const int kExpectedTarget = 5;
const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
SetPacketAudioLength(kFrameSizeMs);
@@ -255,7 +254,6 @@
dm_->SetMinimumDelay(kMinDelayMs);
IncreaseTime(kTimeIncrement);
InsertNextPacket();
- EXPECT_EQ(kExpectedTarget * kFrameSizeMs, dm_->least_required_delay_ms());
EXPECT_EQ(kMinDelayPackets << 8, dm_->TargetLevel());
}
diff --git a/modules/audio_coding/neteq/dsp_helper.h b/modules/audio_coding/neteq/dsp_helper.h
index 8940acd..efa2f9c 100644
--- a/modules/audio_coding/neteq/dsp_helper.h
+++ b/modules/audio_coding/neteq/dsp_helper.h
@@ -15,7 +15,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/dsp_helper_unittest.cc b/modules/audio_coding/neteq/dsp_helper_unittest.cc
index 9d5da5d..ec434a4 100644
--- a/modules/audio_coding/neteq/dsp_helper_unittest.cc
+++ b/modules/audio_coding/neteq/dsp_helper_unittest.cc
@@ -12,7 +12,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/dtmf_buffer.h b/modules/audio_coding/neteq/dtmf_buffer.h
index 1035e87..6de5127 100644
--- a/modules/audio_coding/neteq/dtmf_buffer.h
+++ b/modules/audio_coding/neteq/dtmf_buffer.h
@@ -15,7 +15,6 @@
#include <string> // size_t
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/dtmf_tone_generator.h b/modules/audio_coding/neteq/dtmf_tone_generator.h
index b91d221..a773ff3 100644
--- a/modules/audio_coding/neteq/dtmf_tone_generator.h
+++ b/modules/audio_coding/neteq/dtmf_tone_generator.h
@@ -13,7 +13,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/expand.h b/modules/audio_coding/neteq/expand.h
index 2fd4fae..4cfe7b9 100644
--- a/modules/audio_coding/neteq/expand.h
+++ b/modules/audio_coding/neteq/expand.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/include/neteq.h b/modules/audio_coding/neteq/include/neteq.h
index ce1448a..fdb73c5 100644
--- a/modules/audio_coding/neteq/include/neteq.h
+++ b/modules/audio_coding/neteq/include/neteq.h
@@ -24,7 +24,6 @@
#include "modules/audio_coding/neteq/neteq_decoder_enum.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -97,7 +96,7 @@
bool for_test_no_time_stretching = false; // Use only for testing.
};
- enum ReturnCodes { kOK = 0, kFail = -1, kNotImplemented = -2 };
+ enum ReturnCodes { kOK = 0, kFail = -1 };
// Creates a new NetEq object, with parameters set in |config|. The |config|
// object will only have to be valid for the duration of the call to this
@@ -181,15 +180,6 @@
// the |max_delay_ms| value in the NetEq::Config struct.
virtual bool SetMaximumDelay(int delay_ms) = 0;
- // The smallest latency required. This is computed bases on inter-arrival
- // time and internal NetEq logic. Note that in computing this latency none of
- // the user defined limits (applied by calling setMinimumDelay() and/or
- // SetMaximumDelay()) are applied.
- virtual int LeastRequiredDelayMs() const = 0;
-
- // Not implemented.
- virtual int SetTargetDelay() = 0;
-
// Returns the current target delay in ms. This includes any extra delay
// requested through SetMinimumDelay.
virtual int TargetDelayMs() const = 0;
@@ -242,12 +232,6 @@
virtual absl::optional<SdpAudioFormat> GetDecoderFormat(
int payload_type) const = 0;
- // Not implemented.
- virtual int SetTargetNumberOfChannels() = 0;
-
- // Not implemented.
- virtual int SetTargetSampleRate() = 0;
-
// Flushes both the packet buffer and the sync buffer.
virtual void FlushBuffers() = 0;
diff --git a/modules/audio_coding/neteq/merge.h b/modules/audio_coding/neteq/merge.h
index 017e824..235c07f 100644
--- a/modules/audio_coding/neteq/merge.h
+++ b/modules/audio_coding/neteq/merge.h
@@ -15,7 +15,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h b/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
index 5aed6a9..1fb3db5 100644
--- a/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
+++ b/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h
@@ -15,7 +15,6 @@
#include "modules/audio_coding/codecs/pcm16b/pcm16b.h"
#include "rtc_base/constructormagic.h"
#include "test/gmock.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/nack_tracker_unittest.cc b/modules/audio_coding/neteq/nack_tracker_unittest.cc
index 19adf30..a44f41b 100644
--- a/modules/audio_coding/neteq/nack_tracker_unittest.cc
+++ b/modules/audio_coding/neteq/nack_tracker_unittest.cc
@@ -17,7 +17,6 @@
#include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index 0ef3263..ddcd221 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -307,16 +307,6 @@
return false;
}
-int NetEqImpl::LeastRequiredDelayMs() const {
- rtc::CritScope lock(&crit_sect_);
- assert(delay_manager_.get());
- return delay_manager_->least_required_delay_ms();
-}
-
-int NetEqImpl::SetTargetDelay() {
- return kNotImplemented;
-}
-
int NetEqImpl::TargetDelayMs() const {
rtc::CritScope lock(&crit_sect_);
RTC_DCHECK(delay_manager_.get());
@@ -454,14 +444,6 @@
return di->GetFormat();
}
-int NetEqImpl::SetTargetNumberOfChannels() {
- return kNotImplemented;
-}
-
-int NetEqImpl::SetTargetSampleRate() {
- return kNotImplemented;
-}
-
void NetEqImpl::FlushBuffers() {
rtc::CritScope lock(&crit_sect_);
RTC_LOG(LS_VERBOSE) << "FlushBuffers";
diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h
index 6b8764d..68fdf3c 100644
--- a/modules/audio_coding/neteq/neteq_impl.h
+++ b/modules/audio_coding/neteq/neteq_impl.h
@@ -28,7 +28,6 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/thread_annotations.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -158,10 +157,6 @@
bool SetMaximumDelay(int delay_ms) override;
- int LeastRequiredDelayMs() const override;
-
- int SetTargetDelay() override;
-
int TargetDelayMs() const override;
int CurrentDelayMs() const override;
@@ -197,10 +192,6 @@
absl::optional<SdpAudioFormat> GetDecoderFormat(
int payload_type) const override;
- int SetTargetNumberOfChannels() override;
-
- int SetTargetSampleRate() override;
-
// Flushes both the packet buffer and the sync buffer.
void FlushBuffers() override;
diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc
index 5d43fdb..96a392b 100644
--- a/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_unittest.cc
@@ -33,10 +33,10 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/protobuf_utils.h"
#include "rtc_base/stringencode.h"
+#include "rtc_base/system/arch.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
-#include "typedefs.h" // NOLINT(build/include)
// This must come after test/gtest.h
#include "rtc_base/flags.h" // NOLINT(build/include)
diff --git a/modules/audio_coding/neteq/normal.h b/modules/audio_coding/neteq/normal.h
index 41bd30a..b13f16e 100644
--- a/modules/audio_coding/neteq/normal.h
+++ b/modules/audio_coding/neteq/normal.h
@@ -20,7 +20,6 @@
#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/numerics/safe_conversions.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/packet.h b/modules/audio_coding/neteq/packet.h
index 61b0144..45c56e1 100644
--- a/modules/audio_coding/neteq/packet.h
+++ b/modules/audio_coding/neteq/packet.h
@@ -17,7 +17,6 @@
#include "api/audio_codecs/audio_decoder.h"
#include "modules/audio_coding/neteq/tick_timer.h"
#include "rtc_base/buffer.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/packet_buffer.h b/modules/audio_coding/neteq/packet_buffer.h
index 74f36a5..7e34c1e 100644
--- a/modules/audio_coding/neteq/packet_buffer.h
+++ b/modules/audio_coding/neteq/packet_buffer.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/packet.h"
#include "modules/include/module_common_types.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/post_decode_vad.h b/modules/audio_coding/neteq/post_decode_vad.h
index dac95f0..ad4f082 100644
--- a/modules/audio_coding/neteq/post_decode_vad.h
+++ b/modules/audio_coding/neteq/post_decode_vad.h
@@ -19,7 +19,6 @@
#include "modules/audio_coding/neteq/defines.h"
#include "modules/audio_coding/neteq/packet.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/preemptive_expand.h b/modules/audio_coding/neteq/preemptive_expand.h
index 197d3f1..4d72616 100644
--- a/modules/audio_coding/neteq/preemptive_expand.h
+++ b/modules/audio_coding/neteq/preemptive_expand.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "modules/audio_coding/neteq/time_stretch.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/random_vector.h b/modules/audio_coding/neteq/random_vector.h
index 2c6e06c..e8c7ba8 100644
--- a/modules/audio_coding/neteq/random_vector.h
+++ b/modules/audio_coding/neteq/random_vector.h
@@ -11,10 +11,10 @@
#ifndef MODULES_AUDIO_CODING_NETEQ_RANDOM_VECTOR_H_
#define MODULES_AUDIO_CODING_NETEQ_RANDOM_VECTOR_H_
-#include <string.h> // size_t
+#include <stddef.h>
+#include <stdint.h>
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/rtcp.h b/modules/audio_coding/neteq/rtcp.h
index 45bb058..b1de7eb 100644
--- a/modules/audio_coding/neteq/rtcp.h
+++ b/modules/audio_coding/neteq/rtcp.h
@@ -13,7 +13,6 @@
#include "modules/audio_coding/neteq/include/neteq.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/statistics_calculator.h b/modules/audio_coding/neteq/statistics_calculator.h
index 42fd4c9..5f7d06a 100644
--- a/modules/audio_coding/neteq/statistics_calculator.h
+++ b/modules/audio_coding/neteq/statistics_calculator.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/include/neteq.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/sync_buffer.h b/modules/audio_coding/neteq/sync_buffer.h
index 8a35326..3833cb2 100644
--- a/modules/audio_coding/neteq/sync_buffer.h
+++ b/modules/audio_coding/neteq/sync_buffer.h
@@ -14,7 +14,6 @@
#include "api/audio/audio_frame.h"
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/tick_timer.h b/modules/audio_coding/neteq/tick_timer.h
index 4a9ade5..520099e 100644
--- a/modules/audio_coding/neteq/tick_timer.h
+++ b/modules/audio_coding/neteq/tick_timer.h
@@ -15,7 +15,6 @@
#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/time_stretch.h b/modules/audio_coding/neteq/time_stretch.h
index 606d1d0..13ad2c8 100644
--- a/modules/audio_coding/neteq/time_stretch.h
+++ b/modules/audio_coding/neteq/time_stretch.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/audio_multi_vector.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/timestamp_scaler.h b/modules/audio_coding/neteq/timestamp_scaler.h
index f0b05d6..62f535c 100644
--- a/modules/audio_coding/neteq/timestamp_scaler.h
+++ b/modules/audio_coding/neteq/timestamp_scaler.h
@@ -13,7 +13,6 @@
#include "modules/audio_coding/neteq/packet.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/tools/audio_checksum.h b/modules/audio_coding/neteq/tools/audio_checksum.h
index db67edf..ee8c582 100644
--- a/modules/audio_coding/neteq/tools/audio_checksum.h
+++ b/modules/audio_coding/neteq/tools/audio_checksum.h
@@ -19,7 +19,7 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/messagedigest.h"
#include "rtc_base/stringencode.h"
-#include "typedefs.h" // NOLINT(build/include)
+#include "rtc_base/system/arch.h"
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/audio_loop.h b/modules/audio_coding/neteq/tools/audio_loop.h
index 876c2d7..c7788a6 100644
--- a/modules/audio_coding/neteq/tools/audio_loop.h
+++ b/modules/audio_coding/neteq/tools/audio_loop.h
@@ -16,7 +16,6 @@
#include "api/array_view.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/audio_sink.h b/modules/audio_coding/neteq/tools/audio_sink.h
index 05e6fe8..be2a315 100644
--- a/modules/audio_coding/neteq/tools/audio_sink.h
+++ b/modules/audio_coding/neteq/tools/audio_sink.h
@@ -13,7 +13,6 @@
#include "api/audio/audio_frame.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/encode_neteq_input.cc b/modules/audio_coding/neteq/tools/encode_neteq_input.cc
index f0d5b6f..c576670 100644
--- a/modules/audio_coding/neteq/tools/encode_neteq_input.cc
+++ b/modules/audio_coding/neteq/tools/encode_neteq_input.cc
@@ -27,6 +27,8 @@
CreatePacket();
}
+EncodeNetEqInput::~EncodeNetEqInput() = default;
+
absl::optional<int64_t> EncodeNetEqInput::NextPacketTime() const {
RTC_DCHECK(packet_data_);
return static_cast<int64_t>(packet_data_->time_ms);
@@ -50,6 +52,10 @@
next_output_event_ms_ += kOutputPeriodMs;
}
+bool EncodeNetEqInput::ended() const {
+ return next_output_event_ms_ <= input_duration_ms_;
+}
+
absl::optional<RTPHeader> EncodeNetEqInput::NextHeader() const {
RTC_DCHECK(packet_data_);
return packet_data_->header;
diff --git a/modules/audio_coding/neteq/tools/encode_neteq_input.h b/modules/audio_coding/neteq/tools/encode_neteq_input.h
index a75262b..caa9ac7 100644
--- a/modules/audio_coding/neteq/tools/encode_neteq_input.h
+++ b/modules/audio_coding/neteq/tools/encode_neteq_input.h
@@ -35,6 +35,7 @@
EncodeNetEqInput(std::unique_ptr<Generator> generator,
std::unique_ptr<AudioEncoder> encoder,
int64_t input_duration_ms);
+ ~EncodeNetEqInput() override;
absl::optional<int64_t> NextPacketTime() const override;
@@ -44,9 +45,7 @@
void AdvanceOutputEvent() override;
- bool ended() const override {
- return next_output_event_ms_ <= input_duration_ms_;
- }
+ bool ended() const override;
absl::optional<RTPHeader> NextHeader() const override;
diff --git a/modules/audio_coding/neteq/tools/input_audio_file.h b/modules/audio_coding/neteq/tools/input_audio_file.h
index db5a944..b36dc24 100644
--- a/modules/audio_coding/neteq/tools/input_audio_file.h
+++ b/modules/audio_coding/neteq/tools/input_audio_file.h
@@ -16,7 +16,6 @@
#include <string>
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h b/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h
index 5099e03..f6b895a 100644
--- a/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h
+++ b/modules/audio_coding/neteq/tools/neteq_delay_analyzer.h
@@ -19,7 +19,6 @@
#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/tools/neteq_input.h"
#include "modules/audio_coding/neteq/tools/neteq_test.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/neteq_input.cc b/modules/audio_coding/neteq/tools/neteq_input.cc
index fed3ecc..bb2a01e 100644
--- a/modules/audio_coding/neteq/tools/neteq_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_input.cc
@@ -15,6 +15,9 @@
namespace webrtc {
namespace test {
+NetEqInput::PacketData::PacketData() = default;
+NetEqInput::PacketData::~PacketData() = default;
+
std::string NetEqInput::PacketData::ToString() const {
std::stringstream ss;
ss << "{"
@@ -34,6 +37,8 @@
start_time_ms_(input_->NextEventTime()),
duration_ms_(duration_ms) {}
+TimeLimitedNetEqInput::~TimeLimitedNetEqInput() = default;
+
absl::optional<int64_t> TimeLimitedNetEqInput::NextPacketTime() const {
return ended_ ? absl::nullopt : input_->NextPacketTime();
}
diff --git a/modules/audio_coding/neteq/tools/neteq_input.h b/modules/audio_coding/neteq/tools/neteq_input.h
index 1691585..b9cba09 100644
--- a/modules/audio_coding/neteq/tools/neteq_input.h
+++ b/modules/audio_coding/neteq/tools/neteq_input.h
@@ -28,6 +28,8 @@
class NetEqInput {
public:
struct PacketData {
+ PacketData();
+ ~PacketData();
std::string ToString() const;
RTPHeader header;
@@ -84,6 +86,7 @@
class TimeLimitedNetEqInput : public NetEqInput {
public:
TimeLimitedNetEqInput(std::unique_ptr<NetEqInput> input, int64_t duration_ms);
+ ~TimeLimitedNetEqInput() override;
absl::optional<int64_t> NextPacketTime() const override;
absl::optional<int64_t> NextOutputEventTime() const override;
std::unique_ptr<PacketData> PopPacket() override;
diff --git a/modules/audio_coding/neteq/tools/neteq_performance_test.cc b/modules/audio_coding/neteq/tools/neteq_performance_test.cc
index e0dfebf..52524fe 100644
--- a/modules/audio_coding/neteq/tools/neteq_performance_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_performance_test.cc
@@ -20,7 +20,6 @@
#include "rtc_base/checks.h"
#include "system_wrappers/include/clock.h"
#include "test/testsupport/fileutils.h"
-#include "typedefs.h" // NOLINT(build/include)
using webrtc::NetEq;
using webrtc::test::AudioLoop;
diff --git a/modules/audio_coding/neteq/tools/neteq_performance_test.h b/modules/audio_coding/neteq/tools/neteq_performance_test.h
index dcf0314..d2212f0 100644
--- a/modules/audio_coding/neteq/tools/neteq_performance_test.h
+++ b/modules/audio_coding/neteq/tools/neteq_performance_test.h
@@ -11,7 +11,7 @@
#ifndef MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PERFORMANCE_TEST_H_
#define MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_PERFORMANCE_TEST_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/neteq_quality_test.h b/modules/audio_coding/neteq/tools/neteq_quality_test.h
index b19460c..3d7760e 100644
--- a/modules/audio_coding/neteq/tools/neteq_quality_test.h
+++ b/modules/audio_coding/neteq/tools/neteq_quality_test.h
@@ -21,7 +21,6 @@
#include "modules/audio_coding/neteq/tools/rtp_generator.h"
#include "rtc_base/flags.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/neteq_replacement_input.cc b/modules/audio_coding/neteq/tools/neteq_replacement_input.cc
index 6aa7581..362eb89 100644
--- a/modules/audio_coding/neteq/tools/neteq_replacement_input.cc
+++ b/modules/audio_coding/neteq/tools/neteq_replacement_input.cc
@@ -28,7 +28,6 @@
RTC_CHECK(source_);
packet_ = source_->PopPacket();
ReplacePacket();
- RTC_CHECK(packet_);
}
absl::optional<int64_t> NetEqReplacementInput::NextPacketTime() const {
diff --git a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
index 7f1263c..bf782bf 100644
--- a/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
+++ b/modules/audio_coding/neteq/tools/neteq_rtpplay.cc
@@ -31,8 +31,8 @@
#include "modules/audio_coding/neteq/tools/rtp_file_source.h"
#include "rtc_base/checks.h"
#include "rtc_base/flags.h"
+#include "test/field_trial.h"
#include "test/testsupport/fileutils.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
@@ -133,6 +133,12 @@
"Generates a python script for plotting the delay profile");
DEFINE_bool(help, false, "Prints this message");
DEFINE_bool(concealment_events, false, "Prints concealment events");
+DEFINE_string(
+ force_fieldtrials,
+ "",
+ "Field trials control experimental feature code which can be forced. "
+ "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enable/"
+ " will assign the group Enable to field trial WebRTC-FooFeature.");
// Maps a codec type to a printable name string.
std::string CodecName(NetEqDecoder codec) {
@@ -293,6 +299,10 @@
std::cout << usage;
return 0;
}
+
+ ValidateFieldTrialsStringOrDie(FLAG_force_fieldtrials);
+ ScopedFieldTrials field_trials(FLAG_force_fieldtrials);
+
RTC_CHECK(ValidatePayloadType(FLAG_pcmu));
RTC_CHECK(ValidatePayloadType(FLAG_pcma));
RTC_CHECK(ValidatePayloadType(FLAG_ilbc));
@@ -398,32 +408,38 @@
std::cout << "Output file: " << output_file_name << std::endl;
NetEqTest::DecoderMap codecs = {
- {FLAG_pcmu, std::make_pair(NetEqDecoder::kDecoderPCMu, "pcmu")},
- {FLAG_pcma, std::make_pair(NetEqDecoder::kDecoderPCMa, "pcma")},
- {FLAG_ilbc, std::make_pair(NetEqDecoder::kDecoderILBC, "ilbc")},
- {FLAG_isac, std::make_pair(NetEqDecoder::kDecoderISAC, "isac")},
- {FLAG_isac_swb,
- std::make_pair(NetEqDecoder::kDecoderISACswb, "isac-swb")},
- {FLAG_opus, std::make_pair(NetEqDecoder::kDecoderOpus, "opus")},
- {FLAG_pcm16b, std::make_pair(NetEqDecoder::kDecoderPCM16B, "pcm16-nb")},
- {FLAG_pcm16b_wb,
- std::make_pair(NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb")},
- {FLAG_pcm16b_swb32,
- std::make_pair(NetEqDecoder::kDecoderPCM16Bswb32kHz, "pcm16-swb32")},
- {FLAG_pcm16b_swb48,
- std::make_pair(NetEqDecoder::kDecoderPCM16Bswb48kHz, "pcm16-swb48")},
- {FLAG_g722, std::make_pair(NetEqDecoder::kDecoderG722, "g722")},
- {FLAG_avt, std::make_pair(NetEqDecoder::kDecoderAVT, "avt")},
- {FLAG_avt_16, std::make_pair(NetEqDecoder::kDecoderAVT16kHz, "avt-16")},
- {FLAG_avt_32, std::make_pair(NetEqDecoder::kDecoderAVT32kHz, "avt-32")},
- {FLAG_avt_48, std::make_pair(NetEqDecoder::kDecoderAVT48kHz, "avt-48")},
- {FLAG_red, std::make_pair(NetEqDecoder::kDecoderRED, "red")},
- {FLAG_cn_nb, std::make_pair(NetEqDecoder::kDecoderCNGnb, "cng-nb")},
- {FLAG_cn_wb, std::make_pair(NetEqDecoder::kDecoderCNGwb, "cng-wb")},
- {FLAG_cn_swb32,
- std::make_pair(NetEqDecoder::kDecoderCNGswb32kHz, "cng-swb32")},
- {FLAG_cn_swb48,
- std::make_pair(NetEqDecoder::kDecoderCNGswb48kHz, "cng-swb48")}};
+ {FLAG_pcmu, std::make_pair(NetEqDecoder::kDecoderPCMu, "pcmu")},
+ {FLAG_pcma, std::make_pair(NetEqDecoder::kDecoderPCMa, "pcma")},
+#ifdef WEBRTC_CODEC_ILBC
+ {FLAG_ilbc, std::make_pair(NetEqDecoder::kDecoderILBC, "ilbc")},
+#endif
+ {FLAG_isac, std::make_pair(NetEqDecoder::kDecoderISAC, "isac")},
+#if !defined(WEBRTC_ANDROID)
+ {FLAG_isac_swb, std::make_pair(NetEqDecoder::kDecoderISACswb, "isac-swb")},
+#endif
+#ifdef WEBRTC_CODEC_OPUS
+ {FLAG_opus, std::make_pair(NetEqDecoder::kDecoderOpus, "opus")},
+#endif
+ {FLAG_pcm16b, std::make_pair(NetEqDecoder::kDecoderPCM16B, "pcm16-nb")},
+ {FLAG_pcm16b_wb,
+ std::make_pair(NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb")},
+ {FLAG_pcm16b_swb32,
+ std::make_pair(NetEqDecoder::kDecoderPCM16Bswb32kHz, "pcm16-swb32")},
+ {FLAG_pcm16b_swb48,
+ std::make_pair(NetEqDecoder::kDecoderPCM16Bswb48kHz, "pcm16-swb48")},
+ {FLAG_g722, std::make_pair(NetEqDecoder::kDecoderG722, "g722")},
+ {FLAG_avt, std::make_pair(NetEqDecoder::kDecoderAVT, "avt")},
+ {FLAG_avt_16, std::make_pair(NetEqDecoder::kDecoderAVT16kHz, "avt-16")},
+ {FLAG_avt_32, std::make_pair(NetEqDecoder::kDecoderAVT32kHz, "avt-32")},
+ {FLAG_avt_48, std::make_pair(NetEqDecoder::kDecoderAVT48kHz, "avt-48")},
+ {FLAG_red, std::make_pair(NetEqDecoder::kDecoderRED, "red")},
+ {FLAG_cn_nb, std::make_pair(NetEqDecoder::kDecoderCNGnb, "cng-nb")},
+ {FLAG_cn_wb, std::make_pair(NetEqDecoder::kDecoderCNGwb, "cng-wb")},
+ {FLAG_cn_swb32,
+ std::make_pair(NetEqDecoder::kDecoderCNGswb32kHz, "cng-swb32")},
+ {FLAG_cn_swb48,
+ std::make_pair(NetEqDecoder::kDecoderCNGswb48kHz, "cng-swb48")}
+ };
// Check if a replacement audio file was provided.
std::unique_ptr<AudioDecoder> replacement_decoder;
diff --git a/modules/audio_coding/neteq/tools/neteq_test.cc b/modules/audio_coding/neteq/tools/neteq_test.cc
index e2bed56..3448f4e 100644
--- a/modules/audio_coding/neteq/tools/neteq_test.cc
+++ b/modules/audio_coding/neteq/tools/neteq_test.cc
@@ -46,6 +46,8 @@
RegisterExternalDecoders(ext_codecs);
}
+NetEqTest::~NetEqTest() = default;
+
int64_t NetEqTest::Run() {
const int64_t start_time_ms = *input_->NextEventTime();
int64_t time_now_ms = start_time_ms;
diff --git a/modules/audio_coding/neteq/tools/neteq_test.h b/modules/audio_coding/neteq/tools/neteq_test.h
index 9c05fc4..ada6bab 100644
--- a/modules/audio_coding/neteq/tools/neteq_test.h
+++ b/modules/audio_coding/neteq/tools/neteq_test.h
@@ -82,7 +82,7 @@
std::unique_ptr<AudioSink> output,
Callbacks callbacks);
- ~NetEqTest() = default;
+ ~NetEqTest();
// Runs the test. Returns the duration of the produced audio in ms.
int64_t Run();
diff --git a/modules/audio_coding/neteq/tools/packet.h b/modules/audio_coding/neteq/tools/packet.h
index 2c9a26f..623c5cb 100644
--- a/modules/audio_coding/neteq/tools/packet.h
+++ b/modules/audio_coding/neteq/tools/packet.h
@@ -17,7 +17,6 @@
#include "api/rtp_headers.h" // NOLINT(build/include)
#include "common_types.h" // NOLINT(build/include)
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_coding/neteq/tools/packet_source.h b/modules/audio_coding/neteq/tools/packet_source.h
index 3f98ba1..fb689e3 100644
--- a/modules/audio_coding/neteq/tools/packet_source.h
+++ b/modules/audio_coding/neteq/tools/packet_source.h
@@ -16,7 +16,6 @@
#include "modules/audio_coding/neteq/tools/packet.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/resample_input_audio_file.h b/modules/audio_coding/neteq/tools/resample_input_audio_file.h
index 13c419d..4e2e9b0 100644
--- a/modules/audio_coding/neteq/tools/resample_input_audio_file.h
+++ b/modules/audio_coding/neteq/tools/resample_input_audio_file.h
@@ -16,7 +16,6 @@
#include "common_audio/resampler/include/resampler.h"
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/rtp_encode.cc b/modules/audio_coding/neteq/tools/rtp_encode.cc
index abbb621..5065ca1 100644
--- a/modules/audio_coding/neteq/tools/rtp_encode.cc
+++ b/modules/audio_coding/neteq/tools/rtp_encode.cc
@@ -34,7 +34,6 @@
#include "modules/audio_coding/neteq/tools/input_audio_file.h"
#include "rtc_base/flags.h"
#include "rtc_base/numerics/safe_conversions.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/rtp_file_source.h b/modules/audio_coding/neteq/tools/rtp_file_source.h
index b44bc64..013333b 100644
--- a/modules/audio_coding/neteq/tools/rtp_file_source.h
+++ b/modules/audio_coding/neteq/tools/rtp_file_source.h
@@ -39,7 +39,7 @@
static bool ValidRtpDump(const std::string& file_name);
static bool ValidPcap(const std::string& file_name);
- virtual ~RtpFileSource();
+ ~RtpFileSource() override;
// Registers an RTP header extension and binds it to |id|.
virtual bool RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
diff --git a/modules/audio_coding/neteq/tools/rtp_generator.h b/modules/audio_coding/neteq/tools/rtp_generator.h
index 04fdbdd..ca7b04f 100644
--- a/modules/audio_coding/neteq/tools/rtp_generator.h
+++ b/modules/audio_coding/neteq/tools/rtp_generator.h
@@ -14,7 +14,6 @@
#include "api/rtp_headers.h"
#include "common_types.h" // NOLINT(build/include)
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_coding/neteq/tools/rtp_jitter.cc b/modules/audio_coding/neteq/tools/rtp_jitter.cc
index d92fed0..3c49443 100644
--- a/modules/audio_coding/neteq/tools/rtp_jitter.cc
+++ b/modules/audio_coding/neteq/tools/rtp_jitter.cc
@@ -18,7 +18,6 @@
#include "modules/rtp_rtcp/source/byte_io.h"
#include "rtc_base/buffer.h"
#include "rtc_base/flags.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace test {
diff --git a/modules/audio_processing/BUILD.gn b/modules/audio_processing/BUILD.gn
index 4be7d8f..052bb47 100644
--- a/modules/audio_processing/BUILD.gn
+++ b/modules/audio_processing/BUILD.gn
@@ -37,8 +37,12 @@
"common.h",
"echo_cancellation_impl.cc",
"echo_cancellation_impl.h",
+ "echo_cancellation_proxy.cc",
+ "echo_cancellation_proxy.h",
"echo_control_mobile_impl.cc",
"echo_control_mobile_impl.h",
+ "echo_control_mobile_proxy.cc",
+ "echo_control_mobile_proxy.h",
"echo_detector/circular_buffer.cc",
"echo_detector/circular_buffer.h",
"echo_detector/mean_variance_estimator.cc",
@@ -101,7 +105,6 @@
":audio_processing_c",
":audio_processing_statistics",
":gain_control_interface",
- "../..:typedefs",
"../..:webrtc_common",
"../../api:array_view",
"../../api/audio:aec3_config",
@@ -109,12 +112,13 @@
"../../api/audio:echo_control",
"../../audio/utility:audio_frame_operations",
"../../common_audio:common_audio_c",
- "../../common_audio:fft4g",
+ "../../common_audio/third_party/fft4g:fft4g",
"../../rtc_base:checks",
"../../rtc_base:deprecation",
"../../rtc_base:gtest_prod",
"../../rtc_base:safe_minmax",
"../../rtc_base:sanitizer",
+ "../../rtc_base/system:arch",
"../../system_wrappers:cpu_features_api",
"../../system_wrappers:field_trial_api",
"../../system_wrappers:metrics_api",
@@ -134,18 +138,6 @@
defines += [ "WEBRTC_UNTRUSTED_DELAY" ]
}
- if (rtc_enable_intelligibility_enhancer) {
- defines += [ "WEBRTC_INTELLIGIBILITY_ENHANCER=1" ]
- sources += [
- "intelligibility/intelligibility_enhancer.cc",
- "intelligibility/intelligibility_enhancer.h",
- "intelligibility/intelligibility_utils.cc",
- "intelligibility/intelligibility_utils.h",
- ]
- } else {
- defines += [ "WEBRTC_INTELLIGIBILITY_ENHANCER=0" ]
- }
-
if (rtc_prefer_fixed_point) {
defines += [ "WEBRTC_NS_FIXED" ]
} else {
@@ -257,11 +249,10 @@
}
deps = [
- "../..:typedefs",
"../..:webrtc_common",
"../../common_audio",
"../../common_audio:common_audio_c",
- "../../common_audio:fft4g",
+ "../../common_audio/third_party/fft4g:fft4g",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
"../../system_wrappers:cpu_features_api",
@@ -272,9 +263,7 @@
sources += [ "ns/nsx_core_neon.c" ]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags = [ "-mfpu=neon" ]
}
@@ -336,10 +325,6 @@
":transient_suppression_test",
]
- if (rtc_enable_intelligibility_enhancer) {
- deps += [ ":intelligibility_proc" ]
- }
-
if (rtc_enable_protobuf) {
deps += [
":audioproc_f",
@@ -382,7 +367,6 @@
":audioproc_test_utils",
":file_audio_generator_unittests",
":mocks",
- "../..:typedefs",
"../..:webrtc_common",
"../../api:array_view",
"../../api/audio:aec3_config",
@@ -395,6 +379,7 @@
"../../rtc_base:rtc_base",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:safe_minmax",
+ "../../rtc_base/system:arch",
"../../rtc_base/system:file_wrapper",
"../../system_wrappers",
"../../system_wrappers:cpu_features_api",
@@ -421,16 +406,6 @@
defines = []
- if (rtc_enable_intelligibility_enhancer) {
- defines += [ "WEBRTC_INTELLIGIBILITY_ENHANCER=1" ]
- sources += [
- "intelligibility/intelligibility_enhancer_unittest.cc",
- "intelligibility/intelligibility_utils_unittest.cc",
- ]
- } else {
- defines += [ "WEBRTC_INTELLIGIBILITY_ENHANCER=0" ]
- }
-
if (rtc_prefer_fixed_point) {
defines += [ "WEBRTC_AUDIOPROC_FIXED_PROFILE" ]
} else {
@@ -445,6 +420,7 @@
":audioproc_test_utils",
":audioproc_unittest_proto",
"../../api/audio:audio_frame_api",
+ "../../rtc_base:rtc_base_tests_utils",
"../../rtc_base:rtc_task_queue",
"aec_dump",
"aec_dump:aec_dump_unittests",
@@ -498,12 +474,6 @@
"../../test:perf_test",
"../../test:test_support",
]
-
- if (rtc_enable_intelligibility_enhancer) {
- defines = [ "WEBRTC_INTELLIGIBILITY_ENHANCER=1" ]
- } else {
- defines = [ "WEBRTC_INTELLIGIBILITY_ENHANCER=0" ]
- }
}
rtc_source_set("file_audio_generator_unittests") {
@@ -616,6 +586,7 @@
"../../common_audio",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
+ "../../rtc_base/system:arch",
"../../system_wrappers",
"../../test:fileutils",
"../../test:test_support",
@@ -634,7 +605,6 @@
]
deps = [
":audio_processing",
- "../..:typedefs",
"../..:webrtc_common",
"../../common_audio:common_audio",
"../../rtc_base:rtc_base_approved",
@@ -657,7 +627,6 @@
]
deps = [
":audio_processing",
- "../..:typedefs",
"../..:webrtc_common",
"../../rtc_base/system:file_wrapper",
"../../system_wrappers",
@@ -665,24 +634,6 @@
]
}
- if (rtc_enable_intelligibility_enhancer) {
- rtc_executable("intelligibility_proc") {
- testonly = true
- sources = [
- "intelligibility/test/intelligibility_proc.cc",
- ]
- deps = [
- ":audio_processing",
- ":audioproc_test_utils",
- "../../common_audio",
- "../../rtc_base:rtc_base_approved",
- "../../system_wrappers:metrics_default",
- "../../test:test_support",
- "//testing/gtest",
- ]
- }
- }
-
if (rtc_enable_protobuf) {
proto_library("audioproc_unittest_proto") {
sources = [
@@ -699,10 +650,10 @@
deps = [
":audioproc_debug_proto",
- "../..:typedefs",
"../..:webrtc_common",
"../../rtc_base:protobuf_utils",
"../../rtc_base:rtc_base_approved",
+ "../../rtc_base/system:arch",
]
}
}
diff --git a/modules/audio_processing/aec/BUILD.gn b/modules/audio_processing/aec/BUILD.gn
index 5a858f5..52441d7 100644
--- a/modules/audio_processing/aec/BUILD.gn
+++ b/modules/audio_processing/aec/BUILD.gn
@@ -19,7 +19,6 @@
deps = [
":aec_core",
"..:apm_logging",
- "../../..:typedefs",
"../../../common_audio:common_audio_c",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
@@ -36,10 +35,10 @@
]
deps = [
"..:apm_logging",
- "../../..:typedefs",
"../../../common_audio:common_audio_c",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
+ "../../../rtc_base/system:arch",
"../../../system_wrappers:cpu_features_api",
"../../../system_wrappers:metrics_api",
"../utility:block_mean_calculator",
@@ -59,9 +58,7 @@
sources += [ "aec_core_neon.cc" ]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags += [ "-mfpu=neon" ]
}
@@ -94,7 +91,6 @@
deps = [
":aec",
":aec_core",
- "../../..:typedefs",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../test:test_support",
diff --git a/modules/audio_processing/aec/aec_common.h b/modules/audio_processing/aec/aec_common.h
index 80c5c14..ac1f339 100644
--- a/modules/audio_processing/aec/aec_common.h
+++ b/modules/audio_processing/aec/aec_common.h
@@ -11,8 +11,6 @@
#ifndef MODULES_AUDIO_PROCESSING_AEC_AEC_COMMON_H_
#define MODULES_AUDIO_PROCESSING_AEC_AEC_COMMON_H_
-#include "typedefs.h" // NOLINT(build/include)
-
#ifdef _MSC_VER /* visual c++ */
#define ALIGN16_BEG __declspec(align(16))
#define ALIGN16_END
diff --git a/modules/audio_processing/aec/aec_core.cc b/modules/audio_processing/aec/aec_core.cc
index 95ed595..5a8cf8f 100644
--- a/modules/audio_processing/aec/aec_core.cc
+++ b/modules/audio_processing/aec/aec_core.cc
@@ -30,9 +30,9 @@
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "modules/audio_processing/utility/delay_estimator_wrapper.h"
#include "rtc_base/checks.h"
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "system_wrappers/include/metrics.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/modules/audio_processing/aec/aec_core.h b/modules/audio_processing/aec/aec_core.h
index 9e25292..35a6c9b 100644
--- a/modules/audio_processing/aec/aec_core.h
+++ b/modules/audio_processing/aec/aec_core.h
@@ -26,7 +26,6 @@
#include "modules/audio_processing/utility/block_mean_calculator.h"
#include "modules/audio_processing/utility/ooura_fft.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/aec/aec_core_optimized_methods.h b/modules/audio_processing/aec/aec_core_optimized_methods.h
index a8a20e9..03c027d 100644
--- a/modules/audio_processing/aec/aec_core_optimized_methods.h
+++ b/modules/audio_processing/aec/aec_core_optimized_methods.h
@@ -14,7 +14,6 @@
#include <memory>
#include "modules/audio_processing/aec/aec_core.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/aec/echo_cancellation.cc b/modules/audio_processing/aec/echo_cancellation.cc
index c8382ec..fd1aec4 100644
--- a/modules/audio_processing/aec/echo_cancellation.cc
+++ b/modules/audio_processing/aec/echo_cancellation.cc
@@ -24,7 +24,6 @@
#include "modules/audio_processing/aec/aec_core.h"
#include "modules/audio_processing/aec/aec_resampler.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/aec/echo_cancellation.h b/modules/audio_processing/aec/echo_cancellation.h
index d5c703e..2039347 100644
--- a/modules/audio_processing/aec/echo_cancellation.h
+++ b/modules/audio_processing/aec/echo_cancellation.h
@@ -19,7 +19,6 @@
#include "common_audio/ring_buffer.h"
}
#include "modules/audio_processing/aec/aec_core.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/aec/system_delay_unittest.cc b/modules/audio_processing/aec/system_delay_unittest.cc
index 01119db..9c57e8b 100644
--- a/modules/audio_processing/aec/system_delay_unittest.cc
+++ b/modules/audio_processing/aec/system_delay_unittest.cc
@@ -12,7 +12,6 @@
#include "modules/audio_processing/aec/echo_cancellation.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/modules/audio_processing/aec3/BUILD.gn b/modules/audio_processing/aec3/BUILD.gn
index f27168d..75ee372 100644
--- a/modules/audio_processing/aec3/BUILD.gn
+++ b/modules/audio_processing/aec3/BUILD.gn
@@ -20,6 +20,8 @@
"aec3_fft.h",
"aec_state.cc",
"aec_state.h",
+ "block_delay_buffer.cc",
+ "block_delay_buffer.h",
"block_framer.cc",
"block_framer.h",
"block_processor.cc",
@@ -28,8 +30,6 @@
"block_processor_metrics.h",
"cascaded_biquad_filter.cc",
"cascaded_biquad_filter.h",
- "coherence_gain.cc",
- "coherence_gain.h",
"comfort_noise_generator.cc",
"comfort_noise_generator.h",
"decimator.cc",
@@ -82,6 +82,10 @@
"render_signal_analyzer.h",
"residual_echo_estimator.cc",
"residual_echo_estimator.h",
+ "reverb_decay_estimator.cc",
+ "reverb_decay_estimator.h",
+ "reverb_frequency_response.cc",
+ "reverb_frequency_response.h",
"reverb_model.cc",
"reverb_model.h",
"reverb_model_estimator.cc",
@@ -112,10 +116,14 @@
]
defines = []
+ if (rtc_build_with_neon && current_cpu != "arm64") {
+ suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
+ cflags = [ "-mfpu=neon" ]
+ }
+
deps = [
"..:apm_logging",
"..:audio_processing",
- "../../..:typedefs",
"../../../api:array_view",
"../../../api/audio:aec3_config",
"../../../api/audio:echo_control",
@@ -123,6 +131,7 @@
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_minmax",
+ "../../../rtc_base/system:arch",
"../../../system_wrappers:cpu_features_api",
"../../../system_wrappers:field_trial_api",
"../../../system_wrappers:metrics_api",
@@ -152,12 +161,12 @@
"..:apm_logging",
"..:audio_processing",
"..:audio_processing_unittests",
- "../../..:typedefs",
"../../../api:array_view",
"../../../api/audio:aec3_config",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_minmax",
+ "../../../rtc_base/system:arch",
"../../../system_wrappers:cpu_features_api",
"../../../test:test_support",
"//third_party/abseil-cpp/absl/types:optional",
@@ -170,6 +179,7 @@
"adaptive_fir_filter_unittest.cc",
"aec3_fft_unittest.cc",
"aec_state_unittest.cc",
+ "block_delay_buffer_unittest.cc",
"block_framer_unittest.cc",
"block_processor_metrics_unittest.cc",
"block_processor_unittest.cc",
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter.cc b/modules/audio_processing/aec3/adaptive_fir_filter.cc
index 377436c..9a1e811 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter.cc
+++ b/modules/audio_processing/aec3/adaptive_fir_filter.cc
@@ -10,10 +10,12 @@
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#if defined(WEBRTC_HAS_NEON)
#include <arm_neon.h>
#endif
-#include "typedefs.h" // NOLINT(build/include)
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter.h b/modules/audio_processing/aec3/adaptive_fir_filter.h
index 9b6ca90..5dfb466 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter.h
+++ b/modules/audio_processing/aec3/adaptive_fir_filter.h
@@ -22,6 +22,7 @@
#include "modules/audio_processing/aec3/render_buffer.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/constructormagic.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
namespace aec3 {
diff --git a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
index 6c441f3..077586e 100644
--- a/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
+++ b/modules/audio_processing/aec3/adaptive_fir_filter_unittest.cc
@@ -10,11 +10,13 @@
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#include <math.h>
#include <algorithm>
#include <numeric>
#include <string>
-#include "typedefs.h" // NOLINT(build/include)
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif
diff --git a/modules/audio_processing/aec3/aec3_common.cc b/modules/audio_processing/aec3/aec3_common.cc
index 3e60b46..c374a35 100644
--- a/modules/audio_processing/aec3/aec3_common.cc
+++ b/modules/audio_processing/aec3/aec3_common.cc
@@ -11,9 +11,9 @@
#include "modules/audio_processing/aec3/aec3_common.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
#include "rtc_base/checks.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
diff --git a/modules/audio_processing/aec3/aec3_common.h b/modules/audio_processing/aec3/aec3_common.h
index 6422a52..56c7a90 100644
--- a/modules/audio_processing/aec3/aec3_common.h
+++ b/modules/audio_processing/aec3/aec3_common.h
@@ -12,7 +12,6 @@
#define MODULES_AUDIO_PROCESSING_AEC3_AEC3_COMMON_H_
#include <stddef.h>
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -37,6 +36,7 @@
constexpr size_t kFftLengthBy2Plus1 = kFftLengthBy2 + 1;
constexpr size_t kFftLengthBy2Minus1 = kFftLengthBy2 - 1;
constexpr size_t kFftLength = 2 * kFftLengthBy2;
+constexpr size_t kFftLengthBy2Log2 = 6;
constexpr int kMaxAdaptiveFilterLength = 50;
constexpr int kRenderTransferQueueSizeFrames = 100;
@@ -45,7 +45,7 @@
constexpr size_t kSubFrameLength = 80;
constexpr size_t kBlockSize = kFftLengthBy2;
-constexpr size_t kBlockSizeLog2 = 6;
+constexpr size_t kBlockSizeLog2 = kFftLengthBy2Log2;
constexpr size_t kExtendedBlockSize = 2 * kFftLengthBy2;
constexpr size_t kMatchedFilterWindowSizeSubBlocks = 32;
@@ -97,6 +97,9 @@
static_assert(1 << kBlockSizeLog2 == kBlockSize,
"Proper number of shifts for blocksize");
+static_assert(1 << kFftLengthBy2Log2 == kFftLengthBy2,
+ "Proper number of shifts for the fft length");
+
static_assert(1 == NumBandsForRate(8000), "Number of bands for 8 kHz");
static_assert(1 == NumBandsForRate(16000), "Number of bands for 16 kHz");
static_assert(2 == NumBandsForRate(32000), "Number of bands for 32 kHz");
diff --git a/modules/audio_processing/aec3/aec_state.cc b/modules/audio_processing/aec3/aec_state.cc
index d470611..62232ac 100644
--- a/modules/audio_processing/aec3/aec_state.cc
+++ b/modules/audio_processing/aec3/aec_state.cc
@@ -40,11 +40,6 @@
"WebRTC-Aec3EnforceDelayAfterRealignmentKillSwitch");
}
-bool EnableLinearModeWithDivergedFilter() {
- return !field_trial::IsEnabled(
- "WebRTC-Aec3LinearModeWithDivergedFilterKillSwitch");
-}
-
bool EnableEarlyFilterUsage() {
return !field_trial::IsEnabled("WebRTC-Aec3EarlyLinearFilterUsageKillSwitch");
}
@@ -53,25 +48,11 @@
return !field_trial::IsEnabled("WebRTC-Aec3ShortInitialStateKillSwitch");
}
-bool EnableNoWaitForAlignment() {
- return !field_trial::IsEnabled("WebRTC-Aec3NoAlignmentWaitKillSwitch");
-}
-
-bool EnableConvergenceTriggeredLinearMode() {
- return !field_trial::IsEnabled(
- "WebRTC-Aec3ConvergenceTriggingLinearKillSwitch");
-}
-
bool EnableUncertaintyUntilSufficientAdapted() {
return !field_trial::IsEnabled(
"WebRTC-Aec3ErleUncertaintyUntilSufficientlyAdaptedKillSwitch");
}
-bool TreatTransparentModeAsNonlinear() {
- return !field_trial::IsEnabled(
- "WebRTC-Aec3TreatTransparentModeAsNonlinearKillSwitch");
-}
-
bool LowUncertaintyBeforeConvergence() {
return !field_trial::IsEnabled(
"WebRTC-Aec3LowUncertaintyBeforeConvergenceKillSwitch");
@@ -87,16 +68,16 @@
"WebRTC-Aec3EarlyEntryToConvergedModeKillSwitch");
}
-bool ConservativeFilterDivergence() {
- return !field_trial::IsEnabled(
- "WebRTC-Aec3ConservativeFilterDivergenceKillSwitch");
-}
-
bool UseEarlyLimiterDeactivation() {
return !field_trial::IsEnabled(
"WebRTC-Aec3EarlyLimiterDeactivationKillSwitch");
}
+bool ResetErleAfterEchoPathChanges() {
+ return !field_trial::IsEnabled(
+ "WebRTC-Aec3ResetErleAfterEchoPathChangesKillSwitch");
+}
+
float UncertaintyBeforeConvergence() {
if (LowUncertaintyBeforeConvergence()) {
return 1.f;
@@ -128,20 +109,20 @@
EnableStationaryRenderImprovements() &&
config_.echo_audibility.use_stationary_properties),
enforce_delay_after_realignment_(EnableEnforcingDelayAfterRealignment()),
- allow_linear_mode_with_diverged_filter_(
- EnableLinearModeWithDivergedFilter()),
- early_filter_usage_activated_(EnableEarlyFilterUsage()),
- use_short_initial_state_(EnableShortInitialState()),
- convergence_trigger_linear_mode_(EnableConvergenceTriggeredLinearMode()),
- no_alignment_required_for_linear_mode_(EnableNoWaitForAlignment()),
+ early_filter_usage_activated_(EnableEarlyFilterUsage() &&
+ !config.filter.conservative_initial_phase),
+ use_short_initial_state_(EnableShortInitialState() &&
+ !config.filter.conservative_initial_phase),
+ convergence_trigger_linear_mode_(
+ !config.filter.conservative_initial_phase),
+ no_alignment_required_for_linear_mode_(
+ !config.filter.conservative_initial_phase),
use_uncertainty_until_sufficiently_adapted_(
EnableUncertaintyUntilSufficientAdapted()),
- transparent_mode_enforces_nonlinear_mode_(
- TreatTransparentModeAsNonlinear()),
uncertainty_before_convergence_(UncertaintyBeforeConvergence()),
early_entry_to_converged_mode_(EarlyEntryToConvergedMode()),
- conservative_filter_divergence_(ConservativeFilterDivergence()),
early_limiter_deactivation_(UseEarlyLimiterDeactivation()),
+ reset_erle_after_echo_path_changes_(ResetErleAfterEchoPathChanges()),
erle_estimator_(config.erle.min, config.erle.max_l, config.erle.max_h),
max_render_(config_.filter.main.length_blocks, 0.f),
gain_rampup_increase_(ComputeGainRampupIncrease(config_)),
@@ -160,7 +141,6 @@
filter_analyzer_.Reset();
blocks_since_last_saturation_ = 0;
usable_linear_estimate_ = false;
- diverged_linear_filter_ = false;
capture_signal_saturation_ = false;
echo_saturation_ = false;
std::fill(max_render_.begin(), max_render_.end(), 0.f);
@@ -173,6 +153,9 @@
suppression_gain_limiter_.Reset();
blocks_since_converged_filter_ = kBlocksSinceConvergencedFilterInit;
diverged_blocks_ = 0;
+ if (reset_erle_after_echo_path_changes_) {
+ erle_estimator_.Reset();
+ }
};
// TODO(peah): Refine the reset scheme according to the type of gain and
@@ -252,9 +235,13 @@
}
// Update the ERL and ERLE measures.
+ if (reset_erle_after_echo_path_changes_ && transition_triggered_) {
+ erle_estimator_.Reset();
+ }
if (blocks_since_reset_ >= 2 * kNumBlocksPerSecond) {
const auto& X2 = render_buffer.Spectrum(filter_delay_blocks_);
- erle_estimator_.Update(X2, Y2, E2_main, converged_filter);
+ erle_estimator_.Update(X2, Y2, E2_main, converged_filter,
+ config_.erle.onset_detection);
if (converged_filter) {
erl_estimator_.Update(X2, Y2);
}
@@ -283,13 +270,15 @@
}
// Flag whether the initial state is still active.
+ bool prev_initial_state = initial_state_;
if (use_short_initial_state_) {
- initial_state_ =
- blocks_with_proper_filter_adaptation_ < 2.5f * kNumBlocksPerSecond;
+ initial_state_ = blocks_with_proper_filter_adaptation_ <
+ config_.filter.initial_state_seconds * kNumBlocksPerSecond;
} else {
initial_state_ =
blocks_with_proper_filter_adaptation_ < 5 * kNumBlocksPerSecond;
}
+ transition_triggered_ = !initial_state_ && prev_initial_state;
// Update counters for the filter divergence and convergence.
diverged_blocks_ = diverged_filter ? diverged_blocks_ + 1 : 0;
@@ -372,32 +361,21 @@
if (!config_.echo_removal_control.linear_and_stable_echo_path) {
usable_linear_estimate_ =
usable_linear_estimate_ && recently_converged_filter;
- if (!allow_linear_mode_with_diverged_filter_) {
- usable_linear_estimate_ = usable_linear_estimate_ && !diverged_filter;
- }
}
- if (transparent_mode_enforces_nonlinear_mode_) {
- usable_linear_estimate_ = usable_linear_estimate_ && !TransparentMode();
- }
+ usable_linear_estimate_ = usable_linear_estimate_ && !TransparentMode();
use_linear_filter_output_ = usable_linear_estimate_ && !TransparentMode();
- if (conservative_filter_divergence_) {
- diverged_linear_filter_ =
- subtractor_output_analyzer_.SeverelyDivergedFilter() &&
- active_render_block;
- } else {
- diverged_linear_filter_ = diverged_filter;
- }
+ const bool stationary_block =
+ use_stationary_properties_ && echo_audibility_.IsBlockStationary();
reverb_model_estimator_.Update(
- adaptive_filter_impulse_response, adaptive_filter_frequency_response,
+ filter_analyzer_.GetAdjustedFilter(), adaptive_filter_frequency_response,
erle_estimator_.GetInstLinearQualityEstimate(), filter_delay_blocks_,
- usable_linear_estimate_, config_.ep_strength.default_len,
- IsBlockStationary());
+ usable_linear_estimate_, stationary_block);
erle_estimator_.Dump(data_dumper_);
- reverb_model_estimator_.Dump(data_dumper_);
+ reverb_model_estimator_.Dump(data_dumper_.get());
data_dumper_->DumpRaw("aec3_erl", Erl());
data_dumper_->DumpRaw("aec3_erl_time_domain", ErlTimeDomain());
data_dumper_->DumpRaw("aec3_usable_linear_estimate", UsableLinearEstimate());
@@ -409,7 +387,7 @@
data_dumper_->DumpRaw("aec3_consistent_filter",
filter_analyzer_.Consistent());
data_dumper_->DumpRaw("aec3_suppression_gain_limit", SuppressionGainLimit());
- data_dumper_->DumpRaw("aec3_initial_state", InitialState());
+ data_dumper_->DumpRaw("aec3_initial_state", initial_state_);
data_dumper_->DumpRaw("aec3_capture_saturation", SaturatedCapture());
data_dumper_->DumpRaw("aec3_echo_saturation", echo_saturation_);
data_dumper_->DumpRaw("aec3_converged_filter", converged_filter);
@@ -427,8 +405,8 @@
recently_converged_filter);
data_dumper_->DumpRaw("aec3_suppresion_gain_limiter_running",
IsSuppressionGainLimitActive());
- data_dumper_->DumpRaw("aec3_filter_tail_freq_resp_est", GetFreqRespTail());
-
+ data_dumper_->DumpRaw("aec3_filter_tail_freq_resp_est",
+ GetReverbFrequencyResponse());
}
bool AecState::DetectActiveRender(rtc::ArrayView<const float> x) const {
diff --git a/modules/audio_processing/aec3/aec_state.h b/modules/audio_processing/aec3/aec_state.h
index 408f9b8..ea30daf 100644
--- a/modules/audio_processing/aec3/aec_state.h
+++ b/modules/audio_processing/aec3/aec_state.h
@@ -67,17 +67,6 @@
// aec.
bool UseStationaryProperties() const { return use_stationary_properties_; }
- // Returns true if the current render block is estimated as stationary.
- bool IsBlockStationary() const {
- if (UseStationaryProperties()) {
- return echo_audibility_.IsBlockStationary();
- } else {
- // Assume that a non stationary block when the use of
- // stationary properties are not enabled.
- return false;
- }
- }
-
// Returns the ERLE.
const std::array<float, kFftLengthBy2Plus1>& Erle() const {
return erle_estimator_.Erle();
@@ -85,10 +74,6 @@
// Returns any uncertainty in the ERLE estimate.
absl::optional<float> ErleUncertainty() const {
- if (allow_linear_mode_with_diverged_filter_ && diverged_linear_filter_) {
- return 10.f;
- }
-
if (!filter_has_had_time_to_converge_ &&
use_uncertainty_until_sufficiently_adapted_) {
return uncertainty_before_convergence_;
@@ -135,6 +120,11 @@
// Returns the decay factor for the echo reverberation.
float ReverbDecay() const { return reverb_model_estimator_.ReverbDecay(); }
+ // Return the frequency response of the reverberant echo.
+ rtc::ArrayView<const float> GetReverbFrequencyResponse() const {
+ return reverb_model_estimator_.GetReverbFrequencyResponse();
+ }
+
// Returns the upper limit for the echo suppression gain.
float SuppressionGainLimit() const {
return suppression_gain_limiter_.Limit();
@@ -150,8 +140,9 @@
return filter_has_had_time_to_converge_;
}
- // Returns whether the filter adaptation is still in the initial state.
- bool InitialState() const { return initial_state_; }
+ // Returns whether the transition for going out of the initial stated has
+ // been triggered.
+ bool TransitionTriggered() const { return transition_triggered_; }
// Updates the aec state.
void Update(const absl::optional<DelayEstimate>& external_delay,
@@ -164,11 +155,6 @@
const SubtractorOutput& subtractor_output,
rtc::ArrayView<const float> y);
- // Returns the tail freq. response of the linear filter.
- rtc::ArrayView<const float> GetFreqRespTail() const {
- return reverb_model_estimator_.GetFreqRespTail();
- }
-
// Returns filter length in blocks.
int FilterLengthBlocks() const {
return filter_analyzer_.FilterLengthBlocks();
@@ -186,17 +172,15 @@
const bool allow_transparent_mode_;
const bool use_stationary_properties_;
const bool enforce_delay_after_realignment_;
- const bool allow_linear_mode_with_diverged_filter_;
const bool early_filter_usage_activated_;
const bool use_short_initial_state_;
const bool convergence_trigger_linear_mode_;
const bool no_alignment_required_for_linear_mode_;
const bool use_uncertainty_until_sufficiently_adapted_;
- const bool transparent_mode_enforces_nonlinear_mode_;
const float uncertainty_before_convergence_;
const bool early_entry_to_converged_mode_;
- const bool conservative_filter_divergence_;
const bool early_limiter_deactivation_;
+ const bool reset_erle_after_echo_path_changes_;
ErlEstimator erl_estimator_;
ErleEstimator erle_estimator_;
size_t capture_block_counter_ = 0;
@@ -204,7 +188,6 @@
size_t blocks_with_proper_filter_adaptation_ = 0;
size_t blocks_with_active_render_ = 0;
bool usable_linear_estimate_ = false;
- bool diverged_linear_filter_ = false;
bool capture_signal_saturation_ = false;
bool echo_saturation_ = false;
bool transparent_mode_ = false;
@@ -215,6 +198,7 @@
std::vector<float> max_render_;
bool filter_has_had_time_to_converge_ = false;
bool initial_state_ = true;
+ bool transition_triggered_ = false;
const float gain_rampup_increase_;
SuppressionGainUpperLimiter suppression_gain_limiter_;
FilterAnalyzer filter_analyzer_;
diff --git a/modules/audio_processing/aec3/block_delay_buffer.cc b/modules/audio_processing/aec3/block_delay_buffer.cc
new file mode 100644
index 0000000..0a242ee
--- /dev/null
+++ b/modules/audio_processing/aec3/block_delay_buffer.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018 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 "modules/audio_processing/aec3/block_delay_buffer.h"
+
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+
+BlockDelayBuffer::BlockDelayBuffer(size_t num_bands,
+ size_t frame_length,
+ size_t delay_samples)
+ : frame_length_(frame_length),
+ delay_(delay_samples),
+ buf_(num_bands, std::vector<float>(delay_, 0.f)) {}
+
+BlockDelayBuffer::~BlockDelayBuffer() = default;
+
+void BlockDelayBuffer::DelaySignal(AudioBuffer* frame) {
+ RTC_DCHECK_EQ(1, frame->num_channels());
+ RTC_DCHECK_EQ(buf_.size(), frame->num_bands());
+ if (delay_ == 0) {
+ return;
+ }
+
+ const size_t i_start = last_insert_;
+ size_t i = 0;
+ for (size_t j = 0; j < buf_.size(); ++j) {
+ i = i_start;
+ for (size_t k = 0; k < frame_length_; ++k) {
+ const float tmp = buf_[j][i];
+ buf_[j][i] = frame->split_bands_f(0)[j][k];
+ frame->split_bands_f(0)[j][k] = tmp;
+ i = i < buf_[0].size() - 1 ? i + 1 : 0;
+ }
+ }
+
+ last_insert_ = i;
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/aec3/block_delay_buffer.h b/modules/audio_processing/aec3/block_delay_buffer.h
new file mode 100644
index 0000000..6e5fd5c
--- /dev/null
+++ b/modules/audio_processing/aec3/block_delay_buffer.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018 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 MODULES_AUDIO_PROCESSING_AEC3_BLOCK_DELAY_BUFFER_H_
+#define MODULES_AUDIO_PROCESSING_AEC3_BLOCK_DELAY_BUFFER_H_
+
+#include <vector>
+
+#include "modules/audio_processing/audio_buffer.h"
+
+namespace webrtc {
+
+// Class for applying a fixed delay to the samples in a signal partitioned using
+// the audiobuffer band-splitting scheme.
+class BlockDelayBuffer {
+ public:
+ BlockDelayBuffer(size_t num_bands, size_t frame_length, size_t delay_samples);
+ ~BlockDelayBuffer();
+
+ // Delays the samples by the specified delay.
+ void DelaySignal(AudioBuffer* frame);
+
+ private:
+ const size_t frame_length_;
+ const size_t delay_;
+ std::vector<std::vector<float>> buf_;
+ size_t last_insert_ = 0;
+};
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_AEC3_BLOCK_DELAY_BUFFER_H_
diff --git a/modules/audio_processing/aec3/block_delay_buffer_unittest.cc b/modules/audio_processing/aec3/block_delay_buffer_unittest.cc
new file mode 100644
index 0000000..778d43d
--- /dev/null
+++ b/modules/audio_processing/aec3/block_delay_buffer_unittest.cc
@@ -0,0 +1,91 @@
+/*
+ * 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 "modules/audio_processing/aec3/block_delay_buffer.h"
+
+#include <string>
+
+#include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/audio_buffer.h"
+#include "rtc_base/strings/string_builder.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+
+float SampleValue(size_t sample_index) {
+ return sample_index % 32768;
+}
+
+// Populates the frame with linearly increasing sample values for each band.
+void PopulateInputFrame(size_t frame_length,
+ size_t num_bands,
+ size_t first_sample_index,
+ float* const* frame) {
+ for (size_t k = 0; k < num_bands; ++k) {
+ for (size_t i = 0; i < frame_length; ++i) {
+ frame[k][i] = SampleValue(first_sample_index + i);
+ }
+ }
+}
+
+std::string ProduceDebugText(int sample_rate_hz, size_t delay) {
+ char log_stream_buffer[8 * 1024];
+ rtc::SimpleStringBuilder ss(log_stream_buffer);
+ ss << "Sample rate: " << sample_rate_hz;
+ ss << ", Delay: " << delay;
+ return ss.str();
+}
+
+} // namespace
+
+// Verifies that the correct signal delay is achived.
+TEST(BlockDelayBuffer, CorrectDelayApplied) {
+ for (size_t delay : {0, 1, 27, 160, 4321, 7021}) {
+ for (auto rate : {8000, 16000, 32000, 48000}) {
+ SCOPED_TRACE(ProduceDebugText(rate, delay));
+ size_t num_bands = NumBandsForRate(rate);
+ size_t fullband_frame_length = rate / 100;
+ size_t subband_frame_length = rate == 8000 ? 80 : 160;
+
+ BlockDelayBuffer delay_buffer(num_bands, subband_frame_length, delay);
+
+ static constexpr size_t kNumFramesToProcess = 20;
+ for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
+ ++frame_index) {
+ AudioBuffer audio_buffer(fullband_frame_length, 1,
+ fullband_frame_length, 1,
+ fullband_frame_length);
+ if (rate > 16000) {
+ audio_buffer.SplitIntoFrequencyBands();
+ }
+ size_t first_sample_index = frame_index * subband_frame_length;
+ PopulateInputFrame(subband_frame_length, num_bands, first_sample_index,
+ &audio_buffer.split_bands_f(0)[0]);
+ delay_buffer.DelaySignal(&audio_buffer);
+
+ for (size_t k = 0; k < num_bands; ++k) {
+ size_t sample_index = first_sample_index;
+ for (size_t i = 0; i < subband_frame_length; ++i, ++sample_index) {
+ if (sample_index < delay) {
+ EXPECT_EQ(0.f, audio_buffer.split_bands_f(0)[k][i]);
+ } else {
+ EXPECT_EQ(SampleValue(sample_index - delay),
+ audio_buffer.split_bands_f(0)[k][i]);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/aec3/coherence_gain.cc b/modules/audio_processing/aec3/coherence_gain.cc
deleted file mode 100644
index ad33382..0000000
--- a/modules/audio_processing/aec3/coherence_gain.cc
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2018 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 "modules/audio_processing/aec3/coherence_gain.h"
-
-#include <math.h>
-
-#include <algorithm>
-
-#include "rtc_base/checks.h"
-
-namespace webrtc {
-
-namespace {
-
-// Matlab code to produce table:
-// overDriveCurve = [sqrt(linspace(0,1,65))' + 1];
-// fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', overDriveCurve);
-const float kOverDriveCurve[kFftLengthBy2Plus1] = {
- 1.0000f, 1.1250f, 1.1768f, 1.2165f, 1.2500f, 1.2795f, 1.3062f, 1.3307f,
- 1.3536f, 1.3750f, 1.3953f, 1.4146f, 1.4330f, 1.4507f, 1.4677f, 1.4841f,
- 1.5000f, 1.5154f, 1.5303f, 1.5449f, 1.5590f, 1.5728f, 1.5863f, 1.5995f,
- 1.6124f, 1.6250f, 1.6374f, 1.6495f, 1.6614f, 1.6731f, 1.6847f, 1.6960f,
- 1.7071f, 1.7181f, 1.7289f, 1.7395f, 1.7500f, 1.7603f, 1.7706f, 1.7806f,
- 1.7906f, 1.8004f, 1.8101f, 1.8197f, 1.8292f, 1.8385f, 1.8478f, 1.8570f,
- 1.8660f, 1.8750f, 1.8839f, 1.8927f, 1.9014f, 1.9100f, 1.9186f, 1.9270f,
- 1.9354f, 1.9437f, 1.9520f, 1.9601f, 1.9682f, 1.9763f, 1.9843f, 1.9922f,
- 2.0000f};
-
-// Matlab code to produce table:
-// weightCurve = [0 ; 0.3 * sqrt(linspace(0,1,64))' + 0.1];
-// fprintf(1, '\t%.4f, %.4f, %.4f, %.4f, %.4f, %.4f,\n', weightCurve);
-const float kWeightCurve[kFftLengthBy2Plus1] = {
- 0.0000f, 0.1000f, 0.1378f, 0.1535f, 0.1655f, 0.1756f, 0.1845f, 0.1926f,
- 0.2000f, 0.2069f, 0.2134f, 0.2195f, 0.2254f, 0.2309f, 0.2363f, 0.2414f,
- 0.2464f, 0.2512f, 0.2558f, 0.2604f, 0.2648f, 0.2690f, 0.2732f, 0.2773f,
- 0.2813f, 0.2852f, 0.2890f, 0.2927f, 0.2964f, 0.3000f, 0.3035f, 0.3070f,
- 0.3104f, 0.3138f, 0.3171f, 0.3204f, 0.3236f, 0.3268f, 0.3299f, 0.3330f,
- 0.3360f, 0.3390f, 0.3420f, 0.3449f, 0.3478f, 0.3507f, 0.3535f, 0.3563f,
- 0.3591f, 0.3619f, 0.3646f, 0.3673f, 0.3699f, 0.3726f, 0.3752f, 0.3777f,
- 0.3803f, 0.3828f, 0.3854f, 0.3878f, 0.3903f, 0.3928f, 0.3952f, 0.3976f,
- 0.4000f};
-
-int CmpFloat(const void* a, const void* b) {
- const float* da = static_cast<const float*>(a);
- const float* db = static_cast<const float*>(b);
- return (*da > *db) - (*da < *db);
-}
-
-} // namespace
-
-CoherenceGain::CoherenceGain(int sample_rate_hz, size_t num_bands_to_compute)
- : num_bands_to_compute_(num_bands_to_compute),
- sample_rate_scaler_(sample_rate_hz >= 16000 ? 2 : 1) {
- spectra_.Cye.Clear();
- spectra_.Cxy.Clear();
- spectra_.Pe.fill(0.f);
- // Initialize to 1 in order to prevent numerical instability in the first
- // block.
- spectra_.Py.fill(1.f);
- spectra_.Px.fill(1.f);
-}
-
-CoherenceGain::~CoherenceGain() = default;
-
-void CoherenceGain::ComputeGain(const FftData& E,
- const FftData& X,
- const FftData& Y,
- rtc::ArrayView<float> gain) {
- std::array<float, kFftLengthBy2Plus1> coherence_ye;
- std::array<float, kFftLengthBy2Plus1> coherence_xy;
-
- UpdateCoherenceSpectra(E, X, Y);
- ComputeCoherence(coherence_ye, coherence_xy);
- FormSuppressionGain(coherence_ye, coherence_xy, gain);
-}
-
-// Updates the following smoothed Power Spectral Densities (PSD):
-// - sd : near-end
-// - se : residual echo
-// - sx : far-end
-// - sde : cross-PSD of near-end and residual echo
-// - sxd : cross-PSD of near-end and far-end
-//
-void CoherenceGain::UpdateCoherenceSpectra(const FftData& E,
- const FftData& X,
- const FftData& Y) {
- const float s = sample_rate_scaler_ == 1 ? 0.9f : 0.92f;
- const float one_minus_s = 1.f - s;
- auto& c = spectra_;
-
- for (size_t i = 0; i < c.Py.size(); i++) {
- c.Py[i] =
- s * c.Py[i] + one_minus_s * (Y.re[i] * Y.re[i] + Y.im[i] * Y.im[i]);
- c.Pe[i] =
- s * c.Pe[i] + one_minus_s * (E.re[i] * E.re[i] + E.im[i] * E.im[i]);
- // We threshold here to protect against the ill-effects of a zero farend.
- // The threshold is not arbitrarily chosen, but balances protection and
- // adverse interaction with the algorithm's tuning.
-
- // Threshold to protect against the ill-effects of a zero far-end.
- c.Px[i] =
- s * c.Px[i] +
- one_minus_s * std::max(X.re[i] * X.re[i] + X.im[i] * X.im[i], 15.f);
-
- c.Cye.re[i] =
- s * c.Cye.re[i] + one_minus_s * (Y.re[i] * E.re[i] + Y.im[i] * E.im[i]);
- c.Cye.im[i] =
- s * c.Cye.im[i] + one_minus_s * (Y.re[i] * E.im[i] - Y.im[i] * E.re[i]);
-
- c.Cxy.re[i] =
- s * c.Cxy.re[i] + one_minus_s * (Y.re[i] * X.re[i] + Y.im[i] * X.im[i]);
- c.Cxy.im[i] =
- s * c.Cxy.im[i] + one_minus_s * (Y.re[i] * X.im[i] - Y.im[i] * X.re[i]);
- }
-}
-
-void CoherenceGain::FormSuppressionGain(
- rtc::ArrayView<const float> coherence_ye,
- rtc::ArrayView<const float> coherence_xy,
- rtc::ArrayView<float> gain) {
- RTC_DCHECK_EQ(kFftLengthBy2Plus1, coherence_ye.size());
- RTC_DCHECK_EQ(kFftLengthBy2Plus1, coherence_xy.size());
- RTC_DCHECK_EQ(kFftLengthBy2Plus1, gain.size());
- constexpr int kPrefBandSize = 24;
- auto& gs = gain_state_;
- std::array<float, kPrefBandSize> h_nl_pref;
- float h_nl_fb = 0;
- float h_nl_fb_low = 0;
- const int pref_band_size = kPrefBandSize / sample_rate_scaler_;
- const int min_pref_band = 4 / sample_rate_scaler_;
-
- float h_nl_de_avg = 0.f;
- float h_nl_xd_avg = 0.f;
- for (int i = min_pref_band; i < pref_band_size + min_pref_band; ++i) {
- h_nl_xd_avg += coherence_xy[i];
- h_nl_de_avg += coherence_ye[i];
- }
- h_nl_xd_avg /= pref_band_size;
- h_nl_xd_avg = 1 - h_nl_xd_avg;
- h_nl_de_avg /= pref_band_size;
-
- if (h_nl_xd_avg < 0.75f && h_nl_xd_avg < gs.h_nl_xd_avg_min) {
- gs.h_nl_xd_avg_min = h_nl_xd_avg;
- }
-
- if (h_nl_de_avg > 0.98f && h_nl_xd_avg > 0.9f) {
- gs.near_state = true;
- } else if (h_nl_de_avg < 0.95f || h_nl_xd_avg < 0.8f) {
- gs.near_state = false;
- }
-
- std::array<float, kFftLengthBy2Plus1> h_nl;
- if (gs.h_nl_xd_avg_min == 1) {
- gs.overdrive = 15.f;
-
- if (gs.near_state) {
- std::copy(coherence_ye.begin(), coherence_ye.end(), h_nl.begin());
- h_nl_fb = h_nl_de_avg;
- h_nl_fb_low = h_nl_de_avg;
- } else {
- for (size_t i = 0; i < h_nl.size(); ++i) {
- h_nl[i] = 1 - coherence_xy[i];
- h_nl[i] = std::max(h_nl[i], 0.f);
- }
- h_nl_fb = h_nl_xd_avg;
- h_nl_fb_low = h_nl_xd_avg;
- }
- } else {
- if (gs.near_state) {
- std::copy(coherence_ye.begin(), coherence_ye.end(), h_nl.begin());
- h_nl_fb = h_nl_de_avg;
- h_nl_fb_low = h_nl_de_avg;
- } else {
- for (size_t i = 0; i < h_nl.size(); ++i) {
- h_nl[i] = std::min(coherence_ye[i], 1 - coherence_xy[i]);
- h_nl[i] = std::max(h_nl[i], 0.f);
- }
-
- // Select an order statistic from the preferred bands.
- // TODO(peah): Using quicksort now, but a selection algorithm may be
- // preferred.
- std::copy(h_nl.begin() + min_pref_band,
- h_nl.begin() + min_pref_band + pref_band_size,
- h_nl_pref.begin());
- std::qsort(h_nl_pref.data(), pref_band_size, sizeof(float), CmpFloat);
-
- constexpr float kPrefBandQuant = 0.75f;
- h_nl_fb = h_nl_pref[static_cast<int>(
- floor(kPrefBandQuant * (pref_band_size - 1)))];
- constexpr float kPrefBandQuantLow = 0.5f;
- h_nl_fb_low = h_nl_pref[static_cast<int>(
- floor(kPrefBandQuantLow * (pref_band_size - 1)))];
- }
- }
-
- // Track the local filter minimum to determine suppression overdrive.
- if (h_nl_fb_low < 0.6f && h_nl_fb_low < gs.h_nl_fb_local_min) {
- gs.h_nl_fb_local_min = h_nl_fb_low;
- gs.h_nl_fb_min = h_nl_fb_low;
- gs.h_nl_new_min = 1;
- gs.h_nl_min_ctr = 0;
- }
- gs.h_nl_fb_local_min =
- std::min(gs.h_nl_fb_local_min + 0.0008f / sample_rate_scaler_, 1.f);
- gs.h_nl_xd_avg_min =
- std::min(gs.h_nl_xd_avg_min + 0.0006f / sample_rate_scaler_, 1.f);
-
- if (gs.h_nl_new_min == 1) {
- ++gs.h_nl_min_ctr;
- }
- if (gs.h_nl_min_ctr == 2) {
- gs.h_nl_new_min = 0;
- gs.h_nl_min_ctr = 0;
- constexpr float epsilon = 1e-10f;
- gs.overdrive = std::max(
- -18.4f / static_cast<float>(log(gs.h_nl_fb_min + epsilon) + epsilon),
- 15.f);
- }
-
- // Smooth the overdrive.
- if (gs.overdrive < gs.overdrive_scaling) {
- gs.overdrive_scaling = 0.99f * gs.overdrive_scaling + 0.01f * gs.overdrive;
- } else {
- gs.overdrive_scaling = 0.9f * gs.overdrive_scaling + 0.1f * gs.overdrive;
- }
-
- // Apply the overdrive.
- RTC_DCHECK_LE(num_bands_to_compute_, gain.size());
- for (size_t i = 0; i < num_bands_to_compute_; ++i) {
- if (h_nl[i] > h_nl_fb) {
- h_nl[i] = kWeightCurve[i] * h_nl_fb + (1 - kWeightCurve[i]) * h_nl[i];
- }
- gain[i] = powf(h_nl[i], gs.overdrive_scaling * kOverDriveCurve[i]);
- }
-}
-
-void CoherenceGain::ComputeCoherence(rtc::ArrayView<float> coherence_ye,
- rtc::ArrayView<float> coherence_xy) const {
- const auto& c = spectra_;
- constexpr float epsilon = 1e-10f;
- for (size_t i = 0; i < coherence_ye.size(); ++i) {
- coherence_ye[i] = (c.Cye.re[i] * c.Cye.re[i] + c.Cye.im[i] * c.Cye.im[i]) /
- (c.Py[i] * c.Pe[i] + epsilon);
- coherence_xy[i] = (c.Cxy.re[i] * c.Cxy.re[i] + c.Cxy.im[i] * c.Cxy.im[i]) /
- (c.Px[i] * c.Py[i] + epsilon);
- }
-}
-
-} // namespace webrtc
diff --git a/modules/audio_processing/aec3/coherence_gain.h b/modules/audio_processing/aec3/coherence_gain.h
deleted file mode 100644
index b6e22fd..0000000
--- a/modules/audio_processing/aec3/coherence_gain.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2018 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 MODULES_AUDIO_PROCESSING_AEC3_COHERENCE_GAIN_H_
-#define MODULES_AUDIO_PROCESSING_AEC3_COHERENCE_GAIN_H_
-
-#include <array>
-
-#include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/aec3/aec3_fft.h"
-#include "rtc_base/constructormagic.h"
-
-namespace webrtc {
-
-// Class for computing an echo suppression gain based on the coherence measure.
-class CoherenceGain {
- public:
- CoherenceGain(int sample_rate_hz, size_t num_bands_to_compute);
- ~CoherenceGain();
-
- // Computes the gain based on the FFTs of the filter error output signal, the
- // render signal and the capture signal.
- void ComputeGain(const FftData& E,
- const FftData& X,
- const FftData& Y,
- rtc::ArrayView<float> gain);
-
- private:
- struct {
- FftData Cye;
- FftData Cxy;
- std::array<float, kFftLengthBy2Plus1> Px;
- std::array<float, kFftLengthBy2Plus1> Py;
- std::array<float, kFftLengthBy2Plus1> Pe;
- } spectra_;
-
- struct {
- float h_nl_fb_min = 1;
- float h_nl_fb_local_min = 1;
- float h_nl_xd_avg_min = 1.f;
- int h_nl_new_min = 0;
- float h_nl_min_ctr = 0;
- float overdrive = 2;
- float overdrive_scaling = 2;
- bool near_state = false;
- } gain_state_;
-
- const Aec3Fft fft_;
- const size_t num_bands_to_compute_;
- const int sample_rate_scaler_;
-
- // Updates the spectral estimates used for the coherence computation.
- void UpdateCoherenceSpectra(const FftData& E,
- const FftData& X,
- const FftData& Y);
-
- // Compute the suppression gain based on the coherence.
- void FormSuppressionGain(rtc::ArrayView<const float> coherence_ye,
- rtc::ArrayView<const float> coherence_xy,
- rtc::ArrayView<float> h_nl);
-
- // Compute the coherence.
- void ComputeCoherence(rtc::ArrayView<float> coherence_ye,
- rtc::ArrayView<float> coherence_xy) const;
-
- RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CoherenceGain);
-};
-} // namespace webrtc
-
-#endif // MODULES_AUDIO_PROCESSING_AEC3_COHERENCE_GAIN_H_
diff --git a/modules/audio_processing/aec3/comfort_noise_generator.cc b/modules/audio_processing/aec3/comfort_noise_generator.cc
index dab40a9..55faf4b 100644
--- a/modules/audio_processing/aec3/comfort_noise_generator.cc
+++ b/modules/audio_processing/aec3/comfort_noise_generator.cc
@@ -10,7 +10,9 @@
#include "modules/audio_processing/aec3/comfort_noise_generator.h"
-#include "typedefs.h" // NOLINT(build/include)
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif
diff --git a/modules/audio_processing/aec3/comfort_noise_generator.h b/modules/audio_processing/aec3/comfort_noise_generator.h
index 2d998be..6a47989 100644
--- a/modules/audio_processing/aec3/comfort_noise_generator.h
+++ b/modules/audio_processing/aec3/comfort_noise_generator.h
@@ -18,6 +18,7 @@
#include "modules/audio_processing/aec3/aec_state.h"
#include "modules/audio_processing/aec3/fft_data.h"
#include "rtc_base/constructormagic.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
namespace aec3 {
diff --git a/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc b/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc
index d7e9407..77a09ed 100644
--- a/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc
+++ b/modules/audio_processing/aec3/comfort_noise_generator_unittest.cc
@@ -14,9 +14,9 @@
#include <numeric>
#include "rtc_base/random.h"
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace aec3 {
diff --git a/modules/audio_processing/aec3/echo_canceller3.cc b/modules/audio_processing/aec3/echo_canceller3.cc
index c02bc14..e5219c7 100644
--- a/modules/audio_processing/aec3/echo_canceller3.cc
+++ b/modules/audio_processing/aec3/echo_canceller3.cc
@@ -342,6 +342,7 @@
std::unique_ptr<BlockProcessor> block_processor)
: data_dumper_(
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
+ config_(config),
sample_rate_hz_(sample_rate_hz),
num_bands_(NumBandsForRate(sample_rate_hz_)),
frame_length_(rtc::CheckedDivExact(LowestBandRate(sample_rate_hz_), 100)),
@@ -358,7 +359,10 @@
render_queue_output_frame_(num_bands_,
std::vector<float>(frame_length_, 0.f)),
block_(num_bands_, std::vector<float>(kBlockSize, 0.f)),
- sub_frame_view_(num_bands_) {
+ sub_frame_view_(num_bands_),
+ block_delay_buffer_(num_bands_,
+ frame_length_,
+ config_.delay.fixed_capture_delay_samples) {
RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
std::unique_ptr<CascadedBiQuadFilter> render_highpass_filter;
@@ -421,6 +425,11 @@
data_dumper_->DumpRaw("aec3_call_order",
static_cast<int>(EchoCanceller3ApiCall::kCapture));
+ // Optionally delay the capture signal.
+ if (config_.delay.fixed_capture_delay_samples > 0) {
+ block_delay_buffer_.DelaySignal(capture);
+ }
+
rtc::ArrayView<float> capture_lower_band =
rtc::ArrayView<float>(&capture->split_bands_f(0)[0][0], frame_length_);
diff --git a/modules/audio_processing/aec3/echo_canceller3.h b/modules/audio_processing/aec3/echo_canceller3.h
index b66b8b1..f5520ba 100644
--- a/modules/audio_processing/aec3/echo_canceller3.h
+++ b/modules/audio_processing/aec3/echo_canceller3.h
@@ -12,6 +12,7 @@
#define MODULES_AUDIO_PROCESSING_AEC3_ECHO_CANCELLER3_H_
#include "api/audio/echo_canceller3_config.h"
+#include "modules/audio_processing/aec3/block_delay_buffer.h"
#include "modules/audio_processing/aec3/block_framer.h"
#include "modules/audio_processing/aec3/block_processor.h"
#include "modules/audio_processing/aec3/cascaded_biquad_filter.h"
@@ -110,6 +111,7 @@
// State that may be accessed by the capture thread.
static int instance_count_;
std::unique_ptr<ApmDataDumper> data_dumper_;
+ const EchoCanceller3Config config_;
const int sample_rate_hz_;
const int num_bands_;
const size_t frame_length_;
@@ -129,6 +131,7 @@
std::vector<std::vector<float>> block_ RTC_GUARDED_BY(capture_race_checker_);
std::vector<rtc::ArrayView<float>> sub_frame_view_
RTC_GUARDED_BY(capture_race_checker_);
+ BlockDelayBuffer block_delay_buffer_ RTC_GUARDED_BY(capture_race_checker_);
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCanceller3);
};
diff --git a/modules/audio_processing/aec3/echo_remover.cc b/modules/audio_processing/aec3/echo_remover.cc
index 5394eaf..9b6677e 100644
--- a/modules/audio_processing/aec3/echo_remover.cc
+++ b/modules/audio_processing/aec3/echo_remover.cc
@@ -141,7 +141,6 @@
bool echo_leakage_detected_ = false;
AecState aec_state_;
EchoRemoverMetrics metrics_;
- bool initial_state_ = true;
std::array<float, kFftLengthBy2> e_old_;
std::array<float, kFftLengthBy2> x_old_;
std::array<float, kFftLengthBy2> y_old_;
@@ -163,7 +162,9 @@
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
optimization_(DetectOptimization()),
sample_rate_hz_(sample_rate_hz),
- use_shadow_filter_output_(UseShadowFilterOutput()),
+ use_shadow_filter_output_(
+ UseShadowFilterOutput() &&
+ config_.filter.enable_shadow_filter_output_usage),
use_smooth_signal_transitions_(UseSmoothSignalTransitions()),
subtractor_(config, data_dumper_.get(), optimization_),
suppression_gain_(config_, optimization_, sample_rate_hz),
@@ -233,7 +234,6 @@
if (echo_path_variability.delay_change !=
EchoPathVariability::DelayAdjustment::kNone) {
suppression_gain_.SetInitialState(true);
- initial_state_ = true;
}
}
if (gain_change_hangover_ > 0) {
@@ -257,10 +257,9 @@
aec_state_.FilterDelayBlocks());
// Perform linear echo cancellation.
- if (initial_state_ && !aec_state_.InitialState()) {
+ if (aec_state_.TransitionTriggered()) {
subtractor_.ExitInitialState();
suppression_gain_.SetInitialState(false);
- initial_state_ = false;
}
// If the delay is known, use the echo subtractor.
@@ -281,17 +280,6 @@
subtractor_.FilterImpulseResponse(), *render_buffer, E2, Y2,
subtractor_output, y0);
- // Compute spectra.
- const bool suppression_gain_uses_ffts =
- config_.suppressor.bands_with_reliable_coherence > 0;
- FftData X;
- if (suppression_gain_uses_ffts) {
- auto& x_aligned = render_buffer->Block(-aec_state_.FilterDelayBlocks())[0];
- WindowedPaddedFft(fft_, x_aligned, x_old_, &X);
- } else {
- X.Clear();
- }
-
// Choose the linear output.
data_dumper_->DumpWav("aec3_output_linear2", kBlockSize, &e[0],
LowestBandRate(sample_rate_hz_), 1);
@@ -321,7 +309,9 @@
cng_.Compute(aec_state_, Y2, &comfort_noise, &high_band_comfort_noise);
// Compute and apply the suppression gain.
- suppression_gain_.GetGain(E2, R2, cng_.NoiseSpectrum(), E, X, Y,
+ const auto& echo_spectrum =
+ aec_state_.UsableLinearEstimate() ? S2_linear : R2;
+ suppression_gain_.GetGain(E2, echo_spectrum, R2, cng_.NoiseSpectrum(), E, Y,
render_signal_analyzer_, aec_state_, x,
&high_bands_gain, &G);
@@ -366,9 +356,9 @@
RTC_DCHECK_EQ(subtractor_output.e_shadow.size(), output.size());
bool use_main_output = true;
if (use_shadow_filter_output_) {
- // As the output of the main adaptive filter generally should be better than
- // the shadow filter output, add a margin and threshold for when choosing
- // the shadow filter output.
+ // As the output of the main adaptive filter generally should be better
+ // than the shadow filter output, add a margin and threshold for when
+ // choosing the shadow filter output.
if (subtractor_output.e2_shadow < 0.9f * subtractor_output.e2_main &&
subtractor_output.y2 > 30.f * 30.f * kBlockSize &&
(subtractor_output.s2_main > 60.f * 60.f * kBlockSize ||
diff --git a/modules/audio_processing/aec3/erle_estimator.cc b/modules/audio_processing/aec3/erle_estimator.cc
index 52ef8ed..b02245c 100644
--- a/modules/audio_processing/aec3/erle_estimator.cc
+++ b/modules/audio_processing/aec3/erle_estimator.cc
@@ -35,6 +35,13 @@
max_erle_hf_(max_erle_hf),
erle_freq_inst_(kPointsToAccumulate),
erle_time_inst_(kPointsToAccumulate) {
+ Reset();
+}
+
+ErleEstimator::~ErleEstimator() = default;
+
+void ErleEstimator::Reset() {
+ erle_time_inst_.Reset();
erle_.fill(min_erle_);
erle_onsets_.fill(min_erle_);
hold_counters_.fill(0);
@@ -43,8 +50,6 @@
hold_counter_time_domain_ = 0;
}
-ErleEstimator::~ErleEstimator() = default;
-
ErleEstimator::ErleTimeInstantaneous::ErleTimeInstantaneous(
int points_to_accumulate)
: points_to_accumulate_(points_to_accumulate) {
@@ -167,7 +172,8 @@
void ErleEstimator::Update(rtc::ArrayView<const float> render_spectrum,
rtc::ArrayView<const float> capture_spectrum,
rtc::ArrayView<const float> subtractor_spectrum,
- bool converged_filter) {
+ bool converged_filter,
+ bool onset_detection) {
RTC_DCHECK_EQ(kFftLengthBy2Plus1, render_spectrum.size());
RTC_DCHECK_EQ(kFftLengthBy2Plus1, capture_spectrum.size());
RTC_DCHECK_EQ(kFftLengthBy2Plus1, subtractor_spectrum.size());
@@ -191,19 +197,22 @@
};
// Update the estimates in a clamped minimum statistics manner.
- auto erle_update = [&](size_t start, size_t stop, float max_erle) {
+ auto erle_update = [&](size_t start, size_t stop, float max_erle,
+ bool onset_detection) {
for (size_t k = start; k < stop; ++k) {
if (X2[k] > kX2Min) {
absl::optional<float> new_erle =
erle_freq_inst_.Update(Y2[k], E2[k], k);
if (new_erle) {
- if (coming_onset_[k]) {
- coming_onset_[k] = false;
- erle_onsets_[k] =
- erle_band_update(erle_onsets_[k], new_erle.value(), 0.15f, 0.3f,
- min_erle_, max_erle);
+ if (onset_detection) {
+ if (coming_onset_[k]) {
+ coming_onset_[k] = false;
+ erle_onsets_[k] =
+ erle_band_update(erle_onsets_[k], new_erle.value(), 0.15f,
+ 0.3f, min_erle_, max_erle);
+ }
+ hold_counters_[k] = kBlocksForOnsetDetection;
}
- hold_counters_[k] = kBlocksForOnsetDetection;
erle_[k] = erle_band_update(erle_[k], new_erle.value(), 0.05f, 0.1f,
min_erle_, max_erle);
}
@@ -216,20 +225,22 @@
// a minimum of the erle that can be estimated as that flag would
// be false if the filter is performing poorly.
constexpr size_t kFftLengthBy4 = kFftLengthBy2 / 2;
- erle_update(1, kFftLengthBy4, max_erle_lf_);
- erle_update(kFftLengthBy4, kFftLengthBy2, max_erle_hf_);
+ erle_update(1, kFftLengthBy4, max_erle_lf_, onset_detection);
+ erle_update(kFftLengthBy4, kFftLengthBy2, max_erle_hf_, onset_detection);
}
- for (size_t k = 1; k < kFftLengthBy2; ++k) {
- hold_counters_[k]--;
- if (hold_counters_[k] <= (kBlocksForOnsetDetection - kErleHold)) {
- if (erle_[k] > erle_onsets_[k]) {
- erle_[k] = std::max(erle_onsets_[k], 0.97f * erle_[k]);
- RTC_DCHECK_LE(min_erle_, erle_[k]);
- }
- if (hold_counters_[k] <= 0) {
- coming_onset_[k] = true;
- hold_counters_[k] = 0;
+ if (onset_detection) {
+ for (size_t k = 1; k < kFftLengthBy2; ++k) {
+ hold_counters_[k]--;
+ if (hold_counters_[k] <= (kBlocksForOnsetDetection - kErleHold)) {
+ if (erle_[k] > erle_onsets_[k]) {
+ erle_[k] = std::max(erle_onsets_[k], 0.97f * erle_[k]);
+ RTC_DCHECK_LE(min_erle_, erle_[k]);
+ }
+ if (hold_counters_[k] <= 0) {
+ coming_onset_[k] = true;
+ hold_counters_[k] = 0;
+ }
}
}
}
diff --git a/modules/audio_processing/aec3/erle_estimator.h b/modules/audio_processing/aec3/erle_estimator.h
index 19bc7b4..8160dbe 100644
--- a/modules/audio_processing/aec3/erle_estimator.h
+++ b/modules/audio_processing/aec3/erle_estimator.h
@@ -27,11 +27,15 @@
ErleEstimator(float min_erle, float max_erle_lf, float max_erle_hf);
~ErleEstimator();
+ // Reset the ERLE estimator.
+ void Reset();
+
// Updates the ERLE estimate.
void Update(rtc::ArrayView<const float> render_spectrum,
rtc::ArrayView<const float> capture_spectrum,
rtc::ArrayView<const float> subtractor_spectrum,
- bool converged_filter);
+ bool converged_filter,
+ bool onset_detection);
// Returns the most recent ERLE estimate.
const std::array<float, kFftLengthBy2Plus1>& Erle() const { return erle_; }
diff --git a/modules/audio_processing/aec3/erle_estimator_unittest.cc b/modules/audio_processing/aec3/erle_estimator_unittest.cc
index 86ac5df..1687568 100644
--- a/modules/audio_processing/aec3/erle_estimator_unittest.cc
+++ b/modules/audio_processing/aec3/erle_estimator_unittest.cc
@@ -10,8 +10,8 @@
#include <cmath>
-#include "modules/audio_processing/aec3/erle_estimator.h"
#include "api/array_view.h"
+#include "modules/audio_processing/aec3/erle_estimator.h"
#include "test/gtest.h"
namespace webrtc {
@@ -74,7 +74,7 @@
FormFarendFrame(&X2, &E2, &Y2, kTrueErle);
for (size_t k = 0; k < 200; ++k) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
VerifyErle(estimator.Erle(), std::pow(2.f, estimator.ErleTimeDomainLog2()),
kMaxErleLf, kMaxErleHf);
@@ -83,7 +83,7 @@
// Verifies that the ERLE is not immediately decreased during nearend
// activity.
for (size_t k = 0; k < 50; ++k) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
VerifyErle(estimator.Erle(), std::pow(2.f, estimator.ErleTimeDomainLog2()),
kMaxErleLf, kMaxErleHf);
@@ -99,21 +99,21 @@
for (size_t burst = 0; burst < 20; ++burst) {
FormFarendFrame(&X2, &E2, &Y2, kTrueErleOnsets);
for (size_t k = 0; k < 10; ++k) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
FormFarendFrame(&X2, &E2, &Y2, kTrueErle);
for (size_t k = 0; k < 200; ++k) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
FormNearendFrame(&X2, &E2, &Y2);
for (size_t k = 0; k < 300; ++k) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
}
VerifyErleBands(estimator.ErleOnsets(), kMinErle, kMinErle);
FormNearendFrame(&X2, &E2, &Y2);
for (size_t k = 0; k < 1000; k++) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
// Verifies that during ne activity, Erle converges to the Erle for onsets.
VerifyErle(estimator.Erle(), std::pow(2.f, estimator.ErleTimeDomainLog2()),
@@ -131,7 +131,7 @@
X2.fill(1000.f * 1000.f);
Y2.fill(10 * E2[0]);
for (size_t k = 0; k < 200; ++k) {
- estimator.Update(X2, Y2, E2, true);
+ estimator.Update(X2, Y2, E2, true, true);
}
VerifyErle(estimator.Erle(), std::pow(2.f, estimator.ErleTimeDomainLog2()),
kMinErle, kMinErle);
diff --git a/modules/audio_processing/aec3/fft_data.h b/modules/audio_processing/aec3/fft_data.h
index 59511b5..5e5adb6 100644
--- a/modules/audio_processing/aec3/fft_data.h
+++ b/modules/audio_processing/aec3/fft_data.h
@@ -11,7 +11,9 @@
#ifndef MODULES_AUDIO_PROCESSING_AEC3_FFT_DATA_H_
#define MODULES_AUDIO_PROCESSING_AEC3_FFT_DATA_H_
-#include "typedefs.h" // NOLINT(build/include)
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif
diff --git a/modules/audio_processing/aec3/fft_data_unittest.cc b/modules/audio_processing/aec3/fft_data_unittest.cc
index 8fc5ca7..0812fd6 100644
--- a/modules/audio_processing/aec3/fft_data_unittest.cc
+++ b/modules/audio_processing/aec3/fft_data_unittest.cc
@@ -10,9 +10,9 @@
#include "modules/audio_processing/aec3/fft_data.h"
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/aec3/filter_analyzer.cc b/modules/audio_processing/aec3/filter_analyzer.cc
index ab2c4f2..790cb1e 100644
--- a/modules/audio_processing/aec3/filter_analyzer.cc
+++ b/modules/audio_processing/aec3/filter_analyzer.cc
@@ -95,10 +95,9 @@
const RenderBuffer& render_buffer) {
// Preprocess the filter to avoid issues with low-frequency components in the
// filter.
- if (use_preprocessed_filter_) {
- PreProcessFilter(filter_time_domain);
- data_dumper_->DumpRaw("aec3_linear_filter_processed_td", h_highpass_);
- }
+ PreProcessFilter(filter_time_domain);
+ data_dumper_->DumpRaw("aec3_linear_filter_processed_td", h_highpass_);
+
const auto& filter_to_analyze =
use_preprocessed_filter_ ? h_highpass_ : filter_time_domain;
RTC_DCHECK_EQ(filter_to_analyze.size(), filter_time_domain.size());
diff --git a/modules/audio_processing/aec3/filter_analyzer.h b/modules/audio_processing/aec3/filter_analyzer.h
index 627341d..47e9533 100644
--- a/modules/audio_processing/aec3/filter_analyzer.h
+++ b/modules/audio_processing/aec3/filter_analyzer.h
@@ -54,16 +54,14 @@
// Returns the number of blocks for the current used filter.
float FilterLengthBlocks() const { return filter_length_blocks_; }
+ // Returns the preprocessed filter.
+ rtc::ArrayView<const float> GetAdjustedFilter() const { return h_highpass_; }
+
private:
void UpdateFilterGain(rtc::ArrayView<const float> filter_time_domain,
size_t max_index);
void PreProcessFilter(rtc::ArrayView<const float> filter_time_domain);
- // Updates the estimation of the frequency response at the filter tails.
- void UpdateFreqRespTail(
- const std::vector<std::array<float, kFftLengthBy2Plus1>>&
- filter_freq_response);
-
static int instance_count_;
std::unique_ptr<ApmDataDumper> data_dumper_;
const bool use_preprocessed_filter_;
diff --git a/modules/audio_processing/aec3/main_filter_update_gain.cc b/modules/audio_processing/aec3/main_filter_update_gain.cc
index 6d31ed0..4f48cd4 100644
--- a/modules/audio_processing/aec3/main_filter_update_gain.cc
+++ b/modules/audio_processing/aec3/main_filter_update_gain.cc
@@ -22,7 +22,6 @@
namespace {
constexpr float kHErrorInitial = 10000.f;
-constexpr float kHErrorGainChange = 10000.f;
constexpr int kPoorExcitationCounterInitial = 1000;
} // namespace
@@ -48,7 +47,7 @@
void MainFilterUpdateGain::HandleEchoPathChange(
const EchoPathVariability& echo_path_variability) {
if (echo_path_variability.gain_change) {
- H_error_.fill(kHErrorGainChange);
+ // TODO(bugs.webrtc.org/9526) Handle gain changes.
}
if (echo_path_variability.delay_change !=
diff --git a/modules/audio_processing/aec3/matched_filter.cc b/modules/audio_processing/aec3/matched_filter.cc
index 466acd4..7486ddf 100644
--- a/modules/audio_processing/aec3/matched_filter.cc
+++ b/modules/audio_processing/aec3/matched_filter.cc
@@ -9,10 +9,12 @@
*/
#include "modules/audio_processing/aec3/matched_filter.h"
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#if defined(WEBRTC_HAS_NEON)
#include <arm_neon.h>
#endif
-#include "typedefs.h" // NOLINT(build/include)
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif
diff --git a/modules/audio_processing/aec3/matched_filter.h b/modules/audio_processing/aec3/matched_filter.h
index 8add6fe..1c06b5e 100644
--- a/modules/audio_processing/aec3/matched_filter.h
+++ b/modules/audio_processing/aec3/matched_filter.h
@@ -20,6 +20,7 @@
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/downsampled_render_buffer.h"
#include "rtc_base/constructormagic.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
namespace aec3 {
diff --git a/modules/audio_processing/aec3/matched_filter_unittest.cc b/modules/audio_processing/aec3/matched_filter_unittest.cc
index fd878ff..c7dc211 100644
--- a/modules/audio_processing/aec3/matched_filter_unittest.cc
+++ b/modules/audio_processing/aec3/matched_filter_unittest.cc
@@ -10,7 +10,9 @@
#include "modules/audio_processing/aec3/matched_filter.h"
-#include "typedefs.h" // NOLINT(build/include)
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#if defined(WEBRTC_ARCH_X86_FAMILY)
#include <emmintrin.h>
#endif
diff --git a/modules/audio_processing/aec3/render_buffer.cc b/modules/audio_processing/aec3/render_buffer.cc
index 6e224be..235e3e3 100644
--- a/modules/audio_processing/aec3/render_buffer.cc
+++ b/modules/audio_processing/aec3/render_buffer.cc
@@ -47,4 +47,28 @@
}
}
+void RenderBuffer::SpectralSums(
+ size_t num_spectra_shorter,
+ size_t num_spectra_longer,
+ std::array<float, kFftLengthBy2Plus1>* X2_shorter,
+ std::array<float, kFftLengthBy2Plus1>* X2_longer) const {
+ RTC_DCHECK_LE(num_spectra_shorter, num_spectra_longer);
+ X2_shorter->fill(0.f);
+ int position = spectrum_buffer_->read;
+ size_t j = 0;
+ for (; j < num_spectra_shorter; ++j) {
+ std::transform(X2_shorter->begin(), X2_shorter->end(),
+ spectrum_buffer_->buffer[position].begin(),
+ X2_shorter->begin(), std::plus<float>());
+ position = spectrum_buffer_->IncIndex(position);
+ }
+ std::copy(X2_shorter->begin(), X2_shorter->end(), X2_longer->begin());
+ for (; j < num_spectra_longer; ++j) {
+ std::transform(X2_longer->begin(), X2_longer->end(),
+ spectrum_buffer_->buffer[position].begin(),
+ X2_longer->begin(), std::plus<float>());
+ position = spectrum_buffer_->IncIndex(position);
+ }
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/aec3/render_buffer.h b/modules/audio_processing/aec3/render_buffer.h
index 34e7edf..dd67268 100644
--- a/modules/audio_processing/aec3/render_buffer.h
+++ b/modules/audio_processing/aec3/render_buffer.h
@@ -61,6 +61,12 @@
void SpectralSum(size_t num_spectra,
std::array<float, kFftLengthBy2Plus1>* X2) const;
+ // Returns the sums of the spectrums for two numbers of FFTs.
+ void SpectralSums(size_t num_spectra_shorter,
+ size_t num_spectra_longer,
+ std::array<float, kFftLengthBy2Plus1>* X2_shorter,
+ std::array<float, kFftLengthBy2Plus1>* X2_longer) const;
+
// Gets the recent activity seen in the render signal.
bool GetRenderActivity() const { return render_activity_; }
diff --git a/modules/audio_processing/aec3/residual_echo_estimator.cc b/modules/audio_processing/aec3/residual_echo_estimator.cc
index 43002e3..2e3ad9f 100644
--- a/modules/audio_processing/aec3/residual_echo_estimator.cc
+++ b/modules/audio_processing/aec3/residual_echo_estimator.cc
@@ -113,7 +113,7 @@
if (echo_reverb_) {
echo_reverb_->AddReverb(
render_buffer.Spectrum(aec_state.FilterLengthBlocks() + 1),
- aec_state.GetFreqRespTail(), aec_state.ReverbDecay(), *R2);
+ aec_state.GetReverbFrequencyResponse(), aec_state.ReverbDecay(), *R2);
} else {
RTC_DCHECK(echo_reverb_fallback);
diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.cc b/modules/audio_processing/aec3/reverb_decay_estimator.cc
new file mode 100644
index 0000000..f80afa2
--- /dev/null
+++ b/modules/audio_processing/aec3/reverb_decay_estimator.cc
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2018 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 "modules/audio_processing/aec3/reverb_decay_estimator.h"
+
+#include <algorithm>
+#include <cmath>
+#include <numeric>
+
+#include "api/array_view.h"
+#include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/checks.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+
+namespace {
+
+bool EnforceAdaptiveEchoReverbEstimation() {
+ return field_trial::IsEnabled(
+ "WebRTC-Aec3EnableAdaptiveEchoReverbEstimation");
+}
+
+constexpr int kEarlyReverbMinSizeBlocks = 3;
+constexpr int kBlocksPerSection = 6;
+// Linear regression approach assumes symmetric index around 0.
+constexpr float kEarlyReverbFirstPointAtLinearRegressors =
+ -0.5f * kBlocksPerSection * kFftLengthBy2 + 0.5f;
+
+// Averages the values in a block of size kFftLengthBy2;
+float BlockAverage(rtc::ArrayView<const float> v, size_t block_index) {
+ constexpr float kOneByFftLengthBy2 = 1.f / kFftLengthBy2;
+ const int i = block_index * kFftLengthBy2;
+ RTC_DCHECK_GE(v.size(), i + kFftLengthBy2);
+ const float sum =
+ std::accumulate(v.begin() + i, v.begin() + i + kFftLengthBy2, 0.f);
+ return sum * kOneByFftLengthBy2;
+}
+
+// Analyzes the gain in a block.
+void AnalyzeBlockGain(const std::array<float, kFftLengthBy2>& h2,
+ float floor_gain,
+ float* previous_gain,
+ bool* block_adapting,
+ bool* decaying_gain) {
+ float gain = std::max(BlockAverage(h2, 0), 1e-32f);
+ *block_adapting =
+ *previous_gain > 1.1f * gain || *previous_gain < 0.9f * gain;
+ *decaying_gain = gain > floor_gain;
+ *previous_gain = gain;
+}
+
+// Arithmetic sum of $2 \sum_{i=0.5}^{(N-1)/2}i^2$ calculated directly.
+constexpr float SymmetricArithmetricSum(int N) {
+ return N * (N * N - 1.0f) * (1.f / 12.f);
+}
+
+// Returns the peak energy of an impulse response.
+float BlockEnergyPeak(rtc::ArrayView<const float> h, int peak_block) {
+ RTC_DCHECK_LE((peak_block + 1) * kFftLengthBy2, h.size());
+ RTC_DCHECK_GE(peak_block, 0);
+ float peak_value =
+ *std::max_element(h.begin() + peak_block * kFftLengthBy2,
+ h.begin() + (peak_block + 1) * kFftLengthBy2,
+ [](float a, float b) { return a * a < b * b; });
+ return peak_value * peak_value;
+}
+
+// Returns the average energy of an impulse response block.
+float BlockEnergyAverage(rtc::ArrayView<const float> h, int block_index) {
+ RTC_DCHECK_LE((block_index + 1) * kFftLengthBy2, h.size());
+ RTC_DCHECK_GE(block_index, 0);
+ constexpr float kOneByFftLengthBy2 = 1.f / kFftLengthBy2;
+ const auto sum_of_squares = [](float a, float b) { return a + b * b; };
+ return std::accumulate(h.begin() + block_index * kFftLengthBy2,
+ h.begin() + (block_index + 1) * kFftLengthBy2, 0.f,
+ sum_of_squares) *
+ kOneByFftLengthBy2;
+}
+
+} // namespace
+
+ReverbDecayEstimator::ReverbDecayEstimator(const EchoCanceller3Config& config)
+ : filter_length_blocks_(config.filter.main.length_blocks),
+ filter_length_coefficients_(GetTimeDomainLength(filter_length_blocks_)),
+ use_adaptive_echo_decay_(config.ep_strength.default_len < 0.f ||
+ EnforceAdaptiveEchoReverbEstimation()),
+ early_reverb_estimator_(config.filter.main.length_blocks -
+ kEarlyReverbMinSizeBlocks),
+ late_reverb_start_(kEarlyReverbMinSizeBlocks),
+ late_reverb_end_(kEarlyReverbMinSizeBlocks),
+ decay_(std::fabs(config.ep_strength.default_len)) {
+ previous_gains_.fill(0.f);
+ RTC_DCHECK_GT(config.filter.main.length_blocks,
+ static_cast<size_t>(kEarlyReverbMinSizeBlocks));
+}
+
+ReverbDecayEstimator::~ReverbDecayEstimator() = default;
+
+void ReverbDecayEstimator::Update(rtc::ArrayView<const float> filter,
+ const absl::optional<float>& filter_quality,
+ int filter_delay_blocks,
+ bool usable_linear_filter,
+ bool stationary_signal) {
+ const int filter_size = static_cast<int>(filter.size());
+
+ if (stationary_signal) {
+ return;
+ }
+
+ bool estimation_feasible =
+ filter_delay_blocks <=
+ filter_length_blocks_ - kEarlyReverbMinSizeBlocks - 1;
+ estimation_feasible =
+ estimation_feasible && filter_size == filter_length_coefficients_;
+ estimation_feasible = estimation_feasible && filter_delay_blocks > 0;
+ estimation_feasible = estimation_feasible && usable_linear_filter;
+
+ if (!estimation_feasible) {
+ ResetDecayEstimation();
+ return;
+ }
+
+ if (!use_adaptive_echo_decay_) {
+ return;
+ }
+
+ const float new_smoothing = filter_quality ? *filter_quality * 0.2f : 0.f;
+ smoothing_constant_ = std::max(new_smoothing, smoothing_constant_);
+ if (smoothing_constant_ == 0.f) {
+ return;
+ }
+
+ if (block_to_analyze_ < filter_length_blocks_) {
+ // Analyze the filter and accumulate data for reverb estimation.
+ AnalyzeFilter(filter);
+ ++block_to_analyze_;
+ } else {
+ // When the filter is fully analyzed, estimate the reverb decay and reset
+ // the block_to_analyze_ counter.
+ EstimateDecay(filter, filter_delay_blocks);
+ }
+}
+
+void ReverbDecayEstimator::ResetDecayEstimation() {
+ early_reverb_estimator_.Reset();
+ late_reverb_decay_estimator_.Reset(0);
+ block_to_analyze_ = 0;
+ estimation_region_candidate_size_ = 0;
+ estimation_region_identified_ = false;
+ smoothing_constant_ = 0.f;
+ late_reverb_start_ = 0;
+ late_reverb_end_ = 0;
+}
+
+void ReverbDecayEstimator::EstimateDecay(rtc::ArrayView<const float> filter,
+ int peak_block) {
+ auto& h = filter;
+ RTC_DCHECK_EQ(0, h.size() % kFftLengthBy2);
+
+ // Reset the block analysis counter.
+ block_to_analyze_ =
+ std::min(peak_block + kEarlyReverbMinSizeBlocks, filter_length_blocks_);
+
+ // To estimate the reverb decay, the energy of the first filter section must
+ // be substantially larger than the last. Also, the first filter section
+ // energy must not deviate too much from the max peak.
+ const float first_reverb_gain = BlockEnergyAverage(h, block_to_analyze_);
+ const size_t h_size_blocks = h.size() >> kFftLengthBy2Log2;
+ tail_gain_ = BlockEnergyAverage(h, h_size_blocks - 1);
+ float peak_energy = BlockEnergyPeak(h, peak_block);
+ const bool sufficient_reverb_decay = first_reverb_gain > 4.f * tail_gain_;
+ const bool valid_filter =
+ first_reverb_gain > 2.f * tail_gain_ && peak_energy < 100.f;
+
+ // Estimate the size of the regions with early and late reflections.
+ const int size_early_reverb = early_reverb_estimator_.Estimate();
+ const int size_late_reverb =
+ std::max(estimation_region_candidate_size_ - size_early_reverb, 0);
+
+ // Only update the reverb decay estimate if the size of the identified late
+ // reverb is sufficiently large.
+ if (size_late_reverb >= 5) {
+ if (valid_filter && late_reverb_decay_estimator_.EstimateAvailable()) {
+ float decay = std::pow(
+ 2.0f, late_reverb_decay_estimator_.Estimate() * kFftLengthBy2);
+ constexpr float kMaxDecay = 0.95f; // ~1 sec min RT60.
+ constexpr float kMinDecay = 0.02f; // ~15 ms max RT60.
+ decay = std::max(.97f * decay_, decay);
+ decay = std::min(decay, kMaxDecay);
+ decay = std::max(decay, kMinDecay);
+ decay_ += smoothing_constant_ * (decay - decay_);
+ }
+
+ // Update length of decay. Must have enough data (number of sections) in
+ // order to estimate decay rate.
+ late_reverb_decay_estimator_.Reset(size_late_reverb * kFftLengthBy2);
+ late_reverb_start_ =
+ peak_block + kEarlyReverbMinSizeBlocks + size_early_reverb;
+ late_reverb_end_ =
+ block_to_analyze_ + estimation_region_candidate_size_ - 1;
+ } else {
+ late_reverb_decay_estimator_.Reset(0);
+ late_reverb_start_ = 0;
+ late_reverb_end_ = 0;
+ }
+
+ // Reset variables for the identification of the region for reverb decay
+ // estimation.
+ estimation_region_identified_ = !(valid_filter && sufficient_reverb_decay);
+ estimation_region_candidate_size_ = 0;
+
+ // Stop estimation of the decay until another good filter is received.
+ smoothing_constant_ = 0.f;
+
+ // Reset early reflections detector.
+ early_reverb_estimator_.Reset();
+}
+
+void ReverbDecayEstimator::AnalyzeFilter(rtc::ArrayView<const float> filter) {
+ auto h = rtc::ArrayView<const float>(
+ filter.begin() + block_to_analyze_ * kFftLengthBy2, kFftLengthBy2);
+
+ // Compute squared filter coeffiecients for the block to analyze_;
+ std::array<float, kFftLengthBy2> h2;
+ std::transform(h.begin(), h.end(), h2.begin(), [](float a) { return a * a; });
+
+ // Map out the region for estimating the reverb decay.
+ bool adapting;
+ bool above_noise_floor;
+ AnalyzeBlockGain(h2, tail_gain_, &previous_gains_[block_to_analyze_],
+ &adapting, &above_noise_floor);
+
+ // Count consecutive number of "good" filter sections, where "good" means:
+ // 1) energy is above noise floor.
+ // 2) energy of current section has not changed too much from last check.
+ estimation_region_identified_ =
+ estimation_region_identified_ || adapting || !above_noise_floor;
+ if (!estimation_region_identified_) {
+ ++estimation_region_candidate_size_;
+ }
+
+ // Accumulate data for reverb decay estimation and for the estimation of early
+ // reflections.
+ if (block_to_analyze_ <= late_reverb_end_) {
+ if (block_to_analyze_ >= late_reverb_start_) {
+ for (float h2_k : h2) {
+ float h2_log2 = FastApproxLog2f(h2_k + 1e-10);
+ late_reverb_decay_estimator_.Accumulate(h2_log2);
+ early_reverb_estimator_.Accumulate(h2_log2, smoothing_constant_);
+ }
+ } else {
+ for (float h2_k : h2) {
+ float h2_log2 = FastApproxLog2f(h2_k + 1e-10);
+ early_reverb_estimator_.Accumulate(h2_log2, smoothing_constant_);
+ }
+ }
+ }
+}
+
+void ReverbDecayEstimator::Dump(ApmDataDumper* data_dumper) const {
+ data_dumper->DumpRaw("aec3_reverb_decay", decay_);
+ data_dumper->DumpRaw("aec3_reverb_tail_energy", tail_gain_);
+ data_dumper->DumpRaw("aec3_reverb_alpha", smoothing_constant_);
+ data_dumper->DumpRaw("aec3_num_reverb_decay_blocks",
+ late_reverb_end_ - late_reverb_start_);
+ data_dumper->DumpRaw("aec3_late_reverb_start", late_reverb_start_);
+ data_dumper->DumpRaw("aec3_late_reverb_end", late_reverb_end_);
+ early_reverb_estimator_.Dump(data_dumper);
+}
+
+void ReverbDecayEstimator::LateReverbLinearRegressor::Reset(
+ int num_data_points) {
+ RTC_DCHECK_LE(0, num_data_points);
+ RTC_DCHECK_EQ(0, num_data_points % 2);
+ const int N = num_data_points;
+ nz_ = 0.f;
+ // Arithmetic sum of $2 \sum_{i=0.5}^{(N-1)/2}i^2$ calculated directly.
+ nn_ = SymmetricArithmetricSum(N);
+ // The linear regression approach assumes symmetric index around 0.
+ count_ = N > 0 ? count_ = -N * 0.5f + 0.5f : 0.f;
+ N_ = N;
+ n_ = 0;
+}
+
+void ReverbDecayEstimator::LateReverbLinearRegressor::Accumulate(float z) {
+ nz_ += count_ * z;
+ ++count_;
+ ++n_;
+}
+
+float ReverbDecayEstimator::LateReverbLinearRegressor::Estimate() {
+ RTC_DCHECK(EstimateAvailable());
+ if (nn_ == 0.f) {
+ RTC_NOTREACHED();
+ return 0.f;
+ }
+ return nz_ / nn_;
+}
+
+ReverbDecayEstimator::EarlyReverbLengthEstimator::EarlyReverbLengthEstimator(
+ int max_blocks)
+ : numerators_smooth_(max_blocks - kBlocksPerSection, 0.f),
+ numerators_(numerators_smooth_.size(), 0.f),
+ coefficients_counter_(0) {
+ RTC_DCHECK_LE(0, max_blocks);
+}
+
+ReverbDecayEstimator::EarlyReverbLengthEstimator::
+ ~EarlyReverbLengthEstimator() = default;
+
+void ReverbDecayEstimator::EarlyReverbLengthEstimator::Reset() {
+ coefficients_counter_ = 0;
+ std::fill(numerators_.begin(), numerators_.end(), 0.f);
+ block_counter_ = 0;
+}
+
+void ReverbDecayEstimator::EarlyReverbLengthEstimator::Accumulate(
+ float value,
+ float smoothing) {
+ // Each section is composed by kBlocksPerSection blocks and each section
+ // overlaps with the next one in (kBlocksPerSection - 1) blocks. For example,
+ // the first section covers the blocks [0:5], the second covers the blocks
+ // [1:6] and so on. As a result, for each value, kBlocksPerSection sections
+ // need to be updated.
+ int first_section_index = std::max(block_counter_ - kBlocksPerSection + 1, 0);
+ int last_section_index =
+ std::min(block_counter_, static_cast<int>(numerators_.size() - 1));
+ float x_value = static_cast<float>(coefficients_counter_) +
+ kEarlyReverbFirstPointAtLinearRegressors;
+ const float value_to_inc = kFftLengthBy2 * value;
+ float value_to_add =
+ x_value * value + (block_counter_ - last_section_index) * value_to_inc;
+ for (int section = last_section_index; section >= first_section_index;
+ --section, value_to_add += value_to_inc) {
+ numerators_[section] += value_to_add;
+ }
+
+ // Check if this update was the last coefficient of the current block. In that
+ // case, check if we are at the end of one of the sections and update the
+ // numerator of the linear regressor that is computed in such section.
+ if (++coefficients_counter_ == kFftLengthBy2) {
+ if (block_counter_ >= (kBlocksPerSection - 1)) {
+ size_t section = block_counter_ - (kBlocksPerSection - 1);
+ RTC_DCHECK_GT(numerators_.size(), section);
+ RTC_DCHECK_GT(numerators_smooth_.size(), section);
+ numerators_smooth_[section] +=
+ smoothing * (numerators_[section] - numerators_smooth_[section]);
+ n_sections_ = section + 1;
+ }
+ ++block_counter_;
+ coefficients_counter_ = 0;
+ }
+}
+
+// Estimates the size in blocks of the early reverb. The estimation is done by
+// comparing the tilt that is estimated in each section. As an optimization
+// detail and due to the fact that all the linear regressors that are computed
+// shared the same denominator, the comparison of the tilts is done by a
+// comparison of the numerator of the linear regressors.
+int ReverbDecayEstimator::EarlyReverbLengthEstimator::Estimate() {
+ constexpr float N = kBlocksPerSection * kFftLengthBy2;
+ constexpr float nn = SymmetricArithmetricSum(N);
+ // numerator_11 refers to the quantity that the linear regressor needs in the
+ // numerator for getting a decay equal to 1.1 (which is not a decay).
+ // log2(1.1) * nn / kFftLengthBy2.
+ constexpr float numerator_11 = 0.13750352374993502f * nn / kFftLengthBy2;
+ // log2(0.8) * nn / kFftLengthBy2.
+ constexpr float numerator_08 = -0.32192809488736229f * nn / kFftLengthBy2;
+ constexpr int kNumSectionsToAnalyze = 9;
+
+ if (n_sections_ < kNumSectionsToAnalyze) {
+ return 0;
+ }
+
+ // Estimation of the blocks that correspond to early reverberations. The
+ // estimation is done by analyzing the impulse response. The portions of the
+ // impulse response whose energy is not decreasing over its coefficients are
+ // considered to be part of the early reverberations. Furthermore, the blocks
+ // where the energy is decreasing faster than what it does at the end of the
+ // impulse response are also considered to be part of the early
+ // reverberations. The estimation is limited to the first
+ // kNumSectionsToAnalyze sections.
+
+ RTC_DCHECK_LE(n_sections_, numerators_smooth_.size());
+ const float min_numerator_tail =
+ *std::min_element(numerators_smooth_.begin() + kNumSectionsToAnalyze,
+ numerators_smooth_.begin() + n_sections_);
+ int early_reverb_size_minus_1 = 0;
+ for (int k = 0; k < kNumSectionsToAnalyze; ++k) {
+ if ((numerators_smooth_[k] > numerator_11) ||
+ (numerators_smooth_[k] < numerator_08 &&
+ numerators_smooth_[k] < 0.9f * min_numerator_tail)) {
+ early_reverb_size_minus_1 = k;
+ }
+ }
+
+ return early_reverb_size_minus_1 == 0 ? 0 : early_reverb_size_minus_1 + 1;
+}
+
+void ReverbDecayEstimator::EarlyReverbLengthEstimator::Dump(
+ ApmDataDumper* data_dumper) const {
+ data_dumper->DumpRaw("aec3_er_acum_numerator", numerators_smooth_);
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/aec3/reverb_decay_estimator.h b/modules/audio_processing/aec3/reverb_decay_estimator.h
new file mode 100644
index 0000000..67a84ab
--- /dev/null
+++ b/modules/audio_processing/aec3/reverb_decay_estimator.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2018 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 MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_
+#define MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_
+
+#include <array>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/audio/echo_canceller3_config.h"
+#include "modules/audio_processing/aec3/aec3_common.h"
+
+namespace webrtc {
+
+class ApmDataDumper;
+
+// Class for estimating the decay of the late reverb.
+class ReverbDecayEstimator {
+ public:
+ explicit ReverbDecayEstimator(const EchoCanceller3Config& config);
+ ~ReverbDecayEstimator();
+ // Updates the decay estimate.
+ void Update(rtc::ArrayView<const float> filter,
+ const absl::optional<float>& filter_quality,
+ int filter_delay_blocks,
+ bool usable_linear_filter,
+ bool stationary_signal);
+ // Returns the decay for the exponential model.
+ float Decay() const { return decay_; }
+ // Dumps debug data.
+ void Dump(ApmDataDumper* data_dumper) const;
+
+ private:
+ void EstimateDecay(rtc::ArrayView<const float> filter, int peak_block);
+ void AnalyzeFilter(rtc::ArrayView<const float> filter);
+
+ void ResetDecayEstimation();
+
+ // Class for estimating the decay of the late reverb from the linear filter.
+ class LateReverbLinearRegressor {
+ public:
+ // Resets the estimator to receive a specified number of data points.
+ void Reset(int num_data_points);
+ // Accumulates estimation data.
+ void Accumulate(float z);
+ // Estimates the decay.
+ float Estimate();
+ // Returns whether an estimate is available.
+ bool EstimateAvailable() const { return n_ == N_ && N_ != 0; }
+
+ public:
+ float nz_ = 0.f;
+ float nn_ = 0.f;
+ float count_ = 0.f;
+ int N_ = 0;
+ int n_ = 0;
+ };
+
+ // Class for identifying the length of the early reverb from the linear
+ // filter. For identifying the early reverberations, the impulse response is
+ // divided in sections and the tilt of each section is computed by a linear
+ // regressor.
+ class EarlyReverbLengthEstimator {
+ public:
+ explicit EarlyReverbLengthEstimator(int max_blocks);
+ ~EarlyReverbLengthEstimator();
+
+ // Resets the estimator.
+ void Reset();
+ // Accumulates estimation data.
+ void Accumulate(float value, float smoothing);
+ // Estimates the size in blocks of the early reverb.
+ int Estimate();
+ // Dumps debug data.
+ void Dump(ApmDataDumper* data_dumper) const;
+
+ private:
+ std::vector<float> numerators_smooth_;
+ std::vector<float> numerators_;
+ int coefficients_counter_;
+ int block_counter_ = 0;
+ int n_sections_ = 0;
+ };
+
+ const int filter_length_blocks_;
+ const int filter_length_coefficients_;
+ const bool use_adaptive_echo_decay_;
+ LateReverbLinearRegressor late_reverb_decay_estimator_;
+ EarlyReverbLengthEstimator early_reverb_estimator_;
+ int late_reverb_start_;
+ int late_reverb_end_;
+ int block_to_analyze_ = 0;
+ int estimation_region_candidate_size_ = 0;
+ bool estimation_region_identified_ = false;
+ std::array<float, kMaxAdaptiveFilterLength> previous_gains_;
+ float decay_;
+ float tail_gain_ = 0.f;
+ float smoothing_constant_ = 0.f;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_AEC3_REVERB_DECAY_ESTIMATOR_H_
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.cc b/modules/audio_processing/aec3/reverb_frequency_response.cc
new file mode 100644
index 0000000..0d82515
--- /dev/null
+++ b/modules/audio_processing/aec3/reverb_frequency_response.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018 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 "modules/audio_processing/aec3/reverb_frequency_response.h"
+
+#include <algorithm>
+#include <array>
+#include <cmath>
+#include <memory>
+#include <numeric>
+
+#include "api/array_view.h"
+#include "api/audio/echo_canceller3_config.h"
+#include "modules/audio_processing/aec3/aec3_common.h"
+#include "rtc_base/checks.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+
+namespace {
+
+bool EnableSmoothUpdatesTailFreqResp() {
+ return !field_trial::IsEnabled(
+ "WebRTC-Aec3SmoothUpdatesTailFreqRespKillSwitch");
+}
+
+// Computes the ratio of the energies between the direct path and the tail. The
+// energy is computed in the power spectrum domain discarding the DC
+// contributions.
+float AverageDecayWithinFilter(
+ rtc::ArrayView<const float> freq_resp_direct_path,
+ rtc::ArrayView<const float> freq_resp_tail) {
+ // Skipping the DC for the ratio computation
+ constexpr size_t kSkipBins = 1;
+ RTC_CHECK_EQ(freq_resp_direct_path.size(), freq_resp_tail.size());
+
+ float direct_path_energy =
+ std::accumulate(freq_resp_direct_path.begin() + kSkipBins,
+ freq_resp_direct_path.end(), 0.f);
+
+ if (direct_path_energy == 0.f) {
+ return 0.f;
+ }
+
+ float tail_energy = std::accumulate(freq_resp_tail.begin() + kSkipBins,
+ freq_resp_tail.end(), 0.f);
+ return tail_energy / direct_path_energy;
+}
+
+} // namespace
+
+ReverbFrequencyResponse::ReverbFrequencyResponse()
+ : enable_smooth_tail_response_updates_(EnableSmoothUpdatesTailFreqResp()) {
+ tail_response_.fill(0.f);
+}
+ReverbFrequencyResponse::~ReverbFrequencyResponse() = default;
+
+void ReverbFrequencyResponse::Update(
+ const std::vector<std::array<float, kFftLengthBy2Plus1>>&
+ frequency_response,
+ int filter_delay_blocks,
+ const absl::optional<float>& linear_filter_quality,
+ bool stationary_block) {
+ if (!enable_smooth_tail_response_updates_) {
+ Update(frequency_response, filter_delay_blocks, 0.5f);
+ return;
+ }
+
+ if (stationary_block || !linear_filter_quality) {
+ return;
+ }
+
+ Update(frequency_response, filter_delay_blocks, *linear_filter_quality);
+}
+
+void ReverbFrequencyResponse::Update(
+ const std::vector<std::array<float, kFftLengthBy2Plus1>>&
+ frequency_response,
+ int filter_delay_blocks,
+ float linear_filter_quality) {
+ rtc::ArrayView<const float> freq_resp_tail(
+ frequency_response[frequency_response.size() - 1]);
+
+ rtc::ArrayView<const float> freq_resp_direct_path(
+ frequency_response[filter_delay_blocks]);
+
+ float average_decay =
+ AverageDecayWithinFilter(freq_resp_direct_path, freq_resp_tail);
+
+ const float smoothing = 0.2f * linear_filter_quality;
+ average_decay_ += smoothing * (average_decay - average_decay_);
+
+ for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) {
+ tail_response_[k] = freq_resp_direct_path[k] * average_decay_;
+ }
+
+ for (size_t k = 1; k < kFftLengthBy2; ++k) {
+ const float avg_neighbour =
+ 0.5f * (tail_response_[k - 1] + tail_response_[k + 1]);
+ tail_response_[k] = std::max(tail_response_[k], avg_neighbour);
+ }
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/aec3/reverb_frequency_response.h b/modules/audio_processing/aec3/reverb_frequency_response.h
new file mode 100644
index 0000000..23485e0
--- /dev/null
+++ b/modules/audio_processing/aec3/reverb_frequency_response.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 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 MODULES_AUDIO_PROCESSING_AEC3_REVERB_FREQUENCY_RESPONSE_H_
+#define MODULES_AUDIO_PROCESSING_AEC3_REVERB_FREQUENCY_RESPONSE_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "modules/audio_processing/aec3/aec3_common.h"
+#include "modules/audio_processing/logging/apm_data_dumper.h"
+
+namespace webrtc {
+
+// Class for updating the frequency response for the reverb.
+class ReverbFrequencyResponse {
+ public:
+ ReverbFrequencyResponse();
+ ~ReverbFrequencyResponse();
+
+ // Updates the frequency response estimate of the reverb.
+ void Update(const std::vector<std::array<float, kFftLengthBy2Plus1>>&
+ frequency_response,
+ int filter_delay_blocks,
+ const absl::optional<float>& linear_filter_quality,
+ bool stationary_block);
+
+ // Returns the estimated frequency response for the reverb.
+ rtc::ArrayView<const float> FrequencyResponse() const {
+ return tail_response_;
+ }
+
+ private:
+ void Update(const std::vector<std::array<float, kFftLengthBy2Plus1>>&
+ frequency_response,
+ int filter_delay_blocks,
+ float linear_filter_quality);
+
+ const bool enable_smooth_tail_response_updates_;
+ float average_decay_ = 0.f;
+ std::array<float, kFftLengthBy2Plus1> tail_response_;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_AEC3_REVERB_FREQUENCY_RESPONSE_H_
diff --git a/modules/audio_processing/aec3/reverb_model_estimator.cc b/modules/audio_processing/aec3/reverb_model_estimator.cc
index 84e8e48..ce3e2be 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator.cc
+++ b/modules/audio_processing/aec3/reverb_model_estimator.cc
@@ -10,313 +10,28 @@
#include "modules/audio_processing/aec3/reverb_model_estimator.h"
-#include <algorithm>
-#include <array>
-#include <cmath>
-#include <memory>
-#include <numeric>
-
-#include "api/array_view.h"
-#include "api/audio/echo_canceller3_config.h"
-#include "modules/audio_processing/aec3/aec3_common.h"
-#include "rtc_base/checks.h"
-#include "system_wrappers/include/field_trial.h"
-
namespace webrtc {
-namespace {
-
-bool EnableSmoothUpdatesTailFreqResp() {
- return !field_trial::IsEnabled(
- "WebRTC-Aec3SmoothUpdatesTailFreqRespKillSwitch");
-}
-
-// Computes the ratio of the energies between the direct path and the tail. The
-// energy is computed in the power spectrum domain discarding the DC
-// contributions.
-float ComputeRatioEnergies(
- const rtc::ArrayView<const float>& freq_resp_direct_path,
- const rtc::ArrayView<const float>& freq_resp_tail) {
- // Skipping the DC for the ratio computation
- constexpr size_t n_skip_bins = 1;
- RTC_CHECK_EQ(freq_resp_direct_path.size(), freq_resp_tail.size());
-
- float direct_path_energy =
- std::accumulate(freq_resp_direct_path.begin() + n_skip_bins,
- freq_resp_direct_path.end(), 0.f);
-
- float tail_energy = std::accumulate(freq_resp_tail.begin() + n_skip_bins,
- freq_resp_tail.end(), 0.f);
-
- if (direct_path_energy > 0) {
- return tail_energy / direct_path_energy;
- } else {
- return 0.f;
- }
-}
-
-} // namespace
-
ReverbModelEstimator::ReverbModelEstimator(const EchoCanceller3Config& config)
- : filter_main_length_blocks_(config.filter.main.length_blocks),
- reverb_decay_(std::fabs(config.ep_strength.default_len)),
- enable_smooth_freq_resp_tail_updates_(EnableSmoothUpdatesTailFreqResp()) {
- block_energies_.fill(0.f);
- freq_resp_tail_.fill(0.f);
-}
+ : reverb_decay_estimator_(config) {}
ReverbModelEstimator::~ReverbModelEstimator() = default;
-bool ReverbModelEstimator::IsAGoodFilterForDecayEstimation(
- int filter_delay_blocks,
- bool usable_linear_estimate,
- size_t length_filter) {
- if ((filter_delay_blocks && usable_linear_estimate) &&
- (filter_delay_blocks <=
- static_cast<int>(filter_main_length_blocks_) - 4) &&
- (length_filter >=
- static_cast<size_t>(GetTimeDomainLength(filter_main_length_blocks_)))) {
- return true;
- } else {
- return false;
- }
-}
-
void ReverbModelEstimator::Update(
- const std::vector<float>& impulse_response,
+ rtc::ArrayView<const float> impulse_response,
const std::vector<std::array<float, kFftLengthBy2Plus1>>&
- filter_freq_response,
- const absl::optional<float>& quality_linear,
+ frequency_response,
+ const absl::optional<float>& linear_filter_quality,
int filter_delay_blocks,
bool usable_linear_estimate,
- float default_decay,
bool stationary_block) {
- if (enable_smooth_freq_resp_tail_updates_) {
- if (!stationary_block) {
- float alpha = 0;
- if (quality_linear) {
- alpha = 0.2f * quality_linear.value();
- UpdateFreqRespTail(filter_freq_response, filter_delay_blocks, alpha);
- }
- if (IsAGoodFilterForDecayEstimation(filter_delay_blocks,
- usable_linear_estimate,
- impulse_response.size())) {
- alpha_ = std::max(alpha, alpha_);
- if ((alpha_ > 0.f) && (default_decay < 0.f)) {
- // Echo tail decay estimation if default_decay is negative.
- UpdateReverbDecay(impulse_response);
- }
- } else {
- ResetDecayEstimation();
- }
- }
- } else {
- UpdateFreqRespTail(filter_freq_response, filter_delay_blocks, 0.1f);
- }
+ // Estimate the frequency response for the reverb.
+ reverb_frequency_response_.Update(frequency_response, filter_delay_blocks,
+ linear_filter_quality, stationary_block);
+
+ // Estimate the reverb decay,
+ reverb_decay_estimator_.Update(impulse_response, linear_filter_quality,
+ filter_delay_blocks, usable_linear_estimate,
+ stationary_block);
}
-
-void ReverbModelEstimator::ResetDecayEstimation() {
- accumulated_nz_ = 0.f;
- accumulated_nn_ = 0.f;
- accumulated_count_ = 0.f;
- current_reverb_decay_section_ = 0;
- num_reverb_decay_sections_ = 0;
- num_reverb_decay_sections_next_ = 0;
- found_end_of_reverb_decay_ = false;
- alpha_ = 0.f;
-}
-
-void ReverbModelEstimator::UpdateReverbDecay(
- const std::vector<float>& impulse_response) {
- constexpr float kOneByFftLengthBy2 = 1.f / kFftLengthBy2;
-
- // Form the data to match against by squaring the impulse response
- // coefficients.
- std::array<float, GetTimeDomainLength(kMaxAdaptiveFilterLength)>
- matching_data_data;
- RTC_DCHECK_LE(GetTimeDomainLength(filter_main_length_blocks_),
- matching_data_data.size());
- rtc::ArrayView<float> matching_data(
- matching_data_data.data(),
- GetTimeDomainLength(filter_main_length_blocks_));
- std::transform(
- impulse_response.begin(), impulse_response.end(), matching_data.begin(),
- [](float a) { return a * a; }); // TODO(devicentepena) check if focusing
- // on one block would be enough.
-
- if (current_reverb_decay_section_ < filter_main_length_blocks_) {
- // Update accumulated variables for the current filter section.
-
- const size_t start_index = current_reverb_decay_section_ * kFftLengthBy2;
-
- RTC_DCHECK_GT(matching_data.size(), start_index);
- RTC_DCHECK_GE(matching_data.size(), start_index + kFftLengthBy2);
- float section_energy =
- std::accumulate(matching_data.begin() + start_index,
- matching_data.begin() + start_index + kFftLengthBy2,
- 0.f) *
- kOneByFftLengthBy2;
-
- section_energy = std::max(
- section_energy, 1e-32f); // Regularization to avoid division by 0.
-
- RTC_DCHECK_LT(current_reverb_decay_section_, block_energies_.size());
- const float energy_ratio =
- block_energies_[current_reverb_decay_section_] / section_energy;
-
- found_end_of_reverb_decay_ = found_end_of_reverb_decay_ ||
- (energy_ratio > 1.1f || energy_ratio < 0.9f);
-
- // Count consecutive number of "good" filter sections, where "good" means:
- // 1) energy is above noise floor.
- // 2) energy of current section has not changed too much from last check.
- if (!found_end_of_reverb_decay_ && section_energy > tail_energy_) {
- ++num_reverb_decay_sections_next_;
- } else {
- found_end_of_reverb_decay_ = true;
- }
-
- block_energies_[current_reverb_decay_section_] = section_energy;
-
- if (num_reverb_decay_sections_ > 0) {
- // Linear regression of log squared magnitude of impulse response.
- for (size_t i = 0; i < kFftLengthBy2; i++) {
- RTC_DCHECK_GT(matching_data.size(), start_index + i);
- float z = FastApproxLog2f(matching_data[start_index + i] + 1e-10);
- accumulated_nz_ += accumulated_count_ * z;
- ++accumulated_count_;
- }
- }
-
- num_reverb_decay_sections_ =
- num_reverb_decay_sections_ > 0 ? num_reverb_decay_sections_ - 1 : 0;
- ++current_reverb_decay_section_;
-
- } else {
- constexpr float kMaxDecay = 0.95f; // ~1 sec min RT60.
- constexpr float kMinDecay = 0.02f; // ~15 ms max RT60.
-
- // Accumulated variables throughout whole filter.
-
- // Solve for decay rate.
-
- float decay = reverb_decay_;
-
- if (accumulated_nn_ != 0.f) {
- const float exp_candidate = -accumulated_nz_ / accumulated_nn_;
- decay = std::pow(2.0f, -exp_candidate * kFftLengthBy2);
- decay = std::min(decay, kMaxDecay);
- decay = std::max(decay, kMinDecay);
- }
-
- // Filter tail energy (assumed to be noise).
- constexpr size_t kTailLength = kFftLengthBy2;
-
- constexpr float k1ByTailLength = 1.f / kTailLength;
- const size_t tail_index =
- GetTimeDomainLength(filter_main_length_blocks_) - kTailLength;
-
- RTC_DCHECK_GT(matching_data.size(), tail_index);
-
- tail_energy_ = std::accumulate(matching_data.begin() + tail_index,
- matching_data.end(), 0.f) *
- k1ByTailLength;
-
- // Update length of decay.
- num_reverb_decay_sections_ = num_reverb_decay_sections_next_;
- num_reverb_decay_sections_next_ = 0;
- // Must have enough data (number of sections) in order
- // to estimate decay rate.
- if (num_reverb_decay_sections_ < 5) {
- num_reverb_decay_sections_ = 0;
- }
-
- const float N = num_reverb_decay_sections_ * kFftLengthBy2;
- accumulated_nz_ = 0.f;
- const float k1By12 = 1.f / 12.f;
- // Arithmetic sum $2 \sum_{i=0.5}^{(N-1)/2}i^2$ calculated directly.
- accumulated_nn_ = N * (N * N - 1.0f) * k1By12;
- accumulated_count_ = -N * 0.5f;
- // Linear regression approach assumes symmetric index around 0.
- accumulated_count_ += 0.5f;
-
- // Identify the peak index of the impulse response.
- const size_t peak_index = std::distance(
- matching_data.begin(),
- std::max_element(matching_data.begin(), matching_data.end()));
-
- current_reverb_decay_section_ = peak_index * kOneByFftLengthBy2 + 3;
- // Make sure we're not out of bounds.
- if (current_reverb_decay_section_ + 1 >= filter_main_length_blocks_) {
- current_reverb_decay_section_ = filter_main_length_blocks_;
- }
- size_t start_index = current_reverb_decay_section_ * kFftLengthBy2;
- float first_section_energy =
- std::accumulate(matching_data.begin() + start_index,
- matching_data.begin() + start_index + kFftLengthBy2,
- 0.f) *
- kOneByFftLengthBy2;
-
- // To estimate the reverb decay, the energy of the first filter section
- // must be substantially larger than the last.
- // Also, the first filter section energy must not deviate too much
- // from the max peak.
- bool main_filter_has_reverb = first_section_energy > 4.f * tail_energy_;
- bool main_filter_is_sane = first_section_energy > 2.f * tail_energy_ &&
- matching_data[peak_index] < 100.f;
-
- // Not detecting any decay, but tail is over noise - assume max decay.
- if (num_reverb_decay_sections_ == 0 && main_filter_is_sane &&
- main_filter_has_reverb) {
- decay = kMaxDecay;
- }
-
- if (main_filter_is_sane && num_reverb_decay_sections_ > 0) {
- decay = std::max(.97f * reverb_decay_, decay);
- reverb_decay_ -= alpha_ * (reverb_decay_ - decay);
- }
-
- found_end_of_reverb_decay_ =
- !(main_filter_is_sane && main_filter_has_reverb);
- alpha_ = 0.f; // Stop estimation of the decay until another good filter is
- // received
- }
-}
-
-// Updates the estimation of the frequency response at the filter tail.
-void ReverbModelEstimator::UpdateFreqRespTail(
- const std::vector<std::array<float, kFftLengthBy2Plus1>>&
- filter_freq_response,
- int filter_delay_blocks,
- float alpha) {
- size_t num_blocks = filter_freq_response.size();
- rtc::ArrayView<const float> freq_resp_tail(
- filter_freq_response[num_blocks - 1]);
- rtc::ArrayView<const float> freq_resp_direct_path(
- filter_freq_response[filter_delay_blocks]);
- float ratio_energies =
- ComputeRatioEnergies(freq_resp_direct_path, freq_resp_tail);
- ratio_tail_to_direct_path_ +=
- alpha * (ratio_energies - ratio_tail_to_direct_path_);
-
- for (size_t k = 0; k < kFftLengthBy2Plus1; ++k) {
- freq_resp_tail_[k] = freq_resp_direct_path[k] * ratio_tail_to_direct_path_;
- }
-
- for (size_t k = 1; k < kFftLengthBy2; ++k) {
- float avg_neighbour =
- 0.5f * (freq_resp_tail_[k - 1] + freq_resp_tail_[k + 1]);
- freq_resp_tail_[k] = std::max(freq_resp_tail_[k], avg_neighbour);
- }
-}
-
-void ReverbModelEstimator::Dump(
- const std::unique_ptr<ApmDataDumper>& data_dumper) {
- data_dumper->DumpRaw("aec3_reverb_decay", reverb_decay_);
- data_dumper->DumpRaw("aec3_reverb_tail_energy", tail_energy_);
- data_dumper->DumpRaw("aec3_reverb_alpha", alpha_);
- data_dumper->DumpRaw("aec3_num_reverb_decay_sections",
- static_cast<int>(num_reverb_decay_sections_));
-}
-
} // namespace webrtc
diff --git a/modules/audio_processing/aec3/reverb_model_estimator.h b/modules/audio_processing/aec3/reverb_model_estimator.h
index d2015aa..b6a3591 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator.h
+++ b/modules/audio_processing/aec3/reverb_model_estimator.h
@@ -11,72 +11,49 @@
#ifndef MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_ESTIMATOR_H_
#define MODULES_AUDIO_PROCESSING_AEC3_REVERB_MODEL_ESTIMATOR_H_
-#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/audio/echo_canceller3_config.h"
-#include "modules/audio_processing/aec3/aec3_common.h"
-#include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "modules/audio_processing/aec3/reverb_decay_estimator.h"
+#include "modules/audio_processing/aec3/reverb_frequency_response.h"
namespace webrtc {
-// The ReverbModelEstimator class describes an estimator of the parameters
-// that are used for the reverberant model.
+class ApmDataDumper;
+
+// Class for estimating the model parameters for the reverberant echo.
class ReverbModelEstimator {
public:
explicit ReverbModelEstimator(const EchoCanceller3Config& config);
~ReverbModelEstimator();
- // Updates the model.
- void Update(const std::vector<float>& impulse_response,
+
+ // Updates the estimates based on new data.
+ void Update(rtc::ArrayView<const float> impulse_response,
const std::vector<std::array<float, kFftLengthBy2Plus1>>&
- filter_freq_response,
- const absl::optional<float>& quality_linear,
+ frequency_response,
+ const absl::optional<float>& linear_filter_quality,
int filter_delay_blocks,
bool usable_linear_estimate,
- float default_decay,
bool stationary_block);
- // Returns the decay for the exponential model.
- float ReverbDecay() const { return reverb_decay_; }
- void Dump(const std::unique_ptr<ApmDataDumper>& data_dumper);
+ // Returns the exponential decay of the reverberant echo.
+ float ReverbDecay() const { return reverb_decay_estimator_.Decay(); }
- // Return the estimated freq. response of the tail of the filter.
- rtc::ArrayView<const float> GetFreqRespTail() const {
- return freq_resp_tail_;
+ // Return the frequency response of the reverberant echo.
+ rtc::ArrayView<const float> GetReverbFrequencyResponse() const {
+ return reverb_frequency_response_.FrequencyResponse();
+ }
+
+ // Dumps debug data.
+ void Dump(ApmDataDumper* data_dumper) const {
+ reverb_decay_estimator_.Dump(data_dumper);
}
private:
- bool IsAGoodFilterForDecayEstimation(int filter_delay_blocks,
- bool usable_linear_estimate,
- size_t length_filter);
- void UpdateReverbDecay(const std::vector<float>& impulse_response);
-
- void UpdateFreqRespTail(
- const std::vector<std::array<float, kFftLengthBy2Plus1>>&
- filter_freq_response,
- int filter_delay_blocks,
- float alpha);
-
- void ResetDecayEstimation();
-
- const size_t filter_main_length_blocks_;
-
- float accumulated_nz_ = 0.f;
- float accumulated_nn_ = 0.f;
- float accumulated_count_ = 0.f;
- size_t current_reverb_decay_section_ = 0;
- size_t num_reverb_decay_sections_ = 0;
- size_t num_reverb_decay_sections_next_ = 0;
- bool found_end_of_reverb_decay_ = false;
- std::array<float, kMaxAdaptiveFilterLength> block_energies_;
- float reverb_decay_;
- float tail_energy_ = 0.f;
- float alpha_ = 0.f;
- std::array<float, kFftLengthBy2Plus1> freq_resp_tail_;
- float ratio_tail_to_direct_path_ = 0.f;
- bool enable_smooth_freq_resp_tail_updates_;
+ ReverbDecayEstimator reverb_decay_estimator_;
+ ReverbFrequencyResponse reverb_frequency_response_;
};
} // namespace webrtc
diff --git a/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc b/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc
index 9667f4f..aa5e96f 100644
--- a/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc
+++ b/modules/audio_processing/aec3/reverb_model_estimator_unittest.cc
@@ -29,16 +29,16 @@
class ReverbModelEstimatorTest {
public:
explicit ReverbModelEstimatorTest(float default_decay)
- : default_decay_(default_decay),
- estimated_decay_(default_decay),
- h_(aec3_config_.filter.main.length_blocks * kBlockSize, 0.f),
- H2_(aec3_config_.filter.main.length_blocks) {
+ : default_decay_(default_decay), estimated_decay_(default_decay) {
aec3_config_.ep_strength.default_len = default_decay_;
+ aec3_config_.filter.main.length_blocks = 40;
+ h_.resize(aec3_config_.filter.main.length_blocks * kBlockSize);
+ H2_.resize(aec3_config_.filter.main.length_blocks);
CreateImpulseResponseWithDecay();
}
void RunEstimator();
float GetDecay() { return estimated_decay_; }
- float GetTrueDecay() { return true_power_decay_; }
+ float GetTrueDecay() { return kTruePowerDecay; }
float GetPowerTailDb() { return 10.f * log10(estimated_power_tail_); }
float GetTruePowerTailDb() { return 10.f * log10(true_power_tail_); }
@@ -46,10 +46,10 @@
void CreateImpulseResponseWithDecay();
absl::optional<float> quality_linear_ = 1.0f;
- static constexpr int filter_delay_blocks_ = 2;
- static constexpr bool usable_linear_estimate_ = true;
- static constexpr bool stationary_block_ = false;
- static constexpr float true_power_decay_ = 0.5f;
+ static constexpr int kFilterDelayBlocks = 2;
+ static constexpr bool kUsableLinearEstimate = true;
+ static constexpr bool kStationaryBlock = false;
+ static constexpr float kTruePowerDecay = 0.5f;
EchoCanceller3Config aec3_config_;
float default_decay_;
float estimated_decay_;
@@ -63,43 +63,35 @@
const Aec3Fft fft;
RTC_DCHECK_EQ(h_.size(), aec3_config_.filter.main.length_blocks * kBlockSize);
RTC_DCHECK_EQ(H2_.size(), aec3_config_.filter.main.length_blocks);
- RTC_DCHECK_EQ(filter_delay_blocks_, 2);
- const float peak = 1.0f;
- float decay_power_sample = std::sqrt(true_power_decay_);
- for (size_t k = 1; k < kBlockSizeLog2; k++) {
- decay_power_sample = std::sqrt(decay_power_sample);
- }
- h_[filter_delay_blocks_ * kBlockSize] = peak;
- for (size_t k = filter_delay_blocks_ * kBlockSize + 1; k < h_.size(); ++k) {
- h_[k] = h_[k - 1] * std::sqrt(decay_power_sample);
+ RTC_DCHECK_EQ(kFilterDelayBlocks, 2);
+
+ float decay_sample = std::sqrt(powf(kTruePowerDecay, 1.f / kBlockSize));
+ const size_t filter_delay_coefficients = kFilterDelayBlocks * kBlockSize;
+ std::fill(h_.begin(), h_.end(), 0.f);
+ h_[filter_delay_coefficients] = 1.f;
+ for (size_t k = filter_delay_coefficients + 1; k < h_.size(); ++k) {
+ h_[k] = h_[k - 1] * decay_sample;
}
- for (size_t block = 0; block < H2_.size(); ++block) {
- std::array<float, kFftLength> h_block;
- h_block.fill(0.f);
- FftData H_block;
- rtc::ArrayView<float> H2_block(H2_[block]);
- std::copy(h_.begin() + block * kBlockSize,
- h_.begin() + block * (kBlockSize + 1), h_block.begin());
-
- fft.Fft(&h_block, &H_block);
- for (size_t k = 0; k < H2_block.size(); ++k) {
- H2_block[k] =
- H_block.re[k] * H_block.re[k] + H_block.im[k] * H_block.im[k];
- }
+ std::array<float, kFftLength> fft_data;
+ FftData H_j;
+ for (size_t j = 0, k = 0; j < H2_.size(); ++j, k += kBlockSize) {
+ fft_data.fill(0.f);
+ std::copy(h_.begin() + k, h_.begin() + k + kBlockSize, fft_data.begin());
+ fft.Fft(&fft_data, &H_j);
+ H_j.Spectrum(Aec3Optimization::kNone, H2_[j]);
}
rtc::ArrayView<float> H2_tail(H2_[H2_.size() - 1]);
true_power_tail_ = std::accumulate(H2_tail.begin(), H2_tail.end(), 0.f);
}
void ReverbModelEstimatorTest::RunEstimator() {
ReverbModelEstimator estimator(aec3_config_);
- for (size_t k = 0; k < 1000; ++k) {
- estimator.Update(h_, H2_, quality_linear_, filter_delay_blocks_,
- usable_linear_estimate_, default_decay_,
- stationary_block_);
+ for (size_t k = 0; k < 3000; ++k) {
+ estimator.Update(h_, H2_, quality_linear_, kFilterDelayBlocks,
+ kUsableLinearEstimate, kStationaryBlock);
}
estimated_decay_ = estimator.ReverbDecay();
- rtc::ArrayView<const float> freq_resp_tail = estimator.GetFreqRespTail();
+ auto freq_resp_tail = estimator.GetReverbFrequencyResponse();
estimated_power_tail_ =
std::accumulate(freq_resp_tail.begin(), freq_resp_tail.end(), 0.f);
}
diff --git a/modules/audio_processing/aec3/subtractor.cc b/modules/audio_processing/aec3/subtractor.cc
index 614034b..609e8ac 100644
--- a/modules/audio_processing/aec3/subtractor.cc
+++ b/modules/audio_processing/aec3/subtractor.cc
@@ -128,12 +128,6 @@
G_shadow_(config_.filter.shadow_initial,
config.filter.config_change_duration_blocks) {
RTC_DCHECK(data_dumper_);
- // Currently, the rest of AEC3 requires the main and shadow filter lengths to
- // be identical.
- RTC_DCHECK_EQ(config_.filter.main.length_blocks,
- config_.filter.shadow.length_blocks);
- RTC_DCHECK_EQ(config_.filter.main_initial.length_blocks,
- config_.filter.shadow_initial.length_blocks);
}
Subtractor::~Subtractor() = default;
@@ -159,8 +153,6 @@
}
if (echo_path_variability.gain_change && enable_agc_gain_change_response_) {
- RTC_LOG(LS_WARNING) << "Resetting main filter adaptation speed due to "
- "microphone gain change";
G_main_.HandleEchoPathChange(echo_path_variability);
}
}
@@ -222,11 +214,28 @@
E_shadow.Spectrum(optimization_, output->E2_shadow);
E_main.Spectrum(optimization_, output->E2_main);
+ // Compute the render powers.
+ std::array<float, kFftLengthBy2Plus1> X2_main;
+ std::array<float, kFftLengthBy2Plus1> X2_shadow_data;
+ std::array<float, kFftLengthBy2Plus1>& X2_shadow =
+ main_filter_.SizePartitions() == shadow_filter_.SizePartitions()
+ ? X2_main
+ : X2_shadow_data;
+ if (main_filter_.SizePartitions() == shadow_filter_.SizePartitions()) {
+ render_buffer.SpectralSum(main_filter_.SizePartitions(), &X2_main);
+ } else if (main_filter_.SizePartitions() > shadow_filter_.SizePartitions()) {
+ render_buffer.SpectralSums(shadow_filter_.SizePartitions(),
+ main_filter_.SizePartitions(), &X2_shadow,
+ &X2_main);
+ } else {
+ render_buffer.SpectralSums(main_filter_.SizePartitions(),
+ shadow_filter_.SizePartitions(), &X2_main,
+ &X2_shadow);
+ }
+
// Update the main filter.
- std::array<float, kFftLengthBy2Plus1> X2;
- render_buffer.SpectralSum(main_filter_.SizePartitions(), &X2);
if (!main_filter_adjusted) {
- G_main_.Compute(X2, render_signal_analyzer, *output, main_filter_,
+ G_main_.Compute(X2_main, render_signal_analyzer, *output, main_filter_,
aec_state.SaturatedCapture() || main_saturation, &G);
} else {
G.re.fill(0.f);
@@ -244,19 +253,15 @@
(poor_shadow_filter_counter_ < 10 &&
!enable_early_shadow_filter_jumpstart_)) ||
!enable_shadow_filter_jumpstart_) {
- if (shadow_filter_.SizePartitions() != main_filter_.SizePartitions()) {
- render_buffer.SpectralSum(shadow_filter_.SizePartitions(), &X2);
- }
- G_shadow_.Compute(X2, render_signal_analyzer, E_shadow,
+ G_shadow_.Compute(X2_shadow, render_signal_analyzer, E_shadow,
shadow_filter_.SizePartitions(),
aec_state.SaturatedCapture() || shadow_saturation, &G);
shadow_filter_.Adapt(render_buffer, G);
} else {
poor_shadow_filter_counter_ = 0;
-
if (enable_shadow_filter_boosted_jumpstart_) {
shadow_filter_.SetFilter(main_filter_.GetFilter());
- G_shadow_.Compute(X2, render_signal_analyzer, E_main,
+ G_shadow_.Compute(X2_shadow, render_signal_analyzer, E_main,
shadow_filter_.SizePartitions(),
aec_state.SaturatedCapture() || main_saturation, &G);
shadow_filter_.Adapt(render_buffer, G);
@@ -277,6 +282,11 @@
std::for_each(e_main.begin(), e_main.end(),
[](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); });
}
+
+ data_dumper_->DumpWav("aec3_main_filter_output", kBlockSize, &e_main[0],
+ 16000, 1);
+ data_dumper_->DumpWav("aec3_shadow_filter_output", kBlockSize, &e_shadow[0],
+ 16000, 1);
}
void Subtractor::FilterMisadjustmentEstimator::Update(
diff --git a/modules/audio_processing/aec3/subtractor_output_analyzer.cc b/modules/audio_processing/aec3/subtractor_output_analyzer.cc
index 93675f5..3cacb45 100644
--- a/modules/audio_processing/aec3/subtractor_output_analyzer.cc
+++ b/modules/audio_processing/aec3/subtractor_output_analyzer.cc
@@ -36,19 +36,16 @@
constexpr float kConvergenceThreshold = 50 * 50 * kBlockSize;
main_filter_converged_ = e2_main < 0.5f * y2 && y2 > kConvergenceThreshold;
shadow_filter_converged_ =
- e2_shadow < 0.05 * y2 && y2 > kConvergenceThreshold;
+ e2_shadow < 0.05f * y2 && y2 > kConvergenceThreshold;
float min_e2 =
strict_divergence_check_ ? std::min(e2_main, e2_shadow) : e2_main;
filter_diverged_ = min_e2 > 1.5f * y2 && y2 > 30.f * 30.f * kBlockSize;
- filter_severely_diverged_ =
- min_e2 > 1.5f * y2 && y2 > 200.f * 200.f * kBlockSize;
}
void SubtractorOutputAnalyzer::HandleEchoPathChange() {
shadow_filter_converged_ = false;
main_filter_converged_ = false;
filter_diverged_ = false;
- filter_severely_diverged_ = false;
}
} // namespace webrtc
diff --git a/modules/audio_processing/aec3/subtractor_output_analyzer.h b/modules/audio_processing/aec3/subtractor_output_analyzer.h
index b9a2445..b59a68e 100644
--- a/modules/audio_processing/aec3/subtractor_output_analyzer.h
+++ b/modules/audio_processing/aec3/subtractor_output_analyzer.h
@@ -30,7 +30,6 @@
}
bool DivergedFilter() const { return filter_diverged_; }
- bool SeverelyDivergedFilter() const { return filter_severely_diverged_; }
// Handle echo path change.
void HandleEchoPathChange();
@@ -40,7 +39,6 @@
bool shadow_filter_converged_ = false;
bool main_filter_converged_ = false;
bool filter_diverged_ = false;
- bool filter_severely_diverged_ = false;
};
} // namespace webrtc
diff --git a/modules/audio_processing/aec3/subtractor_unittest.cc b/modules/audio_processing/aec3/subtractor_unittest.cc
index 35abf1c..7791805 100644
--- a/modules/audio_processing/aec3/subtractor_unittest.cc
+++ b/modules/audio_processing/aec3/subtractor_unittest.cc
@@ -25,13 +25,15 @@
float RunSubtractorTest(int num_blocks_to_process,
int delay_samples,
- int filter_length_blocks,
+ int main_filter_length_blocks,
+ int shadow_filter_length_blocks,
bool uncorrelated_inputs,
const std::vector<int>& blocks_with_echo_path_changes) {
ApmDataDumper data_dumper(42);
EchoCanceller3Config config;
- config.filter.main.length_blocks = config.filter.shadow.length_blocks =
- filter_length_blocks;
+ config.filter.main.length_blocks = main_filter_length_blocks;
+ config.filter.shadow.length_blocks = shadow_filter_length_blocks;
+
Subtractor subtractor(config, &data_dumper, DetectOptimization());
absl::optional<DelayEstimate> delay_estimate;
std::vector<std::vector<float>> x(3, std::vector<float>(kBlockSize, 0.f));
@@ -160,9 +162,9 @@
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
SCOPED_TRACE(ProduceDebugText(delay_samples, filter_length_blocks));
- float echo_to_nearend_power =
- RunSubtractorTest(400, delay_samples, filter_length_blocks, false,
- blocks_with_echo_path_changes);
+ float echo_to_nearend_power = RunSubtractorTest(
+ 400, delay_samples, filter_length_blocks, filter_length_blocks, false,
+ blocks_with_echo_path_changes);
// Use different criteria to take overmodelling into account.
if (filter_length_blocks == 12) {
@@ -174,6 +176,24 @@
}
}
+// Verifies that the subtractor is able to handle the case when the main filter
+// is longer than the shadow filter.
+TEST(Subtractor, MainFilterLongerThanShadowFilter) {
+ std::vector<int> blocks_with_echo_path_changes;
+ float echo_to_nearend_power =
+ RunSubtractorTest(400, 64, 20, 15, false, blocks_with_echo_path_changes);
+ EXPECT_GT(0.5f, echo_to_nearend_power);
+}
+
+// Verifies that the subtractor is able to handle the case when the shadow
+// filter is longer than the main filter.
+TEST(Subtractor, ShadowFilterLongerThanMainFilter) {
+ std::vector<int> blocks_with_echo_path_changes;
+ float echo_to_nearend_power =
+ RunSubtractorTest(400, 64, 15, 20, false, blocks_with_echo_path_changes);
+ EXPECT_GT(0.5f, echo_to_nearend_power);
+}
+
// Verifies that the subtractor does not converge on uncorrelated signals.
TEST(Subtractor, NonConvergenceOnUncorrelatedSignals) {
std::vector<int> blocks_with_echo_path_changes;
@@ -181,9 +201,9 @@
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
SCOPED_TRACE(ProduceDebugText(delay_samples, filter_length_blocks));
- float echo_to_nearend_power =
- RunSubtractorTest(300, delay_samples, filter_length_blocks, true,
- blocks_with_echo_path_changes);
+ float echo_to_nearend_power = RunSubtractorTest(
+ 300, delay_samples, filter_length_blocks, filter_length_blocks, true,
+ blocks_with_echo_path_changes);
EXPECT_NEAR(1.f, echo_to_nearend_power, 0.1);
}
}
@@ -198,9 +218,9 @@
for (size_t delay_samples : {0, 64, 150, 200, 301}) {
SCOPED_TRACE(ProduceDebugText(delay_samples, filter_length_blocks));
- float echo_to_nearend_power =
- RunSubtractorTest(100, delay_samples, filter_length_blocks, false,
- blocks_with_echo_path_changes);
+ float echo_to_nearend_power = RunSubtractorTest(
+ 100, delay_samples, filter_length_blocks, filter_length_blocks, false,
+ blocks_with_echo_path_changes);
EXPECT_NEAR(1.f, echo_to_nearend_power, 0.0000001f);
}
}
diff --git a/modules/audio_processing/aec3/suppression_gain.cc b/modules/audio_processing/aec3/suppression_gain.cc
index 846836d..c389a6a 100644
--- a/modules/audio_processing/aec3/suppression_gain.cc
+++ b/modules/audio_processing/aec3/suppression_gain.cc
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
@@ -11,10 +10,6 @@
#include "modules/audio_processing/aec3/suppression_gain.h"
-#include "typedefs.h" // NOLINT(build/include)
-#if defined(WEBRTC_ARCH_X86_FAMILY)
-#include <emmintrin.h>
-#endif
#include <math.h>
#include <algorithm>
#include <functional>
@@ -30,11 +25,6 @@
namespace webrtc {
namespace {
-bool EnableTransparencyImprovements() {
- return !field_trial::IsEnabled(
- "WebRTC-Aec3TransparencyImprovementsKillSwitch");
-}
-
bool EnableNewSuppression() {
return !field_trial::IsEnabled("WebRTC-Aec3NewSuppressionKillSwitch");
}
@@ -57,60 +47,6 @@
(*gain)[kFftLengthBy2] = (*gain)[kFftLengthBy2Minus1];
}
-// Computes the gain to apply for the bands beyond the first band.
-float UpperBandsGain(
- const absl::optional<int>& narrow_peak_band,
- bool saturated_echo,
- const std::vector<std::vector<float>>& render,
- const std::array<float, kFftLengthBy2Plus1>& low_band_gain) {
- RTC_DCHECK_LT(0, render.size());
- if (render.size() == 1) {
- return 1.f;
- }
-
- if (narrow_peak_band &&
- (*narrow_peak_band > static_cast<int>(kFftLengthBy2Plus1 - 10))) {
- return 0.001f;
- }
-
- constexpr size_t kLowBandGainLimit = kFftLengthBy2 / 2;
- const float gain_below_8_khz = *std::min_element(
- low_band_gain.begin() + kLowBandGainLimit, low_band_gain.end());
-
- // Always attenuate the upper bands when there is saturated echo.
- if (saturated_echo) {
- return std::min(0.001f, gain_below_8_khz);
- }
-
- // Compute the upper and lower band energies.
- const auto sum_of_squares = [](float a, float b) { return a + b * b; };
- const float low_band_energy =
- std::accumulate(render[0].begin(), render[0].end(), 0.f, sum_of_squares);
- float high_band_energy = 0.f;
- for (size_t k = 1; k < render.size(); ++k) {
- const float energy = std::accumulate(render[k].begin(), render[k].end(),
- 0.f, sum_of_squares);
- high_band_energy = std::max(high_band_energy, energy);
- }
-
- // If there is more power in the lower frequencies than the upper frequencies,
- // or if the power in upper frequencies is low, do not bound the gain in the
- // upper bands.
- float anti_howling_gain;
- constexpr float kThreshold = kBlockSize * 10.f * 10.f / 4.f;
- if (high_band_energy < std::max(low_band_energy, kThreshold)) {
- anti_howling_gain = 1.f;
- } else {
- // In all other cases, bound the gain for upper frequencies.
- RTC_DCHECK_LE(low_band_energy, high_band_energy);
- RTC_DCHECK_NE(0.f, high_band_energy);
- anti_howling_gain = 0.01f * sqrtf(low_band_energy / high_band_energy);
- }
-
- // Choose the gain as the minimum of the lower and upper gains.
- return std::min(gain_below_8_khz, anti_howling_gain);
-}
-
// Scales the echo according to assessed audibility at the other end.
void WeightEchoForAudibility(const EchoCanceller3Config& config,
rtc::ArrayView<const float> echo,
@@ -159,7 +95,6 @@
bool low_noise_render,
bool saturated_echo,
bool linear_echo_estimate,
- bool enable_transparency_improvements,
const std::array<float, kFftLengthBy2Plus1>& nearend,
const std::array<float, kFftLengthBy2Plus1>& weighted_echo,
const std::array<float, kFftLengthBy2Plus1>& masker,
@@ -181,10 +116,7 @@
RTC_DCHECK_GT(1.f, nearend_masking_margin);
const float masker_margin =
- linear_echo_estimate
- ? (enable_transparency_improvements ? config.gain_mask.m0
- : config.gain_mask.m1)
- : config.gain_mask.m8;
+ linear_echo_estimate ? config.gain_mask.m0 : config.gain_mask.m8;
for (size_t k = 0; k < gain->size(); ++k) {
// TODO(devicentepena): Experiment by removing the reverberation estimation
@@ -211,54 +143,6 @@
// TODO(peah): Make adaptive to take the actual filter error into account.
constexpr size_t kUpperAccurateBandPlus1 = 29;
-// Computes the signal output power that masks the echo signal.
-void MaskingPower(const EchoCanceller3Config& config,
- bool enable_transparency_improvements,
- const std::array<float, kFftLengthBy2Plus1>& nearend,
- const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
- const std::array<float, kFftLengthBy2Plus1>& last_masker,
- const std::array<float, kFftLengthBy2Plus1>& gain,
- std::array<float, kFftLengthBy2Plus1>* masker) {
- if (enable_transparency_improvements) {
- std::copy(comfort_noise.begin(), comfort_noise.end(), masker->begin());
- return;
- }
-
- // Apply masking over time.
- float masking_factor = config.gain_mask.temporal_masking_lf;
- auto limit = config.gain_mask.temporal_masking_lf_bands;
- std::transform(
- comfort_noise.begin(), comfort_noise.begin() + limit, last_masker.begin(),
- masker->begin(),
- [masking_factor](float a, float b) { return a + masking_factor * b; });
- masking_factor = config.gain_mask.temporal_masking_hf;
- std::transform(
- comfort_noise.begin() + limit, comfort_noise.end(),
- last_masker.begin() + limit, masker->begin() + limit,
- [masking_factor](float a, float b) { return a + masking_factor * b; });
-
- // Apply masking only between lower frequency bands.
- std::array<float, kFftLengthBy2Plus1> side_band_masker;
- float max_nearend_after_gain = 0.f;
- for (size_t k = 0; k < gain.size(); ++k) {
- const float nearend_after_gain = nearend[k] * gain[k];
- max_nearend_after_gain =
- std::max(max_nearend_after_gain, nearend_after_gain);
- side_band_masker[k] = nearend_after_gain + comfort_noise[k];
- }
-
- RTC_DCHECK_LT(kUpperAccurateBandPlus1, gain.size());
- for (size_t k = 1; k < kUpperAccurateBandPlus1; ++k) {
- (*masker)[k] += config.gain_mask.m5 *
- (side_band_masker[k - 1] + side_band_masker[k + 1]);
- }
-
- // Add full-band masking as a minimum value for the masker.
- const float min_masker = max_nearend_after_gain * config.gain_mask.m6;
- std::for_each(masker->begin(), masker->end(),
- [min_masker](float& a) { a = std::max(a, min_masker); });
-}
-
// Limits the gain in the frequencies for which the adaptive filter has not
// converged. Currently, these frequencies are not hardcoded to the frequencies
// which are typically not excited by speech.
@@ -280,6 +164,75 @@
int SuppressionGain::instance_count_ = 0;
+float SuppressionGain::UpperBandsGain(
+ const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
+ const std::array<float, kFftLengthBy2Plus1>& comfort_noise_spectrum,
+ const absl::optional<int>& narrow_peak_band,
+ bool saturated_echo,
+ const std::vector<std::vector<float>>& render,
+ const std::array<float, kFftLengthBy2Plus1>& low_band_gain) const {
+ RTC_DCHECK_LT(0, render.size());
+ if (render.size() == 1) {
+ return 1.f;
+ }
+
+ if (narrow_peak_band &&
+ (*narrow_peak_band > static_cast<int>(kFftLengthBy2Plus1 - 10))) {
+ return 0.001f;
+ }
+
+ constexpr size_t kLowBandGainLimit = kFftLengthBy2 / 2;
+ const float gain_below_8_khz = *std::min_element(
+ low_band_gain.begin() + kLowBandGainLimit, low_band_gain.end());
+
+ // Always attenuate the upper bands when there is saturated echo.
+ if (saturated_echo) {
+ return std::min(0.001f, gain_below_8_khz);
+ }
+
+ // Compute the upper and lower band energies.
+ const auto sum_of_squares = [](float a, float b) { return a + b * b; };
+ const float low_band_energy =
+ std::accumulate(render[0].begin(), render[0].end(), 0.f, sum_of_squares);
+ float high_band_energy = 0.f;
+ for (size_t k = 1; k < render.size(); ++k) {
+ const float energy = std::accumulate(render[k].begin(), render[k].end(),
+ 0.f, sum_of_squares);
+ high_band_energy = std::max(high_band_energy, energy);
+ }
+
+ // If there is more power in the lower frequencies than the upper frequencies,
+ // or if the power in upper frequencies is low, do not bound the gain in the
+ // upper bands.
+ float anti_howling_gain;
+ constexpr float kThreshold = kBlockSize * 10.f * 10.f / 4.f;
+ if (high_band_energy < std::max(low_band_energy, kThreshold)) {
+ anti_howling_gain = 1.f;
+ } else {
+ // In all other cases, bound the gain for upper frequencies.
+ RTC_DCHECK_LE(low_band_energy, high_band_energy);
+ RTC_DCHECK_NE(0.f, high_band_energy);
+ anti_howling_gain = 0.01f * sqrtf(low_band_energy / high_band_energy);
+ }
+
+ // Bound the upper gain during significant echo activity.
+ auto low_frequency_energy = [](rtc::ArrayView<const float> spectrum) {
+ RTC_DCHECK_LE(16, spectrum.size());
+ return std::accumulate(spectrum.begin() + 1, spectrum.begin() + 16, 0.f);
+ };
+ const float echo_sum = low_frequency_energy(echo_spectrum);
+ const float noise_sum = low_frequency_energy(comfort_noise_spectrum);
+ const auto& cfg = config_.suppressor.high_bands_suppression;
+ float gain_bound = 1.f;
+ if (echo_sum > cfg.enr_threshold * noise_sum &&
+ !dominant_nearend_detector_.IsNearendState()) {
+ gain_bound = cfg.max_gain_during_echo;
+ }
+
+ // Choose the gain as the minimum of the lower and upper gains.
+ return std::min(std::min(gain_below_8_khz, anti_howling_gain), gain_bound);
+}
+
// Computes the gain to reduce the echo to a non audible level.
void SuppressionGain::GainToNoAudibleEcho(
const std::array<float, kFftLengthBy2Plus1>& nearend,
@@ -288,13 +241,16 @@
const std::array<float, kFftLengthBy2Plus1>& min_gain,
const std::array<float, kFftLengthBy2Plus1>& max_gain,
std::array<float, kFftLengthBy2Plus1>* gain) const {
+ const auto& p = dominant_nearend_detector_.IsNearendState() ? nearend_params_
+ : normal_params_;
for (size_t k = 0; k < gain->size(); ++k) {
float enr = echo[k] / (nearend[k] + 1.f); // Echo-to-nearend ratio.
float emr = echo[k] / (masker[k] + 1.f); // Echo-to-masker (noise) ratio.
float g = 1.0f;
- if (enr > enr_transparent_[k] && emr > emr_transparent_[k]) {
- g = (enr_suppress_[k] - enr) / (enr_suppress_[k] - enr_transparent_[k]);
- g = std::max(g, emr_transparent_[k] / emr);
+ if (enr > p.enr_transparent_[k] && emr > p.emr_transparent_[k]) {
+ g = (p.enr_suppress_[k] - enr) /
+ (p.enr_suppress_[k] - p.enr_transparent_[k]);
+ g = std::max(g, p.emr_transparent_[k] / emr);
}
(*gain)[k] = std::max(std::min(g, max_gain[k]), min_gain[k]);
}
@@ -310,6 +266,9 @@
std::array<float, kFftLengthBy2Plus1>* gain) {
const bool saturated_echo = aec_state.SaturatedEcho();
const bool linear_echo_estimate = aec_state.UsableLinearEstimate();
+ const auto& params = dominant_nearend_detector_.IsNearendState()
+ ? nearend_params_
+ : normal_params_;
// Weight echo power in terms of audibility. // Precompute 1/weighted echo
// (note that when the echo is zero, the precomputed value is never used).
@@ -329,16 +288,13 @@
min_gain[k] = denom > 0.f ? min_echo_power / denom : 1.f;
min_gain[k] = std::min(min_gain[k], 1.f);
}
- if (enable_transparency_improvements_) {
- for (size_t k = 0; k < 6; ++k) {
- // Make sure the gains of the low frequencies do not decrease too
- // quickly after strong nearend.
- if (last_nearend_[k] > last_echo_[k]) {
- min_gain[k] =
- std::max(min_gain[k],
- last_gain_[k] * config_.gain_updates.max_dec_factor_lf);
- min_gain[k] = std::min(min_gain[k], 1.f);
- }
+ for (size_t k = 0; k < 6; ++k) {
+ // Make sure the gains of the low frequencies do not decrease too
+ // quickly after strong nearend.
+ if (last_nearend_[k] > last_echo_[k]) {
+ min_gain[k] =
+ std::max(min_gain[k], last_gain_[k] * params.max_dec_factor_lf);
+ min_gain[k] = std::min(min_gain[k], 1.f);
}
}
} else {
@@ -348,20 +304,10 @@
// Compute the maximum gain by limiting the gain increase from the previous
// gain.
std::array<float, kFftLengthBy2Plus1> max_gain;
- if (enable_transparency_improvements_) {
- for (size_t k = 0; k < gain->size(); ++k) {
- max_gain[k] =
- std::min(std::max(last_gain_[k] * config_.gain_updates.max_inc_factor,
- config_.gain_updates.floor_first_increase),
- 1.f);
- }
- } else {
- for (size_t k = 0; k < gain->size(); ++k) {
- max_gain[k] =
- std::min(std::max(last_gain_[k] * gain_increase_[k],
- config_.gain_updates.floor_first_increase),
- 1.f);
- }
+ for (size_t k = 0; k < gain->size(); ++k) {
+ max_gain[k] = std::min(std::max(last_gain_[k] * params.max_inc_factor,
+ config_.suppressor.floor_first_increase),
+ 1.f);
}
// Iteratively compute the gain required to attenuate the echo to a non
@@ -374,12 +320,11 @@
} else {
gain->fill(0.f);
for (int k = 0; k < 2; ++k) {
- MaskingPower(config_, enable_transparency_improvements_, nearend,
- comfort_noise, last_masker_, *gain, &masker);
- GainToNoAudibleEchoFallback(
- config_, low_noise_render, saturated_echo, linear_echo_estimate,
- enable_transparency_improvements_, nearend, weighted_echo, masker,
- min_gain, max_gain, one_by_weighted_echo, gain);
+ std::copy(comfort_noise.begin(), comfort_noise.end(), masker.begin());
+ GainToNoAudibleEchoFallback(config_, low_noise_render, saturated_echo,
+ linear_echo_estimate, nearend, weighted_echo,
+ masker, min_gain, max_gain,
+ one_by_weighted_echo, gain);
AdjustForExternalFilters(gain);
}
}
@@ -387,23 +332,16 @@
// Adjust the gain for frequencies which have not yet converged.
AdjustNonConvergedFrequencies(gain);
- // Update the allowed maximum gain increase.
- UpdateGainIncrease(low_noise_render, linear_echo_estimate, saturated_echo,
- weighted_echo, *gain);
-
// Store data required for the gain computation of the next block.
std::copy(nearend.begin(), nearend.end(), last_nearend_.begin());
std::copy(weighted_echo.begin(), weighted_echo.end(), last_echo_.begin());
std::copy(gain->begin(), gain->end(), last_gain_.begin());
- MaskingPower(config_, enable_transparency_improvements_, nearend,
- comfort_noise, last_masker_, *gain, &last_masker_);
aec3::VectorMath(optimization_).Sqrt(*gain);
// Debug outputs for the purpose of development and analysis.
data_dumper_->DumpRaw("aec3_suppressor_min_gain", min_gain);
data_dumper_->DumpRaw("aec3_suppressor_max_gain", max_gain);
data_dumper_->DumpRaw("aec3_suppressor_masker", masker);
- data_dumper_->DumpRaw("aec3_suppressor_last_masker", last_masker_);
}
SuppressionGain::SuppressionGain(const EchoCanceller3Config& config,
@@ -415,41 +353,18 @@
config_(config),
state_change_duration_blocks_(
static_cast<int>(config_.filter.config_change_duration_blocks)),
- coherence_gain_(sample_rate_hz,
- config_.suppressor.bands_with_reliable_coherence),
- enable_transparency_improvements_(EnableTransparencyImprovements()),
enable_new_suppression_(EnableNewSuppression()),
moving_average_(kFftLengthBy2Plus1,
- config.suppressor.nearend_average_blocks) {
+ config.suppressor.nearend_average_blocks),
+ nearend_params_(config_.suppressor.nearend_tuning),
+ normal_params_(config_.suppressor.normal_tuning),
+ dominant_nearend_detector_(
+ config_.suppressor.dominant_nearend_detection) {
RTC_DCHECK_LT(0, state_change_duration_blocks_);
one_by_state_change_duration_blocks_ = 1.f / state_change_duration_blocks_;
last_gain_.fill(1.f);
- last_masker_.fill(0.f);
- gain_increase_.fill(1.f);
last_nearend_.fill(0.f);
last_echo_.fill(0.f);
-
- // Compute per-band masking thresholds.
- constexpr size_t kLastLfBand = 5;
- constexpr size_t kFirstHfBand = 8;
- RTC_DCHECK_LT(kLastLfBand, kFirstHfBand);
- auto& lf = config.suppressor.mask_lf;
- auto& hf = config.suppressor.mask_hf;
- RTC_DCHECK_LT(lf.enr_transparent, lf.enr_suppress);
- RTC_DCHECK_LT(hf.enr_transparent, hf.enr_suppress);
- for (size_t k = 0; k < kFftLengthBy2Plus1; k++) {
- float a;
- if (k <= kLastLfBand) {
- a = 0.f;
- } else if (k < kFirstHfBand) {
- a = (k - kLastLfBand) / static_cast<float>(kFirstHfBand - kLastLfBand);
- } else {
- a = 1.f;
- }
- enr_transparent_[k] = (1 - a) * lf.enr_transparent + a * hf.enr_transparent;
- enr_suppress_[k] = (1 - a) * lf.enr_suppress + a * hf.enr_suppress;
- emr_transparent_[k] = (1 - a) * lf.emr_transparent + a * hf.emr_transparent;
- }
}
SuppressionGain::~SuppressionGain() = default;
@@ -457,9 +372,9 @@
void SuppressionGain::GetGain(
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
+ const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
const std::array<float, kFftLengthBy2Plus1>& comfort_noise_spectrum,
const FftData& linear_aec_fft,
- const FftData& render_fft,
const FftData& capture_fft,
const RenderSignalAnalyzer& render_signal_analyzer,
const AecState& aec_state,
@@ -468,28 +383,27 @@
std::array<float, kFftLengthBy2Plus1>* low_band_gain) {
RTC_DCHECK(high_bands_gain);
RTC_DCHECK(low_band_gain);
+ const auto& cfg = config_.suppressor;
+
+ if (cfg.enforce_transparent) {
+ low_band_gain->fill(1.f);
+ *high_bands_gain = cfg.enforce_empty_higher_bands ? 0.f : 1.f;
+ return;
+ }
std::array<float, kFftLengthBy2Plus1> nearend_average;
moving_average_.Average(nearend_spectrum, nearend_average);
+ // Update the state selection.
+ dominant_nearend_detector_.Update(nearend_spectrum, residual_echo_spectrum,
+ comfort_noise_spectrum);
+
// Compute gain for the lower band.
bool low_noise_render = low_render_detector_.Detect(render);
const absl::optional<int> narrow_peak_band =
render_signal_analyzer.NarrowPeakBand();
- LowerBandGain(low_noise_render, aec_state, nearend_average, echo_spectrum,
- comfort_noise_spectrum, low_band_gain);
-
- // Adjust the gain for bands where the coherence indicates not echo.
- if (config_.suppressor.bands_with_reliable_coherence > 0 &&
- !enable_transparency_improvements_) {
- std::array<float, kFftLengthBy2Plus1> G_coherence;
- coherence_gain_.ComputeGain(linear_aec_fft, render_fft, capture_fft,
- G_coherence);
- for (size_t k = 0; k < config_.suppressor.bands_with_reliable_coherence;
- ++k) {
- (*low_band_gain)[k] = std::max((*low_band_gain)[k], G_coherence[k]);
- }
- }
+ LowerBandGain(low_noise_render, aec_state, nearend_average,
+ residual_echo_spectrum, comfort_noise_spectrum, low_band_gain);
// Limit the gain of the lower bands during start up and after resets.
const float gain_upper_bound = aec_state.SuppressionGainLimit();
@@ -500,8 +414,12 @@
}
// Compute the gain for the upper bands.
- *high_bands_gain = UpperBandsGain(narrow_peak_band, aec_state.SaturatedEcho(),
- render, *low_band_gain);
+ *high_bands_gain =
+ UpperBandsGain(echo_spectrum, comfort_noise_spectrum, narrow_peak_band,
+ aec_state.SaturatedEcho(), render, *low_band_gain);
+ if (cfg.enforce_empty_higher_bands) {
+ *high_bands_gain = 0.f;
+ }
}
void SuppressionGain::SetInitialState(bool state) {
@@ -513,102 +431,6 @@
}
}
-void SuppressionGain::UpdateGainIncrease(
- bool low_noise_render,
- bool linear_echo_estimate,
- bool saturated_echo,
- const std::array<float, kFftLengthBy2Plus1>& echo,
- const std::array<float, kFftLengthBy2Plus1>& new_gain) {
- float max_inc;
- float max_dec;
- float rate_inc;
- float rate_dec;
- float min_inc;
- float min_dec;
-
- RTC_DCHECK_GE(state_change_duration_blocks_, initial_state_change_counter_);
- if (initial_state_change_counter_ > 0) {
- if (--initial_state_change_counter_ == 0) {
- initial_state_ = false;
- }
- }
- RTC_DCHECK_LE(0, initial_state_change_counter_);
-
- // EchoCanceller3Config::GainUpdates
- auto& p = config_.gain_updates;
- if (!linear_echo_estimate) {
- max_inc = p.nonlinear.max_inc;
- max_dec = p.nonlinear.max_dec;
- rate_inc = p.nonlinear.rate_inc;
- rate_dec = p.nonlinear.rate_dec;
- min_inc = p.nonlinear.min_inc;
- min_dec = p.nonlinear.min_dec;
- } else if (initial_state_ && !saturated_echo) {
- if (initial_state_change_counter_ > 0) {
- float change_factor =
- initial_state_change_counter_ * one_by_state_change_duration_blocks_;
-
- auto average = [](float from, float to, float from_weight) {
- return from * from_weight + to * (1.f - from_weight);
- };
-
- max_inc = average(p.initial.max_inc, p.normal.max_inc, change_factor);
- max_dec = average(p.initial.max_dec, p.normal.max_dec, change_factor);
- rate_inc = average(p.initial.rate_inc, p.normal.rate_inc, change_factor);
- rate_dec = average(p.initial.rate_dec, p.normal.rate_dec, change_factor);
- min_inc = average(p.initial.min_inc, p.normal.min_inc, change_factor);
- min_dec = average(p.initial.min_dec, p.normal.min_dec, change_factor);
- } else {
- max_inc = p.initial.max_inc;
- max_dec = p.initial.max_dec;
- rate_inc = p.initial.rate_inc;
- rate_dec = p.initial.rate_dec;
- min_inc = p.initial.min_inc;
- min_dec = p.initial.min_dec;
- }
- } else if (low_noise_render) {
- max_inc = p.low_noise.max_inc;
- max_dec = p.low_noise.max_dec;
- rate_inc = p.low_noise.rate_inc;
- rate_dec = p.low_noise.rate_dec;
- min_inc = p.low_noise.min_inc;
- min_dec = p.low_noise.min_dec;
- } else if (!saturated_echo) {
- max_inc = p.normal.max_inc;
- max_dec = p.normal.max_dec;
- rate_inc = p.normal.rate_inc;
- rate_dec = p.normal.rate_dec;
- min_inc = p.normal.min_inc;
- min_dec = p.normal.min_dec;
- } else {
- max_inc = p.saturation.max_inc;
- max_dec = p.saturation.max_dec;
- rate_inc = p.saturation.rate_inc;
- rate_dec = p.saturation.rate_dec;
- min_inc = p.saturation.min_inc;
- min_dec = p.saturation.min_dec;
- }
-
- for (size_t k = 0; k < new_gain.size(); ++k) {
- auto increase_update = [](float new_gain, float last_gain,
- float current_inc, float max_inc, float min_inc,
- float change_rate) {
- return new_gain > last_gain ? std::min(max_inc, current_inc * change_rate)
- : min_inc;
- };
-
- if (echo[k] > last_echo_[k]) {
- gain_increase_[k] =
- increase_update(new_gain[k], last_gain_[k], gain_increase_[k],
- max_inc, min_inc, rate_inc);
- } else {
- gain_increase_[k] =
- increase_update(new_gain[k], last_gain_[k], gain_increase_[k],
- max_dec, min_dec, rate_dec);
- }
- }
-}
-
// Detects when the render signal can be considered to have low power and
// consist of stationary noise.
bool SuppressionGain::LowNoiseRenderDetector::Detect(
@@ -628,4 +450,69 @@
return low_noise_render;
}
+SuppressionGain::DominantNearendDetector::DominantNearendDetector(
+ const EchoCanceller3Config::Suppressor::DominantNearendDetection config)
+ : enr_threshold_(config.enr_threshold),
+ snr_threshold_(config.snr_threshold),
+ hold_duration_(config.hold_duration),
+ trigger_threshold_(config.trigger_threshold) {}
+
+void SuppressionGain::DominantNearendDetector::Update(
+ rtc::ArrayView<const float> nearend_spectrum,
+ rtc::ArrayView<const float> residual_echo_spectrum,
+ rtc::ArrayView<const float> comfort_noise_spectrum) {
+ auto low_frequency_energy = [](rtc::ArrayView<const float> spectrum) {
+ RTC_DCHECK_LE(16, spectrum.size());
+ return std::accumulate(spectrum.begin() + 1, spectrum.begin() + 16, 0.f);
+ };
+ const float ne_sum = low_frequency_energy(nearend_spectrum);
+ const float echo_sum = low_frequency_energy(residual_echo_spectrum);
+ const float noise_sum = low_frequency_energy(comfort_noise_spectrum);
+
+ // Detect strong active nearend if the nearend is sufficiently stronger than
+ // the echo and the nearend noise.
+ if (ne_sum > enr_threshold_ * echo_sum &&
+ ne_sum > snr_threshold_ * noise_sum) {
+ if (++trigger_counter_ >= trigger_threshold_) {
+ // After a period of strong active nearend activity, flag nearend mode.
+ hold_counter_ = hold_duration_;
+ trigger_counter_ = trigger_threshold_;
+ }
+ } else {
+ // Forget previously detected strong active nearend activity.
+ trigger_counter_ = std::max(0, trigger_counter_ - 1);
+ }
+
+ // Remain in any nearend mode for a certain duration.
+ hold_counter_ = std::max(0, hold_counter_ - 1);
+ nearend_state_ = hold_counter_ > 0;
+}
+
+SuppressionGain::GainParameters::GainParameters(
+ const EchoCanceller3Config::Suppressor::Tuning& tuning)
+ : max_inc_factor(tuning.max_inc_factor),
+ max_dec_factor_lf(tuning.max_dec_factor_lf) {
+ // Compute per-band masking thresholds.
+ constexpr size_t kLastLfBand = 5;
+ constexpr size_t kFirstHfBand = 8;
+ RTC_DCHECK_LT(kLastLfBand, kFirstHfBand);
+ auto& lf = tuning.mask_lf;
+ auto& hf = tuning.mask_hf;
+ RTC_DCHECK_LT(lf.enr_transparent, lf.enr_suppress);
+ RTC_DCHECK_LT(hf.enr_transparent, hf.enr_suppress);
+ for (size_t k = 0; k < kFftLengthBy2Plus1; k++) {
+ float a;
+ if (k <= kLastLfBand) {
+ a = 0.f;
+ } else if (k < kFirstHfBand) {
+ a = (k - kLastLfBand) / static_cast<float>(kFirstHfBand - kLastLfBand);
+ } else {
+ a = 1.f;
+ }
+ enr_transparent_[k] = (1 - a) * lf.enr_transparent + a * hf.enr_transparent;
+ enr_suppress_[k] = (1 - a) * lf.enr_suppress + a * hf.enr_suppress;
+ emr_transparent_[k] = (1 - a) * lf.emr_transparent + a * hf.emr_transparent;
+ }
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/aec3/suppression_gain.h b/modules/audio_processing/aec3/suppression_gain.h
index 4c0c85d..b851930 100644
--- a/modules/audio_processing/aec3/suppression_gain.h
+++ b/modules/audio_processing/aec3/suppression_gain.h
@@ -17,7 +17,6 @@
#include "api/audio/echo_canceller3_config.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/aec_state.h"
-#include "modules/audio_processing/aec3/coherence_gain.h"
#include "modules/audio_processing/aec3/moving_average.h"
#include "modules/audio_processing/aec3/render_signal_analyzer.h"
#include "rtc_base/constructormagic.h"
@@ -33,9 +32,9 @@
void GetGain(
const std::array<float, kFftLengthBy2Plus1>& nearend_spectrum,
const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
+ const std::array<float, kFftLengthBy2Plus1>& residual_echo_spectrum,
const std::array<float, kFftLengthBy2Plus1>& comfort_noise_spectrum,
const FftData& linear_aec_fft,
- const FftData& render_fft,
const FftData& capture_fft,
const RenderSignalAnalyzer& render_signal_analyzer,
const AecState& aec_state,
@@ -47,6 +46,15 @@
void SetInitialState(bool state);
private:
+ // Computes the gain to apply for the bands beyond the first band.
+ float UpperBandsGain(
+ const std::array<float, kFftLengthBy2Plus1>& echo_spectrum,
+ const std::array<float, kFftLengthBy2Plus1>& comfort_noise_spectrum,
+ const absl::optional<int>& narrow_peak_band,
+ bool saturated_echo,
+ const std::vector<std::vector<float>>& render,
+ const std::array<float, kFftLengthBy2Plus1>& low_band_gain) const;
+
void GainToNoAudibleEcho(
const std::array<float, kFftLengthBy2Plus1>& nearend,
const std::array<float, kFftLengthBy2Plus1>& echo,
@@ -62,14 +70,6 @@
const std::array<float, kFftLengthBy2Plus1>& comfort_noise,
std::array<float, kFftLengthBy2Plus1>* gain);
- // Limits the gain increase.
- void UpdateGainIncrease(
- bool low_noise_render,
- bool linear_echo_estimate,
- bool saturated_echo,
- const std::array<float, kFftLengthBy2Plus1>& echo,
- const std::array<float, kFftLengthBy2Plus1>& new_gain);
-
class LowNoiseRenderDetector {
public:
bool Detect(const std::vector<std::vector<float>>& render);
@@ -78,6 +78,42 @@
float average_power_ = 32768.f * 32768.f;
};
+ // Class for selecting whether the suppressor is in the nearend or echo state.
+ class DominantNearendDetector {
+ public:
+ explicit DominantNearendDetector(
+ const EchoCanceller3Config::Suppressor::DominantNearendDetection
+ config);
+
+ // Returns whether the current state is the nearend state.
+ bool IsNearendState() const { return nearend_state_; }
+
+ // Updates the state selection based on latest spectral estimates.
+ void Update(rtc::ArrayView<const float> nearend_spectrum,
+ rtc::ArrayView<const float> residual_echo_spectrum,
+ rtc::ArrayView<const float> comfort_noise_spectrum);
+
+ private:
+ const float enr_threshold_;
+ const float snr_threshold_;
+ const int hold_duration_;
+ const int trigger_threshold_;
+
+ bool nearend_state_ = false;
+ int trigger_counter_ = 0;
+ int hold_counter_ = 0;
+ };
+
+ struct GainParameters {
+ explicit GainParameters(
+ const EchoCanceller3Config::Suppressor::Tuning& tuning);
+ const float max_inc_factor;
+ const float max_dec_factor_lf;
+ std::array<float, kFftLengthBy2Plus1> enr_transparent_;
+ std::array<float, kFftLengthBy2Plus1> enr_suppress_;
+ std::array<float, kFftLengthBy2Plus1> emr_transparent_;
+ };
+
static int instance_count_;
std::unique_ptr<ApmDataDumper> data_dumper_;
const Aec3Optimization optimization_;
@@ -85,20 +121,16 @@
const int state_change_duration_blocks_;
float one_by_state_change_duration_blocks_;
std::array<float, kFftLengthBy2Plus1> last_gain_;
- std::array<float, kFftLengthBy2Plus1> last_masker_;
- std::array<float, kFftLengthBy2Plus1> gain_increase_;
std::array<float, kFftLengthBy2Plus1> last_nearend_;
std::array<float, kFftLengthBy2Plus1> last_echo_;
- std::array<float, kFftLengthBy2Plus1> enr_transparent_;
- std::array<float, kFftLengthBy2Plus1> enr_suppress_;
- std::array<float, kFftLengthBy2Plus1> emr_transparent_;
LowNoiseRenderDetector low_render_detector_;
bool initial_state_ = true;
int initial_state_change_counter_ = 0;
- CoherenceGain coherence_gain_;
- const bool enable_transparency_improvements_;
const bool enable_new_suppression_;
aec3::MovingAverage moving_average_;
+ const GainParameters nearend_params_;
+ const GainParameters normal_params_;
+ DominantNearendDetector dominant_nearend_detector_;
RTC_DISALLOW_COPY_AND_ASSIGN(SuppressionGain);
};
diff --git a/modules/audio_processing/aec3/suppression_gain_unittest.cc b/modules/audio_processing/aec3/suppression_gain_unittest.cc
index 2eeb68b..ef31371 100644
--- a/modules/audio_processing/aec3/suppression_gain_unittest.cc
+++ b/modules/audio_processing/aec3/suppression_gain_unittest.cc
@@ -18,7 +18,6 @@
#include "rtc_base/checks.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace aec3 {
@@ -29,17 +28,16 @@
TEST(SuppressionGain, NullOutputGains) {
std::array<float, kFftLengthBy2Plus1> E2;
std::array<float, kFftLengthBy2Plus1> R2;
+ std::array<float, kFftLengthBy2Plus1> S2;
std::array<float, kFftLengthBy2Plus1> N2;
FftData E;
- FftData X;
FftData Y;
E2.fill(0.f);
R2.fill(0.f);
+ S2.fill(0.1f);
N2.fill(0.f);
E.re.fill(0.f);
E.im.fill(0.f);
- X.re.fill(0.f);
- X.im.fill(0.f);
Y.re.fill(0.f);
Y.im.fill(0.f);
@@ -47,7 +45,7 @@
AecState aec_state(EchoCanceller3Config{});
EXPECT_DEATH(
SuppressionGain(EchoCanceller3Config{}, DetectOptimization(), 16000)
- .GetGain(E2, R2, N2, E, X, Y,
+ .GetGain(E2, S2, R2, N2, E, Y,
RenderSignalAnalyzer((EchoCanceller3Config{})), aec_state,
std::vector<std::vector<float>>(
3, std::vector<float>(kBlockSize, 0.f)),
@@ -64,6 +62,7 @@
RenderSignalAnalyzer analyzer(EchoCanceller3Config{});
float high_bands_gain;
std::array<float, kFftLengthBy2Plus1> E2;
+ std::array<float, kFftLengthBy2Plus1> S2;
std::array<float, kFftLengthBy2Plus1> Y2;
std::array<float, kFftLengthBy2Plus1> R2;
std::array<float, kFftLengthBy2Plus1> N2;
@@ -71,7 +70,6 @@
SubtractorOutput output;
std::array<float, kBlockSize> y;
FftData E;
- FftData X;
FftData Y;
std::vector<std::vector<float>> x(1, std::vector<float>(kBlockSize, 0.f));
EchoCanceller3Config config;
@@ -86,13 +84,12 @@
E2.fill(10.f);
Y2.fill(10.f);
R2.fill(0.1f);
+ S2.fill(0.1f);
N2.fill(100.f);
output.Reset();
y.fill(0.f);
E.re.fill(sqrtf(E2[0]));
E.im.fill(0.f);
- X.re.fill(sqrtf(R2[0]));
- X.im.fill(0.f);
Y.re.fill(sqrtf(Y2[0]));
Y.im.fill(0.f);
@@ -109,7 +106,7 @@
subtractor.FilterImpulseResponse(),
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
y);
- suppression_gain.GetGain(E2, R2, N2, E, X, Y, analyzer, aec_state, x,
+ suppression_gain.GetGain(E2, S2, R2, N2, E, Y, analyzer, aec_state, x,
&high_bands_gain, &g);
}
std::for_each(g.begin(), g.end(),
@@ -119,9 +116,9 @@
E2.fill(100.f);
Y2.fill(100.f);
R2.fill(0.1f);
+ S2.fill(0.1f);
N2.fill(0.f);
E.re.fill(sqrtf(E2[0]));
- X.re.fill(sqrtf(R2[0]));
Y.re.fill(sqrtf(Y2[0]));
for (int k = 0; k < 100; ++k) {
@@ -129,7 +126,7 @@
subtractor.FilterImpulseResponse(),
*render_delay_buffer->GetRenderBuffer(), E2, Y2, output,
y);
- suppression_gain.GetGain(E2, R2, N2, E, X, Y, analyzer, aec_state, x,
+ suppression_gain.GetGain(E2, S2, R2, N2, E, Y, analyzer, aec_state, x,
&high_bands_gain, &g);
}
std::for_each(g.begin(), g.end(),
@@ -139,10 +136,9 @@
E2.fill(1000000000.f);
R2.fill(10000000000000.f);
E.re.fill(sqrtf(E2[0]));
- X.re.fill(sqrtf(R2[0]));
for (int k = 0; k < 10; ++k) {
- suppression_gain.GetGain(E2, R2, N2, E, X, Y, analyzer, aec_state, x,
+ suppression_gain.GetGain(E2, S2, R2, N2, E, Y, analyzer, aec_state, x,
&high_bands_gain, &g);
}
std::for_each(g.begin(), g.end(),
diff --git a/modules/audio_processing/aec3/vector_math.h b/modules/audio_processing/aec3/vector_math.h
index 0672b51..255331b 100644
--- a/modules/audio_processing/aec3/vector_math.h
+++ b/modules/audio_processing/aec3/vector_math.h
@@ -11,7 +11,9 @@
#ifndef MODULES_AUDIO_PROCESSING_AEC3_VECTOR_MATH_H_
#define MODULES_AUDIO_PROCESSING_AEC3_VECTOR_MATH_H_
-#include "typedefs.h" // NOLINT(build/include)
+// Defines WEBRTC_ARCH_X86_FAMILY, used below.
+#include "rtc_base/system/arch.h"
+
#if defined(WEBRTC_HAS_NEON)
#include <arm_neon.h>
#endif
diff --git a/modules/audio_processing/aec3/vector_math_unittest.cc b/modules/audio_processing/aec3/vector_math_unittest.cc
index 6bf60ec..fdab2e5 100644
--- a/modules/audio_processing/aec3/vector_math_unittest.cc
+++ b/modules/audio_processing/aec3/vector_math_unittest.cc
@@ -12,9 +12,9 @@
#include <math.h>
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.cc b/modules/audio_processing/aec_dump/aec_dump_impl.cc
index 1b8df40..9e07367 100644
--- a/modules/audio_processing/aec_dump/aec_dump_impl.cc
+++ b/modules/audio_processing/aec_dump/aec_dump_impl.cc
@@ -45,8 +45,6 @@
pb_cfg->set_transient_suppression_enabled(
config.transient_suppression_enabled);
- pb_cfg->set_intelligibility_enhancer_enabled(
- config.intelligibility_enhancer_enabled);
pb_cfg->set_pre_amplifier_enabled(config.pre_amplifier_enabled);
pb_cfg->set_pre_amplifier_fixed_gain_factor(
@@ -74,7 +72,8 @@
thread_sync_event.Wait(rtc::Event::kForever);
}
-void AecDumpImpl::WriteInitMessage(const ProcessingConfig& api_format) {
+void AecDumpImpl::WriteInitMessage(const ProcessingConfig& api_format,
+ int64_t time_now_ms) {
auto task = CreateWriteToFileTask();
auto* event = task->GetEvent();
event->set_type(audioproc::Event::INIT);
@@ -95,6 +94,7 @@
static_cast<int32_t>(api_format.reverse_input_stream().num_channels()));
msg->set_num_reverse_output_channels(
api_format.reverse_output_stream().num_channels());
+ msg->set_timestamp_ms(time_now_ms);
worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(std::move(task)));
}
diff --git a/modules/audio_processing/aec_dump/aec_dump_impl.h b/modules/audio_processing/aec_dump/aec_dump_impl.h
index 1ad4fc8..a5416a0 100644
--- a/modules/audio_processing/aec_dump/aec_dump_impl.h
+++ b/modules/audio_processing/aec_dump/aec_dump_impl.h
@@ -52,8 +52,8 @@
~AecDumpImpl() override;
- void WriteInitMessage(const ProcessingConfig& api_format) override;
-
+ void WriteInitMessage(const ProcessingConfig& api_format,
+ int64_t time_now_ms) override;
void AddCaptureStreamInput(const AudioFrameView<const float>& src) override;
void AddCaptureStreamOutput(const AudioFrameView<const float>& src) override;
void AddCaptureStreamInput(const AudioFrame& frame) override;
diff --git a/modules/audio_processing/aec_dump/aec_dump_integration_test.cc b/modules/audio_processing/aec_dump/aec_dump_integration_test.cc
index 53e731a..b6d8756 100644
--- a/modules/audio_processing/aec_dump/aec_dump_integration_test.cc
+++ b/modules/audio_processing/aec_dump/aec_dump_integration_test.cc
@@ -33,7 +33,7 @@
auto mock_aec_dump =
absl::make_unique<testing::StrictMock<webrtc::test::MockAecDump>>();
EXPECT_CALL(*mock_aec_dump.get(), WriteConfig(_)).Times(AtLeast(1));
- EXPECT_CALL(*mock_aec_dump.get(), WriteInitMessage(_)).Times(AtLeast(1));
+ EXPECT_CALL(*mock_aec_dump.get(), WriteInitMessage(_, _)).Times(AtLeast(1));
return std::unique_ptr<webrtc::test::MockAecDump>(std::move(mock_aec_dump));
}
diff --git a/modules/audio_processing/aec_dump/aec_dump_unittest.cc b/modules/audio_processing/aec_dump/aec_dump_unittest.cc
index dea149d..75ed529 100644
--- a/modules/audio_processing/aec_dump/aec_dump_unittest.cc
+++ b/modules/audio_processing/aec_dump/aec_dump_unittest.cc
@@ -40,7 +40,8 @@
aec_dump->WriteConfig(apm_config);
webrtc::ProcessingConfig api_format;
- aec_dump->WriteInitMessage(api_format);
+ constexpr int64_t kTimeNowMs = 123456789ll;
+ aec_dump->WriteInitMessage(api_format, kTimeNowMs);
}
// Remove file after the AecDump d-tor has finished.
ASSERT_EQ(0, remove(filename.c_str()));
diff --git a/modules/audio_processing/aec_dump/mock_aec_dump.h b/modules/audio_processing/aec_dump/mock_aec_dump.h
index 95f912f..c01de51 100644
--- a/modules/audio_processing/aec_dump/mock_aec_dump.h
+++ b/modules/audio_processing/aec_dump/mock_aec_dump.h
@@ -25,7 +25,8 @@
MockAecDump();
virtual ~MockAecDump();
- MOCK_METHOD1(WriteInitMessage, void(const ProcessingConfig& api_format));
+ MOCK_METHOD2(WriteInitMessage,
+ void(const ProcessingConfig& api_format, int64_t time_now_ms));
MOCK_METHOD1(AddCaptureStreamInput,
void(const AudioFrameView<const float>& src));
diff --git a/modules/audio_processing/aecm/BUILD.gn b/modules/audio_processing/aecm/BUILD.gn
index 54d839e..8250173 100644
--- a/modules/audio_processing/aecm/BUILD.gn
+++ b/modules/audio_processing/aecm/BUILD.gn
@@ -17,7 +17,6 @@
"echo_control_mobile.h",
]
deps = [
- "../../..:typedefs",
"../../../common_audio:common_audio_c",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
@@ -31,9 +30,7 @@
sources += [ "aecm_core_neon.cc" ]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags += [ "-mfpu=neon" ]
}
diff --git a/modules/audio_processing/aecm/aecm_core.cc b/modules/audio_processing/aecm/aecm_core.cc
index 21a2ba1..0e56b50 100644
--- a/modules/audio_processing/aecm/aecm_core.cc
+++ b/modules/audio_processing/aecm/aecm_core.cc
@@ -25,7 +25,6 @@
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
-#include "typedefs.h" // NOLINT(build/include)
#ifdef AEC_DEBUG
FILE* dfile;
diff --git a/modules/audio_processing/aecm/aecm_core.h b/modules/audio_processing/aecm/aecm_core.h
index 3da3bca..1681d2a 100644
--- a/modules/audio_processing/aecm/aecm_core.h
+++ b/modules/audio_processing/aecm/aecm_core.h
@@ -18,7 +18,6 @@
#include "common_audio/signal_processing/include/signal_processing_library.h"
}
#include "modules/audio_processing/aecm/aecm_defines.h"
-#include "typedefs.h" // NOLINT(build/include)
#ifdef _MSC_VER // visual c++
#define ALIGN8_BEG __declspec(align(8))
diff --git a/modules/audio_processing/aecm/aecm_core_c.cc b/modules/audio_processing/aecm/aecm_core_c.cc
index b640f1a..905274f 100644
--- a/modules/audio_processing/aecm/aecm_core_c.cc
+++ b/modules/audio_processing/aecm/aecm_core_c.cc
@@ -26,7 +26,6 @@
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/sanitizer.h"
-#include "typedefs.h" // NOLINT(build/include)
// Square root of Hanning window in Q14.
static const ALIGN8_BEG int16_t WebRtcAecm_kSqrtHanning[] ALIGN8_END = {
diff --git a/modules/audio_processing/aecm/echo_control_mobile.h b/modules/audio_processing/aecm/echo_control_mobile.h
index 576cf19..cea13b8 100644
--- a/modules/audio_processing/aecm/echo_control_mobile.h
+++ b/modules/audio_processing/aecm/echo_control_mobile.h
@@ -11,9 +11,8 @@
#ifndef MODULES_AUDIO_PROCESSING_AECM_ECHO_CONTROL_MOBILE_H_
#define MODULES_AUDIO_PROCESSING_AECM_ECHO_CONTROL_MOBILE_H_
-#include <stdlib.h>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stddef.h>
+#include <stdint.h>
enum { AecmFalse = 0, AecmTrue };
diff --git a/modules/audio_processing/agc/BUILD.gn b/modules/audio_processing/agc/BUILD.gn
index fe2f107..65653a0 100644
--- a/modules/audio_processing/agc/BUILD.gn
+++ b/modules/audio_processing/agc/BUILD.gn
@@ -19,9 +19,9 @@
":level_estimation",
"..:apm_logging",
"..:gain_control_interface",
- "../../..:typedefs",
"../../..:webrtc_common",
"../../../rtc_base:checks",
+ "../../../rtc_base:gtest_prod",
"../../../rtc_base:logging",
"../../../rtc_base:macromagic",
"../../../rtc_base:safe_minmax",
@@ -41,7 +41,6 @@
"utility.h",
]
deps = [
- "../../..:typedefs",
"../../..:webrtc_common",
"../../../rtc_base:checks",
"../../../rtc_base:macromagic",
@@ -66,11 +65,10 @@
]
deps = [
- "../../..:typedefs",
"../../..:webrtc_common",
"../../../common_audio",
"../../../common_audio:common_audio_c",
- "../../../common_audio:fft4g",
+ "../../../common_audio/third_party/fft4g",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../system_wrappers:cpu_features_api",
@@ -78,9 +76,7 @@
if (rtc_build_with_neon) {
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags = [ "-mfpu=neon" ]
}
diff --git a/modules/audio_processing/agc/agc.h b/modules/audio_processing/agc/agc.h
index 98bbf1f..5d34c21 100644
--- a/modules/audio_processing/agc/agc.h
+++ b/modules/audio_processing/agc/agc.h
@@ -14,7 +14,6 @@
#include <memory>
#include "modules/audio_processing/vad/voice_activity_detector.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/agc/agc_manager_direct.cc b/modules/audio_processing/agc/agc_manager_direct.cc
index 132cf82..dc6d451 100644
--- a/modules/audio_processing/agc/agc_manager_direct.cc
+++ b/modules/audio_processing/agc/agc_manager_direct.cc
@@ -84,6 +84,31 @@
return new_level;
}
+int InitializeGainControl(GainControl* gain_control,
+ bool disable_digital_adaptive) {
+ if (gain_control->set_mode(GainControl::kFixedDigital) != 0) {
+ RTC_LOG(LS_ERROR) << "set_mode(GainControl::kFixedDigital) failed.";
+ return -1;
+ }
+ const int target_level_dbfs = disable_digital_adaptive ? 0 : 2;
+ if (gain_control->set_target_level_dbfs(target_level_dbfs) != 0) {
+ RTC_LOG(LS_ERROR) << "set_target_level_dbfs() failed.";
+ return -1;
+ }
+ const int compression_gain_db =
+ disable_digital_adaptive ? 0 : kDefaultCompressionGain;
+ if (gain_control->set_compression_gain_db(compression_gain_db) != 0) {
+ RTC_LOG(LS_ERROR) << "set_compression_gain_db() failed.";
+ return -1;
+ }
+ const bool enable_limiter = !disable_digital_adaptive;
+ if (gain_control->enable_limiter(enable_limiter) != 0) {
+ RTC_LOG(LS_ERROR) << "enable_limiter() failed.";
+ return -1;
+ }
+ return 0;
+}
+
} // namespace
// Facility for dumping debug audio files. All methods are no-ops in the
@@ -114,14 +139,16 @@
int startup_min_level,
int clipped_level_min,
bool use_agc2_level_estimation,
- bool use_agc2_digital_adaptive)
- : AgcManagerDirect(new Agc(),
+ bool disable_digital_adaptive)
+ : AgcManagerDirect(use_agc2_level_estimation ? nullptr : new Agc(),
gctrl,
volume_callbacks,
startup_min_level,
clipped_level_min,
use_agc2_level_estimation,
- use_agc2_digital_adaptive) {}
+ disable_digital_adaptive) {
+ RTC_DCHECK(agc_);
+}
AgcManagerDirect::AgcManagerDirect(Agc* agc,
GainControl* gctrl,
@@ -134,7 +161,9 @@
startup_min_level,
clipped_level_min,
false,
- false) {}
+ false) {
+ RTC_DCHECK(agc_);
+}
AgcManagerDirect::AgcManagerDirect(Agc* agc,
GainControl* gctrl,
@@ -142,7 +171,7 @@
int startup_min_level,
int clipped_level_min,
bool use_agc2_level_estimation,
- bool use_agc2_digital_adaptive)
+ bool disable_digital_adaptive)
: data_dumper_(new ApmDataDumper(instance_counter_)),
agc_(agc),
gctrl_(gctrl),
@@ -158,7 +187,7 @@
check_volume_on_next_process_(true), // Check at startup.
startup_(true),
use_agc2_level_estimation_(use_agc2_level_estimation),
- use_agc2_digital_adaptive_(use_agc2_digital_adaptive),
+ disable_digital_adaptive_(disable_digital_adaptive),
startup_min_level_(ClampLevel(startup_min_level)),
clipped_level_min_(clipped_level_min),
file_preproc_(new DebugFile("agc_preproc.pcm")),
@@ -170,9 +199,6 @@
} else {
RTC_DCHECK(agc);
}
- if (use_agc2_digital_adaptive_) {
- RTC_NOTREACHED() << "Agc2 digital adaptive not implemented.";
- }
}
AgcManagerDirect::~AgcManagerDirect() {}
@@ -180,8 +206,8 @@
int AgcManagerDirect::Initialize() {
max_level_ = kMaxMicLevel;
max_compression_gain_ = kMaxCompressionGain;
- target_compression_ = kDefaultCompressionGain;
- compression_ = target_compression_;
+ target_compression_ = disable_digital_adaptive_ ? 0 : kDefaultCompressionGain;
+ compression_ = disable_digital_adaptive_ ? 0 : target_compression_;
compression_accumulator_ = compression_;
capture_muted_ = false;
check_volume_on_next_process_ = true;
@@ -190,24 +216,7 @@
data_dumper_->InitiateNewSetOfRecordings();
- if (gctrl_->set_mode(GainControl::kFixedDigital) != 0) {
- RTC_LOG(LS_ERROR) << "set_mode(GainControl::kFixedDigital) failed.";
- return -1;
- }
- if (gctrl_->set_target_level_dbfs(2) != 0) {
- RTC_LOG(LS_ERROR) << "set_target_level_dbfs(2) failed.";
- return -1;
- }
- if (gctrl_->set_compression_gain_db(kDefaultCompressionGain) != 0) {
- RTC_LOG(LS_ERROR)
- << "set_compression_gain_db(kDefaultCompressionGain) failed.";
- return -1;
- }
- if (gctrl_->enable_limiter(true) != 0) {
- RTC_LOG(LS_ERROR) << "enable_limiter(true) failed.";
- return -1;
- }
- return 0;
+ return InitializeGainControl(gctrl_, disable_digital_adaptive_);
}
void AgcManagerDirect::AnalyzePreProcess(int16_t* audio,
@@ -272,7 +281,9 @@
agc_->Process(audio, length, sample_rate_hz);
UpdateGain();
- UpdateCompressor();
+ if (!disable_digital_adaptive_) {
+ UpdateCompressor();
+ }
file_postproc_->Write(audio, length);
@@ -437,10 +448,19 @@
// level_ was updated by SetLevel; log the new value.
RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.AgcSetLevel", level_, 1,
kMaxMicLevel, 50);
+ // Reset the AGC since the level has changed.
+ agc_->Reset();
}
}
void AgcManagerDirect::UpdateCompressor() {
+ calls_since_last_gain_log_++;
+ if (calls_since_last_gain_log_ == 100) {
+ calls_since_last_gain_log_ = 0;
+ RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc.DigitalGainApplied",
+ compression_, 0, kMaxCompressionGain,
+ kMaxCompressionGain + 1);
+ }
if (compression_ == target_compression_) {
return;
}
@@ -465,6 +485,9 @@
// Set the new compression gain.
if (new_compression != compression_) {
+ RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc.DigitalGainUpdated",
+ new_compression, 0, kMaxCompressionGain,
+ kMaxCompressionGain + 1);
compression_ = new_compression;
compression_accumulator_ = new_compression;
if (gctrl_->set_compression_gain_db(compression_) != 0) {
diff --git a/modules/audio_processing/agc/agc_manager_direct.h b/modules/audio_processing/agc/agc_manager_direct.h
index de3d1cb..cbfd6a1 100644
--- a/modules/audio_processing/agc/agc_manager_direct.h
+++ b/modules/audio_processing/agc/agc_manager_direct.h
@@ -16,6 +16,7 @@
#include "modules/audio_processing/agc/agc.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/constructormagic.h"
+#include "rtc_base/gtest_prod_util.h"
namespace webrtc {
@@ -50,7 +51,7 @@
int startup_min_level,
int clipped_level_min,
bool use_agc2_level_estimation,
- bool use_agc2_digital_adaptive);
+ bool disable_digital_adaptive);
~AgcManagerDirect();
@@ -71,6 +72,9 @@
private:
friend class AgcManagerDirectTest;
+ FRIEND_TEST_ALL_PREFIXES(AgcManagerDirectStandaloneTest,
+ DisableDigitalDisablesDigital);
+
// Dependency injection for testing. Don't delete |agc| as the memory is owned
// by the manager.
AgcManagerDirect(Agc* agc,
@@ -86,7 +90,7 @@
int startup_min_level,
int clipped_level_min,
bool use_agc2_level_estimation,
- bool use_agc2_digital_adaptive);
+ bool disable_digital_adaptive);
// Sets a new microphone level, after first checking that it hasn't been
// updated by the user, in which case no action is taken.
@@ -119,9 +123,10 @@
bool check_volume_on_next_process_;
bool startup_;
const bool use_agc2_level_estimation_;
- const bool use_agc2_digital_adaptive_;
+ const bool disable_digital_adaptive_;
int startup_min_level_;
const int clipped_level_min_;
+ int calls_since_last_gain_log_ = 0;
std::unique_ptr<DebugFile> file_preproc_;
std::unique_ptr<DebugFile> file_postproc_;
diff --git a/modules/audio_processing/agc/agc_manager_direct_unittest.cc b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
index 1a03402..73ea55d 100644
--- a/modules/audio_processing/agc/agc_manager_direct_unittest.cc
+++ b/modules/audio_processing/agc/agc_manager_direct_unittest.cc
@@ -17,6 +17,7 @@
#include "test/gtest.h"
using ::testing::_;
+using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SetArgPointee;
@@ -53,7 +54,7 @@
}
void FirstProcess() {
- EXPECT_CALL(*agc_, Reset());
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
EXPECT_CALL(*agc_, GetRmsErrorDb(_)).WillOnce(Return(false));
CallProcess(1);
}
@@ -366,11 +367,14 @@
// to SetMicVolume.
EXPECT_CALL(*agc_, GetRmsErrorDb(_))
.WillOnce(DoAll(SetArgPointee<0>(11), Return(true)));
+
+ // When the analog volume changes, the gain controller is reset.
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
+
// GetMicVolume returns a value outside of the quantization slack, indicating
// a manual volume change.
+ ASSERT_NE(volume_.GetMicVolume(), 154);
volume_.SetMicVolume(154);
- // SetMicVolume should not be called.
- EXPECT_CALL(*agc_, Reset()).Times(1);
CallProcess(1);
EXPECT_EQ(154, volume_.GetMicVolume());
@@ -378,7 +382,7 @@
EXPECT_CALL(*agc_, GetRmsErrorDb(_))
.WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
volume_.SetMicVolume(100);
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(100, volume_.GetMicVolume());
@@ -407,7 +411,7 @@
EXPECT_CALL(*agc_, GetRmsErrorDb(_))
.WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
volume_.SetMicVolume(50);
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(50, volume_.GetMicVolume());
@@ -426,7 +430,7 @@
.WillOnce(DoAll(SetArgPointee<0>(-1), Return(true)));
// Don't set to zero, which will cause AGC to take no action.
volume_.SetMicVolume(1);
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(1, volume_.GetMicVolume());
@@ -467,7 +471,7 @@
SetVolumeAndProcess(255);
EXPECT_CALL(*agc_, AnalyzePreproc(_, _)).WillOnce(Return(0.101));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(240, volume_.GetMicVolume());
}
@@ -477,7 +481,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(240, volume_.GetMicVolume());
@@ -489,7 +493,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(225, volume_.GetMicVolume());
}
@@ -499,7 +503,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(kClippedMin, volume_.GetMicVolume());
@@ -515,7 +519,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(240, volume_.GetMicVolume());
@@ -530,7 +534,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(185, volume_.GetMicVolume());
@@ -547,7 +551,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(195, volume_.GetMicVolume());
@@ -576,14 +580,14 @@
CallPreProc(300);
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(180, volume_.GetMicVolume());
CallPreProc(300);
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(kClippedMin, volume_.GetMicVolume());
@@ -628,7 +632,7 @@
EXPECT_CALL(*agc_, AnalyzePreproc(_, _))
.WillOnce(Return(kAboveClippedThreshold));
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallPreProc(1);
EXPECT_EQ(210, volume_.GetMicVolume());
@@ -637,7 +641,7 @@
.WillOnce(DoAll(SetArgPointee<0>(14), Return(true)));
// User changed the volume.
volume_.SetMicVolume(250);
- EXPECT_CALL(*agc_, Reset()).Times(1);
+ EXPECT_CALL(*agc_, Reset()).Times(AtLeast(1));
CallProcess(1);
EXPECT_EQ(250, volume_.GetMicVolume());
@@ -679,4 +683,22 @@
EXPECT_EQ(0, volume_.GetMicVolume());
}
+TEST(AgcManagerDirectStandaloneTest, DisableDigitalDisablesDigital) {
+ auto agc = std::unique_ptr<Agc>(new testing::NiceMock<MockAgc>());
+ test::MockGainControl gctrl;
+ TestVolumeCallbacks volume;
+
+ AgcManagerDirect manager(agc.release(), &gctrl, &volume, kInitialVolume,
+ kClippedMin,
+ /* use agc2 level estimation */ false,
+ /* disable digital adaptive */ true);
+
+ EXPECT_CALL(gctrl, set_mode(GainControl::kFixedDigital));
+ EXPECT_CALL(gctrl, set_target_level_dbfs(0));
+ EXPECT_CALL(gctrl, set_compression_gain_db(0));
+ EXPECT_CALL(gctrl, enable_limiter(false));
+
+ manager.Initialize();
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/agc/legacy/analog_agc.h b/modules/audio_processing/agc/legacy/analog_agc.h
index 1fed377..619d95a 100644
--- a/modules/audio_processing/agc/legacy/analog_agc.h
+++ b/modules/audio_processing/agc/legacy/analog_agc.h
@@ -18,7 +18,6 @@
#include "modules/audio_processing/agc/legacy/digital_agc.h"
#include "modules/audio_processing/agc/legacy/gain_control.h"
-#include "typedefs.h" // NOLINT(build/include)
/* Analog Automatic Gain Control variables:
* Constant declarations (inner limits inside which no changes are done)
diff --git a/modules/audio_processing/agc/legacy/digital_agc.c b/modules/audio_processing/agc/legacy/digital_agc.c
index 7801196..d1c30bd 100644
--- a/modules/audio_processing/agc/legacy/digital_agc.c
+++ b/modules/audio_processing/agc/legacy/digital_agc.c
@@ -583,6 +583,7 @@
int16_t buf2[4];
int16_t HPstate;
int16_t zeros, dB;
+ int64_t tmp64;
// process in 10 sub frames of 1 ms (to save on memory)
nrg = 0;
@@ -688,17 +689,17 @@
tmp32 = WebRtcSpl_DivW32W16(tmp32, state->stdLongTerm);
tmpU16 = (13 << 12);
tmp32b = WEBRTC_SPL_MUL_16_U16(state->logRatio, tmpU16);
- tmp32 += tmp32b >> 10;
-
- state->logRatio = (int16_t)(tmp32 >> 6);
+ tmp64 = tmp32;
+ tmp64 += tmp32b >> 10;
+ tmp64 >>= 6;
// limit
- if (state->logRatio > 2048) {
- state->logRatio = 2048;
+ if (tmp64 > 2048) {
+ tmp64 = 2048;
+ } else if (tmp64 < -2048) {
+ tmp64 = -2048;
}
- if (state->logRatio < -2048) {
- state->logRatio = -2048;
- }
+ state->logRatio = (int16_t)tmp64;
return state->logRatio; // Q10
}
diff --git a/modules/audio_processing/agc/legacy/digital_agc.h b/modules/audio_processing/agc/legacy/digital_agc.h
index af6cf48..f086294 100644
--- a/modules/audio_processing/agc/legacy/digital_agc.h
+++ b/modules/audio_processing/agc/legacy/digital_agc.h
@@ -15,7 +15,6 @@
#include <stdio.h>
#endif
#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "typedefs.h" // NOLINT(build/include)
// the 32 most significant bits of A(19) * B(26) >> 13
#define AGC_MUL32(A, B) (((B) >> 13) * (A) + (((0x00001FFF & (B)) * (A)) >> 13))
diff --git a/modules/audio_processing/agc/legacy/gain_control.h b/modules/audio_processing/agc/legacy/gain_control.h
index 05b7ff6..a0ac96d 100644
--- a/modules/audio_processing/agc/legacy/gain_control.h
+++ b/modules/audio_processing/agc/legacy/gain_control.h
@@ -11,8 +11,6 @@
#ifndef MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_
#define MODULES_AUDIO_PROCESSING_AGC_LEGACY_GAIN_CONTROL_H_
-#include "typedefs.h" // NOLINT(build/include)
-
// Errors
#define AGC_UNSPECIFIED_ERROR 18000
#define AGC_UNSUPPORTED_FUNCTION_ERROR 18001
diff --git a/modules/audio_processing/agc/loudness_histogram.h b/modules/audio_processing/agc/loudness_histogram.h
index ab45276..d8ad751 100644
--- a/modules/audio_processing/agc/loudness_histogram.h
+++ b/modules/audio_processing/agc/loudness_histogram.h
@@ -15,8 +15,6 @@
#include <memory>
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
// This class implements the histogram of loudness with circular buffers so that
diff --git a/modules/audio_processing/agc/mock_agc.h b/modules/audio_processing/agc/mock_agc.h
index ff1e9fd..4297e2a 100644
--- a/modules/audio_processing/agc/mock_agc.h
+++ b/modules/audio_processing/agc/mock_agc.h
@@ -19,6 +19,7 @@
class MockAgc : public Agc {
public:
+ virtual ~MockAgc() {}
MOCK_METHOD2(AnalyzePreproc, float(const int16_t* audio, size_t length));
MOCK_METHOD3(Process,
void(const int16_t* audio, size_t length, int sample_rate_hz));
diff --git a/modules/audio_processing/agc2/BUILD.gn b/modules/audio_processing/agc2/BUILD.gn
index dcdc7fa..45ef968 100644
--- a/modules/audio_processing/agc2/BUILD.gn
+++ b/modules/audio_processing/agc2/BUILD.gn
@@ -29,7 +29,6 @@
":rnn_vad_with_level",
"..:apm_logging",
"..:audio_frame_view",
- "../../..:typedefs",
"../../../api:array_view",
"../../../common_audio",
"../../../rtc_base:checks",
@@ -66,6 +65,7 @@
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:safe_minmax",
+ "../../../system_wrappers:metrics_api",
]
}
@@ -165,7 +165,7 @@
"../../../api:array_view",
"../../../common_audio",
"../../../rtc_base:checks",
- "rnn_vad:lib",
+ "rnn_vad",
]
}
@@ -232,6 +232,7 @@
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../../rtc_base:rtc_base_tests_utils",
+ "../../../system_wrappers:metrics_default",
"//third_party/abseil-cpp/absl/memory",
]
}
diff --git a/modules/audio_processing/agc2/adaptive_agc.cc b/modules/audio_processing/agc2/adaptive_agc.cc
index 7b24244..805be0c 100644
--- a/modules/audio_processing/agc2/adaptive_agc.cc
+++ b/modules/audio_processing/agc2/adaptive_agc.cc
@@ -30,14 +30,6 @@
AdaptiveAgc::~AdaptiveAgc() = default;
void AdaptiveAgc::Process(AudioFrameView<float> float_frame) {
- // TODO(webrtc:7494): Remove this loop. Remove the vectors from
- // VadWithData after we move to a VAD that outputs an estimate every
- // kFrameDurationMs ms.
- //
- // Some VADs are 'bursty'. They return several estimates for some
- // frames, and no estimates for other frames. We want to feed all to
- // the level estimator, but only care about the last level it
- // produces.
const VadWithLevel::LevelAndProbability vad_result =
vad_.AnalyzeFrame(float_frame);
apm_data_dumper_->DumpRaw("agc2_vad_probability",
@@ -58,4 +50,8 @@
float_frame);
}
+void AdaptiveAgc::Reset() {
+ speech_level_estimator_.Reset();
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/agc2/adaptive_agc.h b/modules/audio_processing/agc2/adaptive_agc.h
index dabe783..8f5efec 100644
--- a/modules/audio_processing/agc2/adaptive_agc.h
+++ b/modules/audio_processing/agc2/adaptive_agc.h
@@ -25,9 +25,11 @@
class AdaptiveAgc {
public:
explicit AdaptiveAgc(ApmDataDumper* apm_data_dumper);
- void Process(AudioFrameView<float> float_frame);
~AdaptiveAgc();
+ void Process(AudioFrameView<float> float_frame);
+ void Reset();
+
private:
AdaptiveModeLevelEstimator speech_level_estimator_;
VadWithLevel vad_;
diff --git a/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc b/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc
index ca6ec5d..f5342df 100644
--- a/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc
+++ b/modules/audio_processing/agc2/adaptive_digital_gain_applier.cc
@@ -16,6 +16,7 @@
#include "modules/audio_processing/agc2/agc2_common.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/numerics/safe_minmax.h"
+#include "system_wrappers/include/metrics.h"
namespace webrtc {
namespace {
@@ -76,6 +77,15 @@
float input_noise_level_dbfs,
const VadWithLevel::LevelAndProbability vad_result,
AudioFrameView<float> float_frame) {
+ calls_since_last_gain_log_++;
+ if (calls_since_last_gain_log_ == 100) {
+ calls_since_last_gain_log_ = 0;
+ RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc2.DigitalGainApplied",
+ last_gain_db_, 0, kMaxGainDb, kMaxGainDb + 1);
+ RTC_HISTOGRAM_COUNTS_LINEAR("WebRTC.Audio.Agc2.EstimatedNoiseLevel",
+ input_noise_level_dbfs, 0, 100, 101);
+ }
+
input_level_dbfs = std::min(input_level_dbfs, 0.f);
RTC_DCHECK_GE(input_level_dbfs, -150.f);
diff --git a/modules/audio_processing/agc2/adaptive_digital_gain_applier.h b/modules/audio_processing/agc2/adaptive_digital_gain_applier.h
index 31f87f1..a3a1ff5 100644
--- a/modules/audio_processing/agc2/adaptive_digital_gain_applier.h
+++ b/modules/audio_processing/agc2/adaptive_digital_gain_applier.h
@@ -32,6 +32,7 @@
private:
float last_gain_db_ = kInitialAdaptiveDigitalGainDb;
GainApplier gain_applier_;
+ int calls_since_last_gain_log_ = 0;
// For some combinations of noise and speech probability, increasing
// the level is not allowed. Since we may get VAD results in bursts,
diff --git a/modules/audio_processing/agc2/fixed_digital_level_estimator.cc b/modules/audio_processing/agc2/fixed_digital_level_estimator.cc
index 9a1fd28..39cc764 100644
--- a/modules/audio_processing/agc2/fixed_digital_level_estimator.cc
+++ b/modules/audio_processing/agc2/fixed_digital_level_estimator.cc
@@ -17,11 +17,17 @@
#include "rtc_base/checks.h"
namespace webrtc {
+namespace {
+
+constexpr float kInitialFilterStateLevel = 0.f;
+
+} // namespace
FixedDigitalLevelEstimator::FixedDigitalLevelEstimator(
size_t sample_rate_hz,
ApmDataDumper* apm_data_dumper)
- : apm_data_dumper_(apm_data_dumper) {
+ : apm_data_dumper_(apm_data_dumper),
+ filter_state_level_(kInitialFilterStateLevel) {
SetSampleRate(sample_rate_hz);
CheckParameterCombination();
RTC_DCHECK(apm_data_dumper_);
@@ -97,4 +103,9 @@
rtc::CheckedDivExact(samples_in_frame_, kSubFramesInFrame);
CheckParameterCombination();
}
+
+void FixedDigitalLevelEstimator::Reset() {
+ filter_state_level_ = kInitialFilterStateLevel;
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/agc2/fixed_digital_level_estimator.h b/modules/audio_processing/agc2/fixed_digital_level_estimator.h
index b0e7a6d..4907ec7 100644
--- a/modules/audio_processing/agc2/fixed_digital_level_estimator.h
+++ b/modules/audio_processing/agc2/fixed_digital_level_estimator.h
@@ -45,11 +45,14 @@
// value passed to the constructor. The class is not thread safe.
void SetSampleRate(size_t sample_rate_hz);
+ // Resets the level estimator internal state.
+ void Reset();
+
private:
void CheckParameterCombination();
ApmDataDumper* const apm_data_dumper_ = nullptr;
- float filter_state_level_ = 0.f;
+ float filter_state_level_;
size_t samples_in_frame_;
size_t samples_in_sub_frame_;
diff --git a/modules/audio_processing/agc2/fixed_gain_controller.cc b/modules/audio_processing/agc2/fixed_gain_controller.cc
index e59ae34..d49d181 100644
--- a/modules/audio_processing/agc2/fixed_gain_controller.cc
+++ b/modules/audio_processing/agc2/fixed_gain_controller.cc
@@ -34,8 +34,17 @@
} // namespace
FixedGainController::FixedGainController(ApmDataDumper* apm_data_dumper)
+ : FixedGainController(apm_data_dumper, "Agc2") {}
+
+FixedGainController::FixedGainController(ApmDataDumper* apm_data_dumper,
+ std::string histogram_name_prefix)
: apm_data_dumper_(apm_data_dumper),
- gain_curve_applier_(48000, apm_data_dumper_) {}
+ gain_curve_applier_(48000, apm_data_dumper_, histogram_name_prefix) {
+ // Do update histograms.xml when adding name prefixes.
+ RTC_DCHECK(histogram_name_prefix == "" || histogram_name_prefix == "Test" ||
+ histogram_name_prefix == "AudioMixer" ||
+ histogram_name_prefix == "Agc2");
+}
void FixedGainController::SetGain(float gain_to_apply_db) {
// Changes in gain_to_apply_ cause discontinuities. We assume
@@ -45,9 +54,15 @@
// The gain
RTC_DCHECK_LE(-50.f, gain_to_apply_db);
RTC_DCHECK_LE(gain_to_apply_db, 50.f);
+ const float previous_applied_gained = gain_to_apply_;
gain_to_apply_ = DbToRatio(gain_to_apply_db);
RTC_DCHECK_LT(0.f, gain_to_apply_);
RTC_DLOG(LS_INFO) << "Gain to apply: " << gain_to_apply_db << " db.";
+ // Reset the gain curve applier to quickly react on abrupt level changes
+ // caused by large changes of the applied gain.
+ if (previous_applied_gained != gain_to_apply_) {
+ gain_curve_applier_.Reset();
+ }
}
void FixedGainController::SetSampleRate(size_t sample_rate_hz) {
diff --git a/modules/audio_processing/agc2/fixed_gain_controller.h b/modules/audio_processing/agc2/fixed_gain_controller.h
index 2b92cfc..a41a13f 100644
--- a/modules/audio_processing/agc2/fixed_gain_controller.h
+++ b/modules/audio_processing/agc2/fixed_gain_controller.h
@@ -20,6 +20,8 @@
class FixedGainController {
public:
explicit FixedGainController(ApmDataDumper* apm_data_dumper);
+ FixedGainController(ApmDataDumper* apm_data_dumper,
+ std::string histogram_name_prefix);
void Process(AudioFrameView<float> signal);
diff --git a/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc b/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc
index 72bb409..bd7c356 100644
--- a/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc
+++ b/modules/audio_processing/agc2/fixed_gain_controller_unittest.cc
@@ -16,6 +16,7 @@
#include "modules/audio_processing/agc2/vector_float_frame.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/gunit.h"
+#include "system_wrappers/include/metrics_default.h"
namespace webrtc {
namespace {
@@ -45,24 +46,38 @@
vectors_with_float_frame_last.float_frame_view().channel(0);
return channel[channel.size() - 1];
}
-ApmDataDumper test_data_dumper(0);
+
+std::unique_ptr<ApmDataDumper> GetApmDataDumper() {
+ return absl::make_unique<ApmDataDumper>(0);
+}
std::unique_ptr<FixedGainController> CreateFixedGainController(
float gain_to_apply,
- size_t rate) {
+ size_t rate,
+ std::string histogram_name_prefix,
+ ApmDataDumper* test_data_dumper) {
std::unique_ptr<FixedGainController> fgc =
- absl::make_unique<FixedGainController>(&test_data_dumper);
+ absl::make_unique<FixedGainController>(test_data_dumper,
+ histogram_name_prefix);
fgc->SetGain(gain_to_apply);
fgc->SetSampleRate(rate);
return fgc;
}
+std::unique_ptr<FixedGainController> CreateFixedGainController(
+ float gain_to_apply,
+ size_t rate,
+ ApmDataDumper* test_data_dumper) {
+ return CreateFixedGainController(gain_to_apply, rate, "", test_data_dumper);
+}
+
} // namespace
TEST(AutomaticGainController2FixedDigital, CreateUse) {
const int kSampleRate = 44000;
- std::unique_ptr<FixedGainController> fixed_gc =
- CreateFixedGainController(kGainToApplyDb, kSampleRate);
+ auto test_data_dumper = GetApmDataDumper();
+ std::unique_ptr<FixedGainController> fixed_gc = CreateFixedGainController(
+ kGainToApplyDb, kSampleRate, test_data_dumper.get());
VectorFloatFrame vectors_with_float_frame(
1, rtc::CheckedDivExact(kSampleRate, 100), kInputLevelLinear);
auto float_frame = vectors_with_float_frame.float_frame_view();
@@ -76,13 +91,15 @@
const size_t kNumFrames = 5;
const size_t kSampleRate = 42000;
+ auto test_data_dumper = GetApmDataDumper();
+
const auto gains_no_saturation =
test::LinSpace(0.1, test::kLimiterMaxInputLevelDbFs - 0.01, 10);
for (const auto gain_db : gains_no_saturation) {
// Since |test::kLimiterMaxInputLevelDbFs| > |gain_db|, the
// limiter will not saturate the signal.
std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
- CreateFixedGainController(gain_db, kSampleRate);
+ CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
// Saturation not expected.
SCOPED_TRACE(std::to_string(gain_db));
@@ -98,7 +115,7 @@
// Since |test::kLimiterMaxInputLevelDbFs| < |gain|, the limiter
// will saturate the signal.
std::unique_ptr<FixedGainController> fixed_gc_saturation =
- CreateFixedGainController(gain_db, kSampleRate);
+ CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
// Saturation expected.
SCOPED_TRACE(std::to_string(gain_db));
@@ -115,13 +132,15 @@
const size_t kNumFrames = 5;
const size_t kSampleRate = 8000;
+ auto test_data_dumper = GetApmDataDumper();
+
const auto gains_no_saturation =
test::LinSpace(0.1, test::kLimiterMaxInputLevelDbFs - 0.01, 10);
for (const auto gain_db : gains_no_saturation) {
// Since |gain| > |test::kLimiterMaxInputLevelDbFs|, the limiter will
// not saturate the signal.
std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
- CreateFixedGainController(gain_db, kSampleRate);
+ CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
// Saturation not expected.
SCOPED_TRACE(std::to_string(gain_db));
@@ -137,7 +156,7 @@
// Singe |gain| < |test::kLimiterMaxInputLevelDbFs|, the limiter will
// saturate the signal.
std::unique_ptr<FixedGainController> fixed_gc_saturation =
- CreateFixedGainController(gain_db, kSampleRate);
+ CreateFixedGainController(gain_db, kSampleRate, test_data_dumper.get());
// Saturation expected.
SCOPED_TRACE(std::to_string(gain_db));
@@ -155,8 +174,10 @@
constexpr float kGainDbNoChange = 0.f;
constexpr float kGainDbFactor10 = 20.f;
+ auto test_data_dumper = GetApmDataDumper();
std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
- CreateFixedGainController(kGainDbNoChange, kSampleRate);
+ CreateFixedGainController(kGainDbNoChange, kSampleRate,
+ test_data_dumper.get());
// Signal level is unchanged with 0 db gain.
EXPECT_FLOAT_EQ(
@@ -173,4 +194,65 @@
kInputLevel * 10);
}
+TEST(AutomaticGainController2FixedDigital,
+ SetGainShouldBeFastAndTimeInvariant) {
+ // Number of frames required for the fixed gain controller to adapt on the
+ // input signal when the gain changes.
+ constexpr size_t kNumFrames = 5;
+
+ constexpr float kInputLevel = 1000.f;
+ constexpr size_t kSampleRate = 8000;
+ constexpr float kGainDbLow = 0.f;
+ constexpr float kGainDbHigh = 40.f;
+ static_assert(kGainDbLow < kGainDbHigh, "");
+
+ auto test_data_dumper = GetApmDataDumper();
+ std::unique_ptr<FixedGainController> fixed_gc = CreateFixedGainController(
+ kGainDbLow, kSampleRate, test_data_dumper.get());
+
+ fixed_gc->SetGain(kGainDbLow);
+ const float output_level_pre = RunFixedGainControllerWithConstantInput(
+ fixed_gc.get(), kInputLevel, kNumFrames, kSampleRate);
+
+ fixed_gc->SetGain(kGainDbHigh);
+ RunFixedGainControllerWithConstantInput(fixed_gc.get(), kInputLevel,
+ kNumFrames, kSampleRate);
+
+ fixed_gc->SetGain(kGainDbLow);
+ const float output_level_post = RunFixedGainControllerWithConstantInput(
+ fixed_gc.get(), kInputLevel, kNumFrames, kSampleRate);
+
+ EXPECT_EQ(output_level_pre, output_level_post);
+}
+
+TEST(AutomaticGainController2FixedDigital, RegionHistogramIsUpdated) {
+ constexpr size_t kSampleRate = 8000;
+ constexpr float kGainDb = 0.f;
+ constexpr float kInputLevel = 1000.f;
+ constexpr size_t kNumFrames = 5;
+
+ metrics::Reset();
+
+ auto test_data_dumper = GetApmDataDumper();
+ std::unique_ptr<FixedGainController> fixed_gc_no_saturation =
+ CreateFixedGainController(kGainDb, kSampleRate, "Test",
+ test_data_dumper.get());
+
+ static_cast<void>(RunFixedGainControllerWithConstantInput(
+ fixed_gc_no_saturation.get(), kInputLevel, kNumFrames, kSampleRate));
+
+ // Destroying FixedGainController should cause the last limiter region to be
+ // logged.
+ fixed_gc_no_saturation.reset();
+
+ EXPECT_EQ(1, metrics::NumSamples(
+ "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Identity"));
+ EXPECT_EQ(0, metrics::NumSamples(
+ "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Knee"));
+ EXPECT_EQ(0, metrics::NumSamples(
+ "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Limiter"));
+ EXPECT_EQ(0, metrics::NumSamples(
+ "WebRTC.Audio.Test.FixedDigitalGainCurveRegion.Saturation"));
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/agc2/gain_curve_applier.cc b/modules/audio_processing/agc2/gain_curve_applier.cc
index 122839a..b52e0d7 100644
--- a/modules/audio_processing/agc2/gain_curve_applier.cc
+++ b/modules/audio_processing/agc2/gain_curve_applier.cc
@@ -84,8 +84,9 @@
} // namespace
GainCurveApplier::GainCurveApplier(size_t sample_rate_hz,
- ApmDataDumper* apm_data_dumper)
- : interp_gain_curve_(apm_data_dumper),
+ ApmDataDumper* apm_data_dumper,
+ std::string histogram_name)
+ : interp_gain_curve_(apm_data_dumper, histogram_name),
level_estimator_(sample_rate_hz, apm_data_dumper),
apm_data_dumper_(apm_data_dumper) {}
@@ -129,4 +130,8 @@
kMaximalNumberOfSamplesPerChannel * 1000 / kFrameDurationMs);
}
+void GainCurveApplier::Reset() {
+ level_estimator_.Reset();
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/agc2/gain_curve_applier.h b/modules/audio_processing/agc2/gain_curve_applier.h
index 86ca251..a7ffa36 100644
--- a/modules/audio_processing/agc2/gain_curve_applier.h
+++ b/modules/audio_processing/agc2/gain_curve_applier.h
@@ -23,7 +23,9 @@
class GainCurveApplier {
public:
- GainCurveApplier(size_t sample_rate_hz, ApmDataDumper* apm_data_dumper);
+ GainCurveApplier(size_t sample_rate_hz,
+ ApmDataDumper* apm_data_dumper,
+ std::string histogram_name_prefix);
~GainCurveApplier();
@@ -37,6 +39,9 @@
// per_sample_scaling_factors_ array.
void SetSampleRate(size_t sample_rate_hz);
+ // Resets the internal state.
+ void Reset();
+
private:
const InterpolatedGainCurve interp_gain_curve_;
FixedDigitalLevelEstimator level_estimator_;
diff --git a/modules/audio_processing/agc2/gain_curve_applier_unittest.cc b/modules/audio_processing/agc2/gain_curve_applier_unittest.cc
index d9179a4..0f75f62 100644
--- a/modules/audio_processing/agc2/gain_curve_applier_unittest.cc
+++ b/modules/audio_processing/agc2/gain_curve_applier_unittest.cc
@@ -23,7 +23,7 @@
const int sample_rate_hz = 48000;
ApmDataDumper apm_data_dumper(0);
- GainCurveApplier gain_curve_applier(sample_rate_hz, &apm_data_dumper);
+ GainCurveApplier gain_curve_applier(sample_rate_hz, &apm_data_dumper, "");
VectorFloatFrame vectors_with_float_frame(1, sample_rate_hz / 100,
kMaxAbsFloatS16Value);
@@ -37,7 +37,7 @@
2.f;
ApmDataDumper apm_data_dumper(0);
- GainCurveApplier gain_curve_applier(sample_rate_hz, &apm_data_dumper);
+ GainCurveApplier gain_curve_applier(sample_rate_hz, &apm_data_dumper, "");
// Give the level estimator time to adapt.
for (int i = 0; i < 5; ++i) {
diff --git a/modules/audio_processing/agc2/interpolated_gain_curve.cc b/modules/audio_processing/agc2/interpolated_gain_curve.cc
index 7f1f16c..73e6a8e 100644
--- a/modules/audio_processing/agc2/interpolated_gain_curve.cc
+++ b/modules/audio_processing/agc2/interpolated_gain_curve.cc
@@ -14,41 +14,8 @@
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
-#include "system_wrappers/include/metrics.h"
namespace webrtc {
-namespace {
-void LogRegionStats(const InterpolatedGainCurve::Stats& stats) {
- using Region = InterpolatedGainCurve::GainCurveRegion;
- const int duration_s =
- stats.region_duration_frames / (1000 / kFrameDurationMs);
-
- switch (stats.region) {
- case Region::kIdentity: {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Audio.Agc2.FixedDigitalGainCurveRegion.Identity", duration_s);
- break;
- }
- case Region::kKnee: {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Audio.Agc2.FixedDigitalGainCurveRegion.Knee", duration_s);
- break;
- }
- case Region::kLimiter: {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Audio.Agc2.FixedDigitalGainCurveRegion.Limiter", duration_s);
- break;
- }
- case Region::kSaturation: {
- RTC_HISTOGRAM_COUNTS_10000(
- "WebRTC.Audio.Agc2.FixedDigitalGainCurveRegion.Saturation",
- duration_s);
- break;
- }
- default: { RTC_NOTREACHED(); }
- }
-}
-} // namespace
constexpr std::array<float, kInterpolatedGainCurveTotalPoints>
InterpolatedGainCurve::approximation_params_x_;
@@ -59,8 +26,17 @@
constexpr std::array<float, kInterpolatedGainCurveTotalPoints>
InterpolatedGainCurve::approximation_params_q_;
-InterpolatedGainCurve::InterpolatedGainCurve(ApmDataDumper* apm_data_dumper)
- : apm_data_dumper_(apm_data_dumper) {}
+InterpolatedGainCurve::InterpolatedGainCurve(ApmDataDumper* apm_data_dumper,
+ std::string histogram_name_prefix)
+ : region_logger_("WebRTC.Audio." + histogram_name_prefix +
+ ".FixedDigitalGainCurveRegion.Identity",
+ "WebRTC.Audio." + histogram_name_prefix +
+ ".FixedDigitalGainCurveRegion.Knee",
+ "WebRTC.Audio." + histogram_name_prefix +
+ ".FixedDigitalGainCurveRegion.Limiter",
+ "WebRTC.Audio." + histogram_name_prefix +
+ ".FixedDigitalGainCurveRegion.Saturation"),
+ apm_data_dumper_(apm_data_dumper) {}
InterpolatedGainCurve::~InterpolatedGainCurve() {
if (stats_.available) {
@@ -73,7 +49,69 @@
stats_.look_ups_limiter_region);
apm_data_dumper_->DumpRaw("agc2_interp_gain_curve_lookups_saturation",
stats_.look_ups_saturation_region);
- LogRegionStats(stats_);
+ region_logger_.LogRegionStats(stats_);
+ }
+}
+
+InterpolatedGainCurve::RegionLogger::RegionLogger(
+ std::string identity_histogram_name,
+ std::string knee_histogram_name,
+ std::string limiter_histogram_name,
+ std::string saturation_histogram_name)
+ : identity_histogram(
+ metrics::HistogramFactoryGetCounts(identity_histogram_name,
+ 1,
+ 10000,
+ 50)),
+ knee_histogram(metrics::HistogramFactoryGetCounts(knee_histogram_name,
+ 1,
+ 10000,
+ 50)),
+ limiter_histogram(
+ metrics::HistogramFactoryGetCounts(limiter_histogram_name,
+ 1,
+ 10000,
+ 50)),
+ saturation_histogram(
+ metrics::HistogramFactoryGetCounts(saturation_histogram_name,
+ 1,
+ 10000,
+ 50)) {}
+
+InterpolatedGainCurve::RegionLogger::~RegionLogger() = default;
+
+void InterpolatedGainCurve::RegionLogger::LogRegionStats(
+ const InterpolatedGainCurve::Stats& stats) const {
+ using Region = InterpolatedGainCurve::GainCurveRegion;
+ const int duration_s =
+ stats.region_duration_frames / (1000 / kFrameDurationMs);
+
+ switch (stats.region) {
+ case Region::kIdentity: {
+ if (identity_histogram) {
+ metrics::HistogramAdd(identity_histogram, duration_s);
+ }
+ break;
+ }
+ case Region::kKnee: {
+ if (knee_histogram) {
+ metrics::HistogramAdd(knee_histogram, duration_s);
+ }
+ break;
+ }
+ case Region::kLimiter: {
+ if (limiter_histogram) {
+ metrics::HistogramAdd(limiter_histogram, duration_s);
+ }
+ break;
+ }
+ case Region::kSaturation: {
+ if (saturation_histogram) {
+ metrics::HistogramAdd(saturation_histogram, duration_s);
+ }
+ break;
+ }
+ default: { RTC_NOTREACHED(); }
}
}
@@ -100,7 +138,7 @@
if (region == stats_.region) {
++stats_.region_duration_frames;
} else {
- LogRegionStats(stats_);
+ region_logger_.LogRegionStats(stats_);
stats_.region_duration_frames = 0;
stats_.region = region;
diff --git a/modules/audio_processing/agc2/interpolated_gain_curve.h b/modules/audio_processing/agc2/interpolated_gain_curve.h
index fc5842b..68d4532 100644
--- a/modules/audio_processing/agc2/interpolated_gain_curve.h
+++ b/modules/audio_processing/agc2/interpolated_gain_curve.h
@@ -12,11 +12,13 @@
#define MODULES_AUDIO_PROCESSING_AGC2_INTERPOLATED_GAIN_CURVE_H_
#include <array>
+#include <string>
#include "modules/audio_processing/agc2/agc2_common.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/gtest_prod_util.h"
+#include "system_wrappers/include/metrics.h"
namespace webrtc {
@@ -59,8 +61,8 @@
int64_t region_duration_frames = 0;
};
- // InterpolatedGainCurve(InterpolatedGainCurve&&);
- explicit InterpolatedGainCurve(ApmDataDumper* apm_data_dumper);
+ InterpolatedGainCurve(ApmDataDumper* apm_data_dumper,
+ std::string histogram_name_prefix);
~InterpolatedGainCurve();
Stats get_stats() const { return stats_; }
@@ -76,6 +78,23 @@
// ComputeInterpolatedGainCurve.
FRIEND_TEST_ALL_PREFIXES(AutomaticGainController2InterpolatedGainCurve,
CheckApproximationParams);
+
+ struct RegionLogger {
+ metrics::Histogram* identity_histogram;
+ metrics::Histogram* knee_histogram;
+ metrics::Histogram* limiter_histogram;
+ metrics::Histogram* saturation_histogram;
+
+ RegionLogger(std::string identity_histogram_name,
+ std::string knee_histogram_name,
+ std::string limiter_histogram_name,
+ std::string saturation_histogram_name);
+
+ ~RegionLogger();
+
+ void LogRegionStats(const InterpolatedGainCurve::Stats& stats) const;
+ } region_logger_;
+
void UpdateStats(float input_level) const;
ApmDataDumper* const apm_data_dumper_;
diff --git a/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc b/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc
index d75ddbd..dd69631 100644
--- a/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc
+++ b/modules/audio_processing/agc2/interpolated_gain_curve_unittest.cc
@@ -32,7 +32,7 @@
} // namespace
TEST(AutomaticGainController2InterpolatedGainCurve, CreateUse) {
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels = test::LinSpace(
kLevelEpsilon, DbfsToFloatS16(limiter.max_input_level_db() + 1), 500);
@@ -42,7 +42,7 @@
}
TEST(AutomaticGainController2InterpolatedGainCurve, CheckValidOutput) {
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels = test::LinSpace(
kLevelEpsilon, limiter.max_input_level_linear() * 2.0, 500);
@@ -55,7 +55,7 @@
}
TEST(AutomaticGainController2InterpolatedGainCurve, CheckMonotonicity) {
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels = test::LinSpace(
kLevelEpsilon, limiter.max_input_level_linear() + kLevelEpsilon + 0.5,
@@ -69,7 +69,7 @@
}
TEST(AutomaticGainController2InterpolatedGainCurve, CheckApproximation) {
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels = test::LinSpace(
kLevelEpsilon, limiter.max_input_level_linear() - kLevelEpsilon, 500);
@@ -82,7 +82,7 @@
}
TEST(AutomaticGainController2InterpolatedGainCurve, CheckRegionBoundaries) {
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const std::vector<double> levels{
{kLevelEpsilon, limiter.knee_start_linear() + kLevelEpsilon,
@@ -101,7 +101,7 @@
TEST(AutomaticGainController2InterpolatedGainCurve, CheckIdentityRegion) {
constexpr size_t kNumSteps = 10;
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels =
test::LinSpace(kLevelEpsilon, limiter.knee_start_linear(), kNumSteps);
@@ -120,7 +120,7 @@
TEST(AutomaticGainController2InterpolatedGainCurve,
CheckNoOverApproximationKnee) {
constexpr size_t kNumSteps = 10;
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels =
test::LinSpace(limiter.knee_start_linear() + kLevelEpsilon,
@@ -142,7 +142,7 @@
TEST(AutomaticGainController2InterpolatedGainCurve,
CheckNoOverApproximationBeyondKnee) {
constexpr size_t kNumSteps = 10;
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels = test::LinSpace(
limiter.limiter_start_linear() + kLevelEpsilon,
@@ -164,7 +164,7 @@
TEST(AutomaticGainController2InterpolatedGainCurve,
CheckNoOverApproximationWithSaturation) {
constexpr size_t kNumSteps = 3;
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
const auto levels = test::LinSpace(
limiter.max_input_level_linear() + kLevelEpsilon,
@@ -185,7 +185,7 @@
test::InterpolatedParameters parameters =
test::ComputeInterpolatedGainCurveApproximationParams();
- InterpolatedGainCurve igc(&apm_data_dumper);
+ InterpolatedGainCurve igc(&apm_data_dumper, "");
for (size_t i = 0; i < kInterpolatedGainCurveTotalPoints; ++i) {
// The tolerance levels are chosen to account for deviations due
diff --git a/modules/audio_processing/agc2/rnn_vad/BUILD.gn b/modules/audio_processing/agc2/rnn_vad/BUILD.gn
index 41521df..d1edece 100644
--- a/modules/audio_processing/agc2/rnn_vad/BUILD.gn
+++ b/modules/audio_processing/agc2/rnn_vad/BUILD.gn
@@ -8,13 +8,7 @@
import("../../../../webrtc.gni")
-group("rnn_vad") {
- deps = [
- ":lib",
- ]
-}
-
-rtc_source_set("lib") {
+rtc_source_set("rnn_vad") {
sources = [
"common.h",
"features_extraction.cc",
@@ -50,7 +44,7 @@
}
if (rtc_include_tests) {
- rtc_source_set("lib_test") {
+ rtc_source_set("test_utils") {
testonly = true
sources = [
"test_utils.cc",
@@ -104,8 +98,8 @@
"symmetric_matrix_buffer_unittest.cc",
]
deps = [
- ":lib",
- ":lib_test",
+ ":rnn_vad",
+ ":test_utils",
"../..:audioproc_test_utils",
"../../../../api:array_view",
"../../../../common_audio/",
@@ -126,7 +120,7 @@
"rnn_vad_tool.cc",
]
deps = [
- ":lib",
+ ":rnn_vad",
"../../../../api:array_view",
"../../../../common_audio:common_audio",
"../../../../rtc_base:rtc_base_approved",
diff --git a/modules/audio_processing/audio_buffer.h b/modules/audio_processing/audio_buffer.h
index 3d7c4a8..ade3eec 100644
--- a/modules/audio_processing/audio_buffer.h
+++ b/modules/audio_processing/audio_buffer.h
@@ -18,7 +18,6 @@
#include "common_audio/channel_buffer.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/splitting_filter.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc
index 7e5955a..8848b73 100644
--- a/modules/audio_processing/audio_processing_impl.cc
+++ b/modules/audio_processing/audio_processing_impl.cc
@@ -24,7 +24,9 @@
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/common.h"
#include "modules/audio_processing/echo_cancellation_impl.h"
+#include "modules/audio_processing/echo_cancellation_proxy.h"
#include "modules/audio_processing/echo_control_mobile_impl.h"
+#include "modules/audio_processing/echo_control_mobile_proxy.h"
#include "modules/audio_processing/gain_control_for_experimental_agc.h"
#include "modules/audio_processing/gain_control_impl.h"
#include "modules/audio_processing/gain_controller2.h"
@@ -33,10 +35,9 @@
#include "rtc_base/logging.h"
#include "rtc_base/platform_file.h"
#include "rtc_base/refcountedobject.h"
+#include "rtc_base/system/arch.h"
+#include "rtc_base/timeutils.h"
#include "rtc_base/trace_event.h"
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
-#include "modules/audio_processing/intelligibility/intelligibility_enhancer.h"
-#endif
#include "modules/audio_processing/level_estimator_impl.h"
#include "modules/audio_processing/low_cut_filter.h"
#include "modules/audio_processing/noise_suppression_impl.h"
@@ -46,14 +47,6 @@
#include "rtc_base/atomicops.h"
#include "system_wrappers/include/metrics.h"
-// Check to verify that the define for the intelligibility enhancer is properly
-// set.
-#if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \
- (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \
- WEBRTC_INTELLIGIBILITY_ENHANCER != 1)
-#error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1"
-#endif
-
#define RETURN_ON_ERR(expr) \
do { \
int err = (expr); \
@@ -154,9 +147,11 @@
AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates(
bool capture_post_processor_enabled,
- bool render_pre_processor_enabled)
+ bool render_pre_processor_enabled,
+ bool capture_analyzer_enabled)
: capture_post_processor_enabled_(capture_post_processor_enabled),
- render_pre_processor_enabled_(render_pre_processor_enabled) {}
+ render_pre_processor_enabled_(render_pre_processor_enabled),
+ capture_analyzer_enabled_(capture_analyzer_enabled) {}
bool AudioProcessingImpl::ApmSubmoduleStates::Update(
bool low_cut_filter_enabled,
@@ -164,7 +159,6 @@
bool mobile_echo_controller_enabled,
bool residual_echo_detector_enabled,
bool noise_suppressor_enabled,
- bool intelligibility_enhancer_enabled,
bool adaptive_gain_controller_enabled,
bool gain_controller2_enabled,
bool pre_amplifier_enabled,
@@ -181,8 +175,6 @@
(residual_echo_detector_enabled != residual_echo_detector_enabled_);
changed |= (noise_suppressor_enabled != noise_suppressor_enabled_);
changed |=
- (intelligibility_enhancer_enabled != intelligibility_enhancer_enabled_);
- changed |=
(adaptive_gain_controller_enabled != adaptive_gain_controller_enabled_);
changed |=
(gain_controller2_enabled != gain_controller2_enabled_);
@@ -198,7 +190,6 @@
mobile_echo_controller_enabled_ = mobile_echo_controller_enabled;
residual_echo_detector_enabled_ = residual_echo_detector_enabled;
noise_suppressor_enabled_ = noise_suppressor_enabled;
- intelligibility_enhancer_enabled_ = intelligibility_enhancer_enabled;
adaptive_gain_controller_enabled_ = adaptive_gain_controller_enabled;
gain_controller2_enabled_ = gain_controller2_enabled;
pre_amplifier_enabled_ = pre_amplifier_enabled;
@@ -215,12 +206,7 @@
bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandSubModulesActive()
const {
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- return CaptureMultiBandProcessingActive() ||
- intelligibility_enhancer_enabled_ || voice_activity_detector_enabled_;
-#else
return CaptureMultiBandProcessingActive() || voice_activity_detector_enabled_;
-#endif
}
bool AudioProcessingImpl::ApmSubmoduleStates::CaptureMultiBandProcessingActive()
@@ -236,6 +222,10 @@
pre_amplifier_enabled_;
}
+bool AudioProcessingImpl::ApmSubmoduleStates::CaptureAnalyzerActive() const {
+ return capture_analyzer_enabled_;
+}
+
bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandSubModulesActive()
const {
return RenderMultiBandProcessingActive() || echo_canceller_enabled_ ||
@@ -250,11 +240,7 @@
bool AudioProcessingImpl::ApmSubmoduleStates::RenderMultiBandProcessingActive()
const {
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- return intelligibility_enhancer_enabled_;
-#else
return false;
-#endif
}
struct AudioProcessingImpl::ApmPublicSubmodules {
@@ -262,6 +248,8 @@
// Accessed externally of APM without any lock acquired.
std::unique_ptr<EchoCancellationImpl> echo_cancellation;
std::unique_ptr<EchoControlMobileImpl> echo_control_mobile;
+ std::unique_ptr<EchoCancellationProxy> echo_cancellation_proxy;
+ std::unique_ptr<EchoControlMobileProxy> echo_control_mobile_proxy;
std::unique_ptr<GainControlImpl> gain_control;
std::unique_ptr<LevelEstimatorImpl> level_estimator;
std::unique_ptr<NoiseSuppressionImpl> noise_suppression;
@@ -271,18 +259,17 @@
// Accessed internally from both render and capture.
std::unique_ptr<TransientSuppressor> transient_suppressor;
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- std::unique_ptr<IntelligibilityEnhancer> intelligibility_enhancer;
-#endif
};
struct AudioProcessingImpl::ApmPrivateSubmodules {
ApmPrivateSubmodules(std::unique_ptr<CustomProcessing> capture_post_processor,
std::unique_ptr<CustomProcessing> render_pre_processor,
- rtc::scoped_refptr<EchoDetector> echo_detector)
+ rtc::scoped_refptr<EchoDetector> echo_detector,
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer)
: echo_detector(std::move(echo_detector)),
capture_post_processor(std::move(capture_post_processor)),
- render_pre_processor(std::move(render_pre_processor)) {}
+ render_pre_processor(std::move(render_pre_processor)),
+ capture_analyzer(std::move(capture_analyzer)) {}
// Accessed internally from capture or during initialization
std::unique_ptr<AgcManagerDirect> agc_manager;
std::unique_ptr<GainController2> gain_controller2;
@@ -292,6 +279,7 @@
std::unique_ptr<CustomProcessing> capture_post_processor;
std::unique_ptr<CustomProcessing> render_pre_processor;
std::unique_ptr<GainApplier> pre_amplifier;
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer;
};
AudioProcessingBuilder::AudioProcessingBuilder() = default;
@@ -309,6 +297,12 @@
return *this;
}
+AudioProcessingBuilder& AudioProcessingBuilder::SetCaptureAnalyzer(
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer) {
+ capture_analyzer_ = std::move(capture_analyzer);
+ return *this;
+}
+
AudioProcessingBuilder& AudioProcessingBuilder::SetEchoControlFactory(
std::unique_ptr<EchoControlFactory> echo_control_factory) {
echo_control_factory_ = std::move(echo_control_factory);
@@ -330,7 +324,7 @@
AudioProcessingImpl* apm = new rtc::RefCountedObject<AudioProcessingImpl>(
config, std::move(capture_post_processing_),
std::move(render_pre_processing_), std::move(echo_control_factory_),
- std::move(echo_detector_));
+ std::move(echo_detector_), std::move(capture_analyzer_));
if (apm->Initialize() != AudioProcessing::kNoError) {
delete apm;
apm = nullptr;
@@ -339,7 +333,8 @@
}
AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
- : AudioProcessingImpl(config, nullptr, nullptr, nullptr, nullptr) {}
+ : AudioProcessingImpl(config, nullptr, nullptr, nullptr, nullptr, nullptr) {
+}
int AudioProcessingImpl::instance_count_ = 0;
@@ -348,7 +343,8 @@
std::unique_ptr<CustomProcessing> capture_post_processor,
std::unique_ptr<CustomProcessing> render_pre_processor,
std::unique_ptr<EchoControlFactory> echo_control_factory,
- rtc::scoped_refptr<EchoDetector> echo_detector)
+ rtc::scoped_refptr<EchoDetector> echo_detector,
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer)
: data_dumper_(
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
capture_runtime_settings_(kRuntimeSettingQueueSize),
@@ -357,12 +353,15 @@
render_runtime_settings_enqueuer_(&render_runtime_settings_),
high_pass_filter_impl_(new HighPassFilterImpl(this)),
echo_control_factory_(std::move(echo_control_factory)),
- submodule_states_(!!capture_post_processor, !!render_pre_processor),
+ submodule_states_(!!capture_post_processor,
+ !!render_pre_processor,
+ !!capture_analyzer),
public_submodules_(new ApmPublicSubmodules()),
private_submodules_(
new ApmPrivateSubmodules(std::move(capture_post_processor),
std::move(render_pre_processor),
- std::move(echo_detector))),
+ std::move(echo_detector),
+ std::move(capture_analyzer))),
constants_(config.Get<ExperimentalAgc>().startup_min_volume,
config.Get<ExperimentalAgc>().clipped_level_min,
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
@@ -372,14 +371,14 @@
#else
config.Get<ExperimentalAgc>().enabled,
config.Get<ExperimentalAgc>().enabled_agc2_level_estimator,
- config.Get<ExperimentalAgc>().enabled_agc2_digital_adaptive),
+ config.Get<ExperimentalAgc>().digital_adaptive_disabled),
#endif
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
capture_(false),
#else
capture_(config.Get<ExperimentalNs>().enabled),
#endif
- capture_nonlocked_(config.Get<Intelligibility>().enabled) {
+ capture_nonlocked_() {
{
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
@@ -392,6 +391,11 @@
new EchoCancellationImpl(&crit_render_, &crit_capture_));
public_submodules_->echo_control_mobile.reset(
new EchoControlMobileImpl(&crit_render_, &crit_capture_));
+ public_submodules_->echo_cancellation_proxy.reset(new EchoCancellationProxy(
+ this, public_submodules_->echo_cancellation.get()));
+ public_submodules_->echo_control_mobile_proxy.reset(
+ new EchoControlMobileProxy(
+ this, public_submodules_->echo_control_mobile.get()));
public_submodules_->gain_control.reset(
new GainControlImpl(&crit_render_, &crit_capture_));
public_submodules_->level_estimator.reset(
@@ -414,7 +418,9 @@
// implemented.
private_submodules_->gain_controller2.reset(new GainController2());
- RTC_LOG(LS_INFO) << "Capture post processor activated: "
+ RTC_LOG(LS_INFO) << "Capture analyzer activated: "
+ << !!private_submodules_->capture_analyzer
+ << "\nCapture post processor activated: "
<< !!private_submodules_->capture_post_processor
<< "\nRender pre processor activated: "
<< !!private_submodules_->render_pre_processor;
@@ -556,9 +562,6 @@
public_submodules_->gain_control_for_experimental_agc->Initialize();
}
InitializeTransient();
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- InitializeIntelligibility();
-#endif
InitializeLowCutFilter();
public_submodules_->noise_suppression->Initialize(num_proc_channels(),
proc_sample_rate_hz());
@@ -567,11 +570,12 @@
InitializeResidualEchoDetector();
InitializeEchoController();
InitializeGainController2();
+ InitializeAnalyzer();
InitializePostProcessor();
InitializePreProcessor();
if (aec_dump_) {
- aec_dump_->WriteInitMessage(formats_.api_format);
+ aec_dump_->WriteInitMessage(formats_.api_format, rtc::TimeUTCMillis());
}
return kNoError;
}
@@ -666,6 +670,13 @@
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
+ static_cast<EchoCancellation*>(public_submodules_->echo_cancellation.get())
+ ->Enable(config_.echo_canceller.enabled &&
+ !config_.echo_canceller.mobile_mode);
+ static_cast<EchoControlMobile*>(public_submodules_->echo_control_mobile.get())
+ ->Enable(config_.echo_canceller.enabled &&
+ config_.echo_canceller.mobile_mode);
+
InitializeLowCutFilter();
RTC_LOG(LS_INFO) << "Highpass filter activated: "
@@ -701,15 +712,6 @@
config.Get<ExperimentalNs>().enabled;
InitializeTransient();
}
-
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- if (capture_nonlocked_.intelligibility_enabled !=
- config.Get<Intelligibility>().enabled) {
- capture_nonlocked_.intelligibility_enabled =
- config.Get<Intelligibility>().enabled;
- InitializeIntelligibility();
- }
-#endif
}
int AudioProcessingImpl::proc_sample_rate_hz() const {
@@ -1098,10 +1100,10 @@
TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_AudioFrame");
{
// Acquire the capture lock in order to safely call the function
- // that retrieves the render side data. This function accesses apm
+ // that retrieves the render side data. This function accesses APM
// getters that need the capture lock held when being called.
// The lock needs to be released as
- // public_submodules_->echo_control_mobile->is_enabled() aquires this lock
+ // public_submodules_->echo_control_mobile->is_enabled() acquires this lock
// as well.
rtc::CritScope cs_capture(&crit_capture_);
EmptyQueuedRenderAudio();
@@ -1265,18 +1267,6 @@
capture_buffer->CopyLowPassToReference();
}
public_submodules_->noise_suppression->ProcessCaptureAudio(capture_buffer);
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- if (capture_nonlocked_.intelligibility_enabled) {
- RTC_DCHECK(public_submodules_->noise_suppression->is_enabled());
- const int gain_db =
- public_submodules_->gain_control->is_enabled()
- ? public_submodules_->gain_control->compression_gain_db()
- : 0;
- const float gain = DbToRatio(gain_db);
- public_submodules_->intelligibility_enhancer->SetCaptureNoiseEstimate(
- public_submodules_->noise_suppression->NoiseEstimate(), gain);
- }
-#endif
// Ensure that the stream delay was set before the call to the
// AECM ProcessCaptureAudio function.
@@ -1332,7 +1322,14 @@
capture_.key_pressed);
}
+ // Experimental APM sub-module that analyzes |capture_buffer|.
+ if (private_submodules_->capture_analyzer) {
+ private_submodules_->capture_analyzer->Analyze(capture_buffer);
+ }
+
if (config_.gain_controller2.enabled) {
+ private_submodules_->gain_controller2->NotifyAnalogLevel(
+ gain_control()->stream_analog_level());
private_submodules_->gain_controller2->Process(capture_buffer);
}
@@ -1478,32 +1475,25 @@
int AudioProcessingImpl::ProcessRenderStreamLocked() {
AudioBuffer* render_buffer = render_.render_audio.get(); // For brevity.
- QueueNonbandedRenderAudio(render_buffer);
-
HandleRenderRuntimeSettings();
if (private_submodules_->render_pre_processor) {
private_submodules_->render_pre_processor->Process(render_buffer);
}
+ QueueNonbandedRenderAudio(render_buffer);
+
if (submodule_states_.RenderMultiBandSubModulesActive() &&
SampleRateSupportsMultiBand(
formats_.render_processing_format.sample_rate_hz())) {
render_buffer->SplitIntoFrequencyBands();
}
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- if (capture_nonlocked_.intelligibility_enabled) {
- public_submodules_->intelligibility_enhancer->ProcessRenderAudio(
- render_buffer);
- }
-#endif
-
if (submodule_states_.RenderMultiBandSubModulesActive()) {
QueueBandedRenderAudio(render_buffer);
}
- // TODO(peah): Perform the queueing Ãnside QueueRenderAudiuo().
+ // TODO(peah): Perform the queuing inside QueueRenderAudiuo().
if (private_submodules_->echo_controller) {
private_submodules_->echo_controller->AnalyzeRender(render_buffer);
}
@@ -1572,7 +1562,7 @@
// 'aec_dump' parameter, which is after locks are released.
aec_dump_.swap(aec_dump);
WriteAecDumpConfigMessage(true);
- aec_dump_->WriteInitMessage(formats_.api_format);
+ aec_dump_->WriteInitMessage(formats_.api_format, rtc::TimeUTCMillis());
}
void AudioProcessingImpl::DetachAecDump() {
@@ -1710,11 +1700,11 @@
}
EchoCancellation* AudioProcessingImpl::echo_cancellation() const {
- return public_submodules_->echo_cancellation.get();
+ return public_submodules_->echo_cancellation_proxy.get();
}
EchoControlMobile* AudioProcessingImpl::echo_control_mobile() const {
- return public_submodules_->echo_control_mobile.get();
+ return public_submodules_->echo_control_mobile_proxy.get();
}
GainControl* AudioProcessingImpl::gain_control() const {
@@ -1761,7 +1751,6 @@
public_submodules_->echo_control_mobile->is_enabled(),
config_.residual_echo_detector.enabled,
public_submodules_->noise_suppression->is_enabled(),
- capture_nonlocked_.intelligibility_enabled,
public_submodules_->gain_control->is_enabled(),
config_.gain_controller2.enabled, config_.pre_amplifier.enabled,
capture_nonlocked_.echo_controller_enabled,
@@ -1782,18 +1771,6 @@
}
}
-void AudioProcessingImpl::InitializeIntelligibility() {
-#if WEBRTC_INTELLIGIBILITY_ENHANCER
- if (capture_nonlocked_.intelligibility_enabled) {
- public_submodules_->intelligibility_enhancer.reset(
- new IntelligibilityEnhancer(capture_nonlocked_.split_rate,
- render_.render_audio->num_channels(),
- render_.render_audio->num_bands(),
- NoiseSuppressionImpl::num_noise_bins()));
- }
-#endif
-}
-
void AudioProcessingImpl::InitializeLowCutFilter() {
if (config_.high_pass_filter.enabled) {
private_submodules_->low_cut_filter.reset(
@@ -1834,6 +1811,13 @@
formats_.render_processing_format.sample_rate_hz(), 1);
}
+void AudioProcessingImpl::InitializeAnalyzer() {
+ if (private_submodules_->capture_analyzer) {
+ private_submodules_->capture_analyzer->Initialize(proc_sample_rate_hz(),
+ num_proc_channels());
+ }
+}
+
void AudioProcessingImpl::InitializePostProcessor() {
if (private_submodules_->capture_post_processor) {
private_submodules_->capture_post_processor->Initialize(
@@ -1974,8 +1958,6 @@
apm_config.transient_suppression_enabled =
capture_.transient_suppressor_enabled;
- apm_config.intelligibility_enhancer_enabled =
- capture_nonlocked_.intelligibility_enabled;
apm_config.experiments_description = experiments_description;
apm_config.pre_amplifier_enabled = config_.pre_amplifier.enabled;
apm_config.pre_amplifier_fixed_gain_factor =
diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h
index 44d0d08..a95e150 100644
--- a/modules/audio_processing/audio_processing_impl.h
+++ b/modules/audio_processing/audio_processing_impl.h
@@ -42,7 +42,8 @@
std::unique_ptr<CustomProcessing> capture_post_processor,
std::unique_ptr<CustomProcessing> render_pre_processor,
std::unique_ptr<EchoControlFactory> echo_control_factory,
- rtc::scoped_refptr<EchoDetector> echo_detector);
+ rtc::scoped_refptr<EchoDetector> echo_detector,
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer);
~AudioProcessingImpl() override;
int Initialize() override;
int Initialize(int capture_input_sample_rate_hz,
@@ -174,14 +175,14 @@
class ApmSubmoduleStates {
public:
ApmSubmoduleStates(bool capture_post_processor_enabled,
- bool render_pre_processor_enabled);
+ bool render_pre_processor_enabled,
+ bool capture_analyzer_enabled);
// Updates the submodule state and returns true if it has changed.
bool Update(bool low_cut_filter_enabled,
bool echo_canceller_enabled,
bool mobile_echo_controller_enabled,
bool residual_echo_detector_enabled,
bool noise_suppressor_enabled,
- bool intelligibility_enhancer_enabled,
bool adaptive_gain_controller_enabled,
bool gain_controller2_enabled,
bool pre_amplifier_enabled,
@@ -192,6 +193,7 @@
bool CaptureMultiBandSubModulesActive() const;
bool CaptureMultiBandProcessingActive() const;
bool CaptureFullBandProcessingActive() const;
+ bool CaptureAnalyzerActive() const;
bool RenderMultiBandSubModulesActive() const;
bool RenderFullBandProcessingActive() const;
bool RenderMultiBandProcessingActive() const;
@@ -199,12 +201,12 @@
private:
const bool capture_post_processor_enabled_ = false;
const bool render_pre_processor_enabled_ = false;
+ const bool capture_analyzer_enabled_ = false;
bool low_cut_filter_enabled_ = false;
bool echo_canceller_enabled_ = false;
bool mobile_echo_controller_enabled_ = false;
bool residual_echo_detector_enabled_ = false;
bool noise_suppressor_enabled_ = false;
- bool intelligibility_enhancer_enabled_ = false;
bool adaptive_gain_controller_enabled_ = false;
bool gain_controller2_enabled_ = false;
bool pre_amplifier_enabled_ = false;
@@ -241,8 +243,6 @@
// acquired.
void InitializeTransient()
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
- void InitializeIntelligibility()
- RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
int InitializeLocked(const ProcessingConfig& config)
RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_, crit_capture_);
void InitializeResidualEchoDetector()
@@ -252,6 +252,7 @@
void InitializeGainController2() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
void InitializePreAmplifier() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
void InitializePostProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
+ void InitializeAnalyzer() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_capture_);
void InitializePreProcessor() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_render_);
// Empties and handles the respective RuntimeSetting queues.
@@ -394,18 +395,16 @@
} capture_ RTC_GUARDED_BY(crit_capture_);
struct ApmCaptureNonLockedState {
- ApmCaptureNonLockedState(bool intelligibility_enabled)
+ ApmCaptureNonLockedState()
: capture_processing_format(kSampleRate16kHz),
split_rate(kSampleRate16kHz),
- stream_delay_ms(0),
- intelligibility_enabled(intelligibility_enabled) {}
+ stream_delay_ms(0) {}
// Only the rate and samples fields of capture_processing_format_ are used
// because the forward processing number of channels is mutable and is
// tracked by the capture_audio_.
StreamConfig capture_processing_format;
int split_rate;
int stream_delay_ms;
- bool intelligibility_enabled;
bool echo_controller_enabled = false;
} capture_nonlocked_;
diff --git a/modules/audio_processing/audio_processing_impl_unittest.cc b/modules/audio_processing/audio_processing_impl_unittest.cc
index 3ac5e71..8926f02 100644
--- a/modules/audio_processing/audio_processing_impl_unittest.cc
+++ b/modules/audio_processing/audio_processing_impl_unittest.cc
@@ -10,7 +10,10 @@
#include "modules/audio_processing/audio_processing_impl.h"
+#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/test/test_utils.h"
+#include "rtc_base/refcountedobject.h"
+#include "rtc_base/scoped_ref_ptr.h"
#include "test/gmock.h"
#include "test/gtest.h"
@@ -33,24 +36,83 @@
MOCK_CONST_METHOD0(Release, rtc::RefCountReleaseStatus());
};
-void GenerateFixedFrame(int16_t audio_level,
- size_t input_rate,
- size_t num_channels,
- AudioFrame* fixed_frame) {
+void InitializeAudioFrame(size_t input_rate,
+ size_t num_channels,
+ AudioFrame* frame) {
const size_t samples_per_input_channel = rtc::CheckedDivExact(
input_rate, static_cast<size_t>(rtc::CheckedDivExact(
1000, AudioProcessing::kChunkSizeMs)));
- fixed_frame->samples_per_channel_ = samples_per_input_channel;
- fixed_frame->sample_rate_hz_ = input_rate;
- fixed_frame->num_channels_ = num_channels;
-
RTC_DCHECK_LE(samples_per_input_channel * num_channels,
AudioFrame::kMaxDataSizeSamples);
- for (size_t i = 0; i < samples_per_input_channel * num_channels; ++i) {
- fixed_frame->mutable_data()[i] = audio_level;
+ frame->samples_per_channel_ = samples_per_input_channel;
+ frame->sample_rate_hz_ = input_rate;
+ frame->num_channels_ = num_channels;
+}
+
+void FillFixedFrame(int16_t audio_level, AudioFrame* frame) {
+ const size_t num_samples = frame->samples_per_channel_ * frame->num_channels_;
+ for (size_t i = 0; i < num_samples; ++i) {
+ frame->mutable_data()[i] = audio_level;
}
}
+// Mocks EchoDetector and records the first samples of the last analyzed render
+// stream frame. Used to check what data is read by an EchoDetector
+// implementation injected into an APM.
+class TestEchoDetector : public EchoDetector {
+ public:
+ TestEchoDetector()
+ : analyze_render_audio_called_(false),
+ last_render_audio_first_sample_(0.f) {}
+ ~TestEchoDetector() override = default;
+ void AnalyzeRenderAudio(rtc::ArrayView<const float> render_audio) override {
+ last_render_audio_first_sample_ = render_audio[0];
+ analyze_render_audio_called_ = true;
+ }
+ void AnalyzeCaptureAudio(rtc::ArrayView<const float> capture_audio) override {
+ }
+ void Initialize(int capture_sample_rate_hz,
+ int num_capture_channels,
+ int render_sample_rate_hz,
+ int num_render_channels) override {}
+ EchoDetector::Metrics GetMetrics() const override { return {}; }
+ // Returns true if AnalyzeRenderAudio() has been called at least once.
+ bool analyze_render_audio_called() const {
+ return analyze_render_audio_called_;
+ }
+ // Returns the first sample of the last analyzed render frame.
+ float last_render_audio_first_sample() const {
+ return last_render_audio_first_sample_;
+ }
+
+ private:
+ bool analyze_render_audio_called_;
+ float last_render_audio_first_sample_;
+};
+
+// Mocks CustomProcessing and applies ProcessSample() to all the samples.
+// Meant to be injected into an APM to modify samples in a known and detectable
+// way.
+class TestRenderPreProcessor : public CustomProcessing {
+ public:
+ TestRenderPreProcessor() = default;
+ ~TestRenderPreProcessor() = default;
+ void Initialize(int sample_rate_hz, int num_channels) override {}
+ void Process(AudioBuffer* audio) override {
+ for (size_t k = 0; k < audio->num_channels(); ++k) {
+ rtc::ArrayView<float> channel_view(audio->channels_f()[k],
+ audio->num_frames());
+ std::transform(channel_view.begin(), channel_view.end(),
+ channel_view.begin(), ProcessSample);
+ }
+ };
+ std::string ToString() const override { return "TestRenderPreProcessor"; }
+ void SetRuntimeSetting(AudioProcessing::RuntimeSetting setting) override {}
+ // Modifies a sample. This member is used in Process() to modify a frame and
+ // it is publicly visible to enable tests.
+ static constexpr float ProcessSample(float x) { return 2.f * x; }
+};
+
} // namespace
TEST(AudioProcessingImplTest, AudioParameterChangeTriggersInit) {
@@ -98,26 +160,74 @@
apm->ApplyConfig(apm_config);
AudioFrame frame;
- constexpr int16_t audio_level = 10000;
- constexpr size_t input_rate = 48000;
- constexpr size_t num_channels = 2;
+ constexpr int16_t kAudioLevel = 10000;
+ constexpr size_t kSampleRateHz = 48000;
+ constexpr size_t kNumChannels = 2;
+ InitializeAudioFrame(kSampleRateHz, kNumChannels, &frame);
- GenerateFixedFrame(audio_level, input_rate, num_channels, &frame);
+ FillFixedFrame(kAudioLevel, &frame);
apm->ProcessStream(&frame);
- EXPECT_EQ(frame.data()[100], audio_level)
+ EXPECT_EQ(frame.data()[100], kAudioLevel)
<< "With factor 1, frame shouldn't be modified.";
- constexpr float gain_factor = 2.f;
+ constexpr float kGainFactor = 2.f;
apm->SetRuntimeSetting(
- AudioProcessing::RuntimeSetting::CreateCapturePreGain(gain_factor));
+ AudioProcessing::RuntimeSetting::CreateCapturePreGain(kGainFactor));
// Process for two frames to have time to ramp up gain.
for (int i = 0; i < 2; ++i) {
- GenerateFixedFrame(audio_level, input_rate, num_channels, &frame);
+ FillFixedFrame(kAudioLevel, &frame);
apm->ProcessStream(&frame);
}
- EXPECT_EQ(frame.data()[100], gain_factor * audio_level)
+ EXPECT_EQ(frame.data()[100], kGainFactor * kAudioLevel)
<< "Frame should be amplified.";
}
+TEST(AudioProcessingImplTest, RenderPreProcessorBeforeEchoDetector) {
+ // Make sure that signal changes caused by a render pre-processing sub-module
+ // take place before any echo detector analysis.
+ rtc::scoped_refptr<TestEchoDetector> test_echo_detector(
+ new rtc::RefCountedObject<TestEchoDetector>());
+ std::unique_ptr<CustomProcessing> test_render_pre_processor(
+ new TestRenderPreProcessor());
+ // Create APM injecting the test echo detector and render pre-processor.
+ std::unique_ptr<AudioProcessing> apm(
+ AudioProcessingBuilder()
+ .SetEchoDetector(test_echo_detector)
+ .SetRenderPreProcessing(std::move(test_render_pre_processor))
+ .Create());
+ webrtc::AudioProcessing::Config apm_config;
+ apm_config.pre_amplifier.enabled = true;
+ apm_config.residual_echo_detector.enabled = true;
+ apm->ApplyConfig(apm_config);
+
+ constexpr int16_t kAudioLevel = 1000;
+ constexpr int kSampleRateHz = 16000;
+ constexpr size_t kNumChannels = 1;
+ AudioFrame frame;
+ InitializeAudioFrame(kSampleRateHz, kNumChannels, &frame);
+
+ constexpr float kAudioLevelFloat = static_cast<float>(kAudioLevel);
+ constexpr float kExpectedPreprocessedAudioLevel =
+ TestRenderPreProcessor::ProcessSample(kAudioLevelFloat);
+ ASSERT_NE(kAudioLevelFloat, kExpectedPreprocessedAudioLevel);
+
+ // Analyze a render stream frame.
+ FillFixedFrame(kAudioLevel, &frame);
+ ASSERT_EQ(AudioProcessing::Error::kNoError,
+ apm->ProcessReverseStream(&frame));
+ // Trigger a call to in EchoDetector::AnalyzeRenderAudio() via
+ // ProcessStream().
+ FillFixedFrame(kAudioLevel, &frame);
+ ASSERT_EQ(AudioProcessing::Error::kNoError, apm->ProcessStream(&frame));
+ // Regardless of how the call to in EchoDetector::AnalyzeRenderAudio() is
+ // triggered, the line below checks that the call has occurred. If not, the
+ // APM implementation may have changed and this test might need to be adapted.
+ ASSERT_TRUE(test_echo_detector->analyze_render_audio_called());
+ // Check that the data read in EchoDetector::AnalyzeRenderAudio() is that
+ // produced by the render pre-processor.
+ EXPECT_EQ(kExpectedPreprocessedAudioLevel,
+ test_echo_detector->last_render_audio_first_sample());
+}
+
} // namespace webrtc
diff --git a/modules/audio_processing/audio_processing_performance_unittest.cc b/modules/audio_processing/audio_processing_performance_unittest.cc
index 56615cb..df8d5fe 100644
--- a/modules/audio_processing/audio_processing_performance_unittest.cc
+++ b/modules/audio_processing/audio_processing_performance_unittest.cc
@@ -26,14 +26,6 @@
#include "test/gtest.h"
#include "test/testsupport/perf_test.h"
-// Check to verify that the define for the intelligibility enhancer is properly
-// set.
-#if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \
- (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \
- WEBRTC_INTELLIGIBILITY_ENHANCER != 1)
-#error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1"
-#endif
-
namespace webrtc {
namespace {
@@ -49,7 +41,6 @@
enum class SettingsType {
kDefaultApmDesktop,
kDefaultApmMobile,
- kDefaultApmDesktopAndIntelligibilityEnhancer,
kAllSubmodulesTurnedOff,
kDefaultApmDesktopWithoutDelayAgnostic,
kDefaultApmDesktopWithoutExtendedFilter
@@ -99,20 +90,6 @@
simulation_configs.push_back(SimulationConfig(sample_rate, settings));
}
}
-
-#if WEBRTC_INTELLIGIBILITY_ENHANCER == 1
- const SettingsType intelligibility_enhancer_settings[] = {
- SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer};
-
- const int intelligibility_enhancer_sample_rates[] = {8000, 16000, 32000,
- 48000};
-
- for (auto sample_rate : intelligibility_enhancer_sample_rates) {
- for (auto settings : intelligibility_enhancer_settings) {
- simulation_configs.push_back(SimulationConfig(sample_rate, settings));
- }
- }
-#endif
#endif
const SettingsType mobile_settings[] = {SettingsType::kDefaultApmMobile};
@@ -137,9 +114,6 @@
case SettingsType::kDefaultApmDesktop:
description = "DefaultApmDesktop";
break;
- case SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer:
- description = "DefaultApmDesktopAndIntelligibilityEnhancer";
- break;
case SettingsType::kAllSubmodulesTurnedOff:
description = "AllSubmodulesOff";
break;
@@ -538,16 +512,6 @@
apm_->SetExtraOptions(config);
break;
}
- case SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer: {
- Config config;
- config.Set<Intelligibility>(new Intelligibility(true));
- add_default_desktop_config(&config);
- apm_.reset(AudioProcessingBuilder().Create(config));
- ASSERT_TRUE(!!apm_);
- set_default_desktop_apm_runtime_settings(apm_.get());
- apm_->SetExtraOptions(config);
- break;
- }
case SettingsType::kAllSubmodulesTurnedOff: {
apm_.reset(AudioProcessingBuilder().Create());
ASSERT_TRUE(!!apm_);
diff --git a/modules/audio_processing/audio_processing_unittest.cc b/modules/audio_processing/audio_processing_unittest.cc
index 4b244fc..b04f89a 100644
--- a/modules/audio_processing/audio_processing_unittest.cc
+++ b/modules/audio_processing/audio_processing_unittest.cc
@@ -28,6 +28,7 @@
#include "modules/audio_processing/test/test_utils.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
+#include "rtc_base/fakeclock.h"
#include "rtc_base/gtest_prod_util.h"
#include "rtc_base/ignore_wundef.h"
#include "rtc_base/numerics/safe_conversions.h"
@@ -35,6 +36,7 @@
#include "rtc_base/protobuf_utils.h"
#include "rtc_base/refcountedobject.h"
#include "rtc_base/swap_queue.h"
+#include "rtc_base/system/arch.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/event_wrapper.h"
@@ -176,23 +178,26 @@
}
void EnableAllAPComponents(AudioProcessing* ap) {
+ AudioProcessing::Config apm_config = ap->GetConfig();
+ apm_config.echo_canceller.enabled = true;
#if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
- EXPECT_NOERR(ap->echo_control_mobile()->Enable(true));
+ apm_config.echo_canceller.mobile_mode = true;
EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveDigital));
EXPECT_NOERR(ap->gain_control()->Enable(true));
#elif defined(WEBRTC_AUDIOPROC_FLOAT_PROFILE)
+ apm_config.echo_canceller.mobile_mode = false;
EXPECT_NOERR(ap->echo_cancellation()->enable_drift_compensation(true));
EXPECT_NOERR(ap->echo_cancellation()->enable_metrics(true));
EXPECT_NOERR(ap->echo_cancellation()->enable_delay_logging(true));
- EXPECT_NOERR(ap->echo_cancellation()->Enable(true));
+ EXPECT_NOERR(ap->echo_cancellation()->set_suppression_level(
+ EchoCancellation::SuppressionLevel::kModerateSuppression));
EXPECT_NOERR(ap->gain_control()->set_mode(GainControl::kAdaptiveAnalog));
EXPECT_NOERR(ap->gain_control()->set_analog_level_limits(0, 255));
EXPECT_NOERR(ap->gain_control()->Enable(true));
#endif
- AudioProcessing::Config apm_config;
apm_config.high_pass_filter.enabled = true;
ap->ApplyConfig(apm_config);
@@ -1729,6 +1734,7 @@
}
void ApmTest::VerifyDebugDumpTest(Format format) {
+ rtc::ScopedFakeClock fake_clock;
const std::string in_filename = test::ResourcePath("ref03", "aecdump");
std::string format_string;
switch (format) {
@@ -2182,9 +2188,9 @@
// or generate a separate android reference.
#if defined(WEBRTC_ANDROID)
const int kHasVoiceCountOffset = 3;
- const int kHasVoiceCountNear = 4;
+ const int kHasVoiceCountNear = 8;
const int kMaxOutputAverageOffset = 9;
- const int kMaxOutputAverageNear = 9;
+ const int kMaxOutputAverageNear = 26;
#else
const int kHasVoiceCountOffset = 0;
const int kHasVoiceCountNear = kIntNear;
@@ -2796,6 +2802,25 @@
apm->ProcessReverseStream(&audio);
}
+TEST(ApmConfiguration, EnableCaptureAnalyzer) {
+ // Verify that apm uses a capture analyzer if one is provided.
+ auto mock_capture_analyzer_ptr =
+ new testing::NiceMock<test::MockCustomAudioAnalyzer>();
+ auto mock_capture_analyzer =
+ std::unique_ptr<CustomAudioAnalyzer>(mock_capture_analyzer_ptr);
+ rtc::scoped_refptr<AudioProcessing> apm =
+ AudioProcessingBuilder()
+ .SetCaptureAnalyzer(std::move(mock_capture_analyzer))
+ .Create();
+
+ AudioFrame audio;
+ audio.num_channels_ = 1;
+ SetFrameSampleRate(&audio, AudioProcessing::NativeRate::kSampleRate16kHz);
+
+ EXPECT_CALL(*mock_capture_analyzer_ptr, Analyze(testing::_)).Times(1);
+ apm->ProcessStream(&audio);
+}
+
TEST(ApmConfiguration, PreProcessingReceivesRuntimeSettings) {
auto mock_pre_processor_ptr =
new testing::NiceMock<test::MockCustomProcessing>();
diff --git a/modules/audio_processing/debug.proto b/modules/audio_processing/debug.proto
index f7f8d10..b19f7fe 100644
--- a/modules/audio_processing/debug.proto
+++ b/modules/audio_processing/debug.proto
@@ -14,6 +14,7 @@
optional int32 output_sample_rate = 7;
optional int32 reverse_output_sample_rate = 8;
optional int32 num_reverse_output_channels = 9;
+ optional int64 timestamp_ms = 10;
}
// May contain interleaved or deinterleaved data, but don't store both formats.
@@ -46,7 +47,6 @@
// Contains the configurations of various APM component. A Config message is
// added when any of the fields are changed.
message Config {
- // Next field number 19.
// Acoustic echo canceler.
optional bool aec_enabled = 1;
optional bool aec_delay_agnostic_enabled = 2;
@@ -72,11 +72,12 @@
// Semicolon-separated string containing experimental feature
// descriptions.
optional string experiments_description = 17;
- // Intelligibility Enhancer.
- optional bool intelligibility_enhancer_enabled = 18;
+ reserved 18; // Intelligibility enhancer enabled (deprecated).
// Pre amplifier.
optional bool pre_amplifier_enabled = 19;
optional float pre_amplifier_fixed_gain_factor = 20;
+
+ // Next field number 21.
}
message Event {
diff --git a/modules/audio_processing/echo_cancellation_impl.cc b/modules/audio_processing/echo_cancellation_impl.cc
index 15cd0db..9feaea7 100644
--- a/modules/audio_processing/echo_cancellation_impl.cc
+++ b/modules/audio_processing/echo_cancellation_impl.cc
@@ -109,7 +109,7 @@
crit_capture_(crit_capture),
drift_compensation_enabled_(false),
metrics_enabled_(false),
- suppression_level_(kModerateSuppression),
+ suppression_level_(kHighSuppression),
stream_drift_samples_(0),
was_stream_drift_set_(false),
stream_has_echo_(false),
diff --git a/modules/audio_processing/echo_cancellation_proxy.cc b/modules/audio_processing/echo_cancellation_proxy.cc
new file mode 100644
index 0000000..e8b1fbd
--- /dev/null
+++ b/modules/audio_processing/echo_cancellation_proxy.cc
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2018 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 "modules/audio_processing/echo_cancellation_proxy.h"
+
+namespace webrtc {
+
+EchoCancellationProxy::EchoCancellationProxy(
+ AudioProcessing* audio_processing,
+ EchoCancellation* echo_cancellation)
+ : audio_processing_(audio_processing),
+ echo_cancellation_(echo_cancellation) {}
+
+EchoCancellationProxy::~EchoCancellationProxy() = default;
+
+int EchoCancellationProxy::Enable(bool enable) {
+ // Change the config in APM to mirror the applied settings.
+ // TODO(bugs.webrtc.org/9535): Remove the call to EchoCancellation::Enable
+ // when APM starts taking the config into account.
+ AudioProcessing::Config apm_config = audio_processing_->GetConfig();
+ bool aec2_enabled = apm_config.echo_canceller.enabled &&
+ !apm_config.echo_canceller.mobile_mode;
+ if ((aec2_enabled && !enable) || (!aec2_enabled && enable)) {
+ apm_config.echo_canceller.enabled = enable;
+ apm_config.echo_canceller.mobile_mode = false;
+ audio_processing_->ApplyConfig(apm_config);
+ }
+ echo_cancellation_->Enable(enable);
+ return AudioProcessing::kNoError;
+}
+
+bool EchoCancellationProxy::is_enabled() const {
+ return echo_cancellation_->is_enabled();
+}
+
+int EchoCancellationProxy::enable_drift_compensation(bool enable) {
+ return echo_cancellation_->enable_drift_compensation(enable);
+}
+
+bool EchoCancellationProxy::is_drift_compensation_enabled() const {
+ return echo_cancellation_->is_drift_compensation_enabled();
+}
+
+void EchoCancellationProxy::set_stream_drift_samples(int drift) {
+ echo_cancellation_->set_stream_drift_samples(drift);
+}
+
+int EchoCancellationProxy::stream_drift_samples() const {
+ return echo_cancellation_->stream_drift_samples();
+}
+
+int EchoCancellationProxy::set_suppression_level(
+ EchoCancellation::SuppressionLevel level) {
+ return echo_cancellation_->set_suppression_level(level);
+}
+
+EchoCancellation::SuppressionLevel EchoCancellationProxy::suppression_level()
+ const {
+ return echo_cancellation_->suppression_level();
+}
+
+bool EchoCancellationProxy::stream_has_echo() const {
+ return echo_cancellation_->stream_has_echo();
+}
+int EchoCancellationProxy::enable_metrics(bool enable) {
+ return echo_cancellation_->enable_metrics(enable);
+}
+bool EchoCancellationProxy::are_metrics_enabled() const {
+ return echo_cancellation_->are_metrics_enabled();
+}
+int EchoCancellationProxy::GetMetrics(Metrics* metrics) {
+ return echo_cancellation_->GetMetrics(metrics);
+}
+int EchoCancellationProxy::enable_delay_logging(bool enable) {
+ return echo_cancellation_->enable_delay_logging(enable);
+}
+bool EchoCancellationProxy::is_delay_logging_enabled() const {
+ return echo_cancellation_->is_delay_logging_enabled();
+}
+int EchoCancellationProxy::GetDelayMetrics(int* median, int* std) {
+ return echo_cancellation_->GetDelayMetrics(median, std);
+}
+int EchoCancellationProxy::GetDelayMetrics(int* median,
+ int* std,
+ float* fraction_poor_delays) {
+ return echo_cancellation_->GetDelayMetrics(median, std, fraction_poor_delays);
+}
+
+struct AecCore* EchoCancellationProxy::aec_core() const {
+ return echo_cancellation_->aec_core();
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/echo_cancellation_proxy.h b/modules/audio_processing/echo_cancellation_proxy.h
new file mode 100644
index 0000000..f2d3017
--- /dev/null
+++ b/modules/audio_processing/echo_cancellation_proxy.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018 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 MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_PROXY_H_
+#define MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_PROXY_H_
+
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+// Class for temporarily redirecting AEC2 configuration to a new API.
+class EchoCancellationProxy : public EchoCancellation {
+ public:
+ EchoCancellationProxy(AudioProcessing* audio_processing,
+ EchoCancellation* echo_cancellation);
+ ~EchoCancellationProxy() override;
+
+ int Enable(bool enable) override;
+ bool is_enabled() const override;
+ int enable_drift_compensation(bool enable) override;
+ bool is_drift_compensation_enabled() const override;
+ void set_stream_drift_samples(int drift) override;
+ int stream_drift_samples() const override;
+ int set_suppression_level(SuppressionLevel level) override;
+ SuppressionLevel suppression_level() const override;
+ bool stream_has_echo() const override;
+ int enable_metrics(bool enable) override;
+ bool are_metrics_enabled() const override;
+ int GetMetrics(Metrics* metrics) override;
+ int enable_delay_logging(bool enable) override;
+ bool is_delay_logging_enabled() const override;
+ int GetDelayMetrics(int* median, int* std) override;
+ int GetDelayMetrics(int* median,
+ int* std,
+ float* fraction_poor_delays) override;
+ struct AecCore* aec_core() const override;
+
+ private:
+ AudioProcessing* audio_processing_;
+ EchoCancellation* echo_cancellation_;
+
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationProxy);
+};
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_PROXY_H_
diff --git a/modules/audio_processing/echo_control_mobile_impl.cc b/modules/audio_processing/echo_control_mobile_impl.cc
index 841364f..272da7a 100644
--- a/modules/audio_processing/echo_control_mobile_impl.cc
+++ b/modules/audio_processing/echo_control_mobile_impl.cc
@@ -113,7 +113,7 @@
: crit_render_(crit_render),
crit_capture_(crit_capture),
routing_mode_(kSpeakerphone),
- comfort_noise_enabled_(true),
+ comfort_noise_enabled_(false),
external_echo_path_(NULL) {
RTC_DCHECK(crit_render);
RTC_DCHECK(crit_capture);
diff --git a/modules/audio_processing/echo_control_mobile_proxy.cc b/modules/audio_processing/echo_control_mobile_proxy.cc
new file mode 100644
index 0000000..fd29834
--- /dev/null
+++ b/modules/audio_processing/echo_control_mobile_proxy.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018 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 "modules/audio_processing/echo_control_mobile_proxy.h"
+
+namespace webrtc {
+
+EchoControlMobileProxy::EchoControlMobileProxy(
+ AudioProcessing* audio_processing,
+ EchoControlMobile* echo_control_mobile)
+ : audio_processing_(audio_processing),
+ echo_control_mobile_(echo_control_mobile) {}
+
+EchoControlMobileProxy::~EchoControlMobileProxy() = default;
+
+int EchoControlMobileProxy::Enable(bool enable) {
+ // Change the config in APM to mirror the applied settings.
+ // TODO(bugs.webrtc.org/9535): Remove the call to EchoControlMobile::Enable
+ // when APM starts taking the config into account.
+ AudioProcessing::Config apm_config = audio_processing_->GetConfig();
+ bool aecm_enabled = apm_config.echo_canceller.enabled &&
+ apm_config.echo_canceller.mobile_mode;
+ if ((aecm_enabled && !enable) || (!aecm_enabled && enable)) {
+ apm_config.echo_canceller.enabled = enable;
+ apm_config.echo_canceller.mobile_mode = true;
+ audio_processing_->ApplyConfig(apm_config);
+ }
+ echo_control_mobile_->Enable(enable);
+ return AudioProcessing::kNoError;
+}
+
+bool EchoControlMobileProxy::is_enabled() const {
+ return echo_control_mobile_->is_enabled();
+}
+
+int EchoControlMobileProxy::set_routing_mode(RoutingMode mode) {
+ return echo_control_mobile_->set_routing_mode(mode);
+}
+
+EchoControlMobile::RoutingMode EchoControlMobileProxy::routing_mode() const {
+ return echo_control_mobile_->routing_mode();
+}
+
+int EchoControlMobileProxy::enable_comfort_noise(bool enable) {
+ return echo_control_mobile_->enable_comfort_noise(enable);
+}
+
+bool EchoControlMobileProxy::is_comfort_noise_enabled() const {
+ return echo_control_mobile_->is_comfort_noise_enabled();
+}
+
+int EchoControlMobileProxy::SetEchoPath(const void* echo_path,
+ size_t size_bytes) {
+ return echo_control_mobile_->SetEchoPath(echo_path, size_bytes);
+}
+
+int EchoControlMobileProxy::GetEchoPath(void* echo_path,
+ size_t size_bytes) const {
+ return echo_control_mobile_->GetEchoPath(echo_path, size_bytes);
+}
+
+} // namespace webrtc
diff --git a/modules/audio_processing/echo_control_mobile_proxy.h b/modules/audio_processing/echo_control_mobile_proxy.h
new file mode 100644
index 0000000..eb5908a
--- /dev/null
+++ b/modules/audio_processing/echo_control_mobile_proxy.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018 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 MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_PROXY_H_
+#define MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_PROXY_H_
+
+#include "modules/audio_processing/include/audio_processing.h"
+#include "rtc_base/constructormagic.h"
+#include "rtc_base/scoped_ref_ptr.h"
+
+namespace webrtc {
+
+// Class for temporarily redirecting AECM configuration to a new API.
+class EchoControlMobileProxy : public EchoControlMobile {
+ public:
+ EchoControlMobileProxy(AudioProcessing* audio_processing,
+ EchoControlMobile* echo_control_mobile);
+ ~EchoControlMobileProxy() override;
+
+ bool is_enabled() const override;
+ RoutingMode routing_mode() const override;
+ bool is_comfort_noise_enabled() const override;
+ int Enable(bool enable) override;
+ int set_routing_mode(RoutingMode mode) override;
+ int enable_comfort_noise(bool enable) override;
+ int SetEchoPath(const void* echo_path, size_t size_bytes) override;
+ int GetEchoPath(void* echo_path, size_t size_bytes) const override;
+
+ private:
+ AudioProcessing* audio_processing_;
+ EchoControlMobile* echo_control_mobile_;
+
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoControlMobileProxy);
+};
+} // namespace webrtc
+
+#endif // MODULES_AUDIO_PROCESSING_ECHO_CONTROL_MOBILE_PROXY_H_
diff --git a/modules/audio_processing/gain_control_for_experimental_agc.cc b/modules/audio_processing/gain_control_for_experimental_agc.cc
index d5d978c..4ab856c 100644
--- a/modules/audio_processing/gain_control_for_experimental_agc.cc
+++ b/modules/audio_processing/gain_control_for_experimental_agc.cc
@@ -12,6 +12,7 @@
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
+#include "rtc_base/atomicops.h"
#include "rtc_base/checks.h"
#include "rtc_base/criticalsection.h"
@@ -22,12 +23,11 @@
GainControlForExperimentalAgc::GainControlForExperimentalAgc(
GainControl* gain_control,
rtc::CriticalSection* crit_capture)
- : data_dumper_(new ApmDataDumper(instance_counter_)),
+ : data_dumper_(
+ new ApmDataDumper(rtc::AtomicOps::Increment(&instance_counter_))),
real_gain_control_(gain_control),
volume_(0),
- crit_capture_(crit_capture) {
- instance_counter_++;
-}
+ crit_capture_(crit_capture) {}
GainControlForExperimentalAgc::~GainControlForExperimentalAgc() = default;
@@ -43,14 +43,18 @@
rtc::CritScope cs_capture(crit_capture_);
data_dumper_->DumpRaw("experimental_gain_control_set_stream_analog_level", 1,
&level);
+ do_log_level_ = true;
volume_ = level;
return AudioProcessing::kNoError;
}
int GainControlForExperimentalAgc::stream_analog_level() {
rtc::CritScope cs_capture(crit_capture_);
- data_dumper_->DumpRaw("experimental_gain_control_stream_analog_level", 1,
- &volume_);
+ if (do_log_level_) {
+ data_dumper_->DumpRaw("experimental_gain_control_stream_analog_level", 1,
+ &volume_);
+ do_log_level_ = false;
+ }
return volume_;
}
diff --git a/modules/audio_processing/gain_control_for_experimental_agc.h b/modules/audio_processing/gain_control_for_experimental_agc.h
index 0894a0e..b20fbc9 100644
--- a/modules/audio_processing/gain_control_for_experimental_agc.h
+++ b/modules/audio_processing/gain_control_for_experimental_agc.h
@@ -68,6 +68,7 @@
GainControl* real_gain_control_;
int volume_;
rtc::CriticalSection* crit_capture_;
+ bool do_log_level_ = true;
static int instance_counter_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(GainControlForExperimentalAgc);
};
diff --git a/modules/audio_processing/gain_controller2.cc b/modules/audio_processing/gain_controller2.cc
index 6c0149a..fd4b411 100644
--- a/modules/audio_processing/gain_controller2.cc
+++ b/modules/audio_processing/gain_controller2.cc
@@ -41,15 +41,25 @@
void GainController2::Process(AudioBuffer* audio) {
AudioFrameView<float> float_frame(audio->channels_f(), audio->num_channels(),
audio->num_frames());
- adaptive_agc_.Process(float_frame);
+ if (adaptive_digital_mode_) {
+ adaptive_agc_.Process(float_frame);
+ }
fixed_gain_controller_.Process(float_frame);
}
+void GainController2::NotifyAnalogLevel(int level) {
+ if (analog_level_ != level && adaptive_digital_mode_) {
+ adaptive_agc_.Reset();
+ }
+ analog_level_ = level;
+}
+
void GainController2::ApplyConfig(
const AudioProcessing::Config::GainController2& config) {
RTC_DCHECK(Validate(config));
config_ = config;
fixed_gain_controller_.SetGain(config_.fixed_gain_db);
+ adaptive_digital_mode_ = config_.adaptive_digital_mode;
}
bool GainController2::Validate(
diff --git a/modules/audio_processing/gain_controller2.h b/modules/audio_processing/gain_controller2.h
index e2ca05e..b4727d0 100644
--- a/modules/audio_processing/gain_controller2.h
+++ b/modules/audio_processing/gain_controller2.h
@@ -33,6 +33,7 @@
void Initialize(int sample_rate_hz);
void Process(AudioBuffer* audio);
+ void NotifyAnalogLevel(int level);
void ApplyConfig(const AudioProcessing::Config::GainController2& config);
static bool Validate(const AudioProcessing::Config::GainController2& config);
@@ -45,6 +46,8 @@
FixedGainController fixed_gain_controller_;
AudioProcessing::Config::GainController2 config_;
AdaptiveAgc adaptive_agc_;
+ int analog_level_ = -1;
+ bool adaptive_digital_mode_ = true;
RTC_DISALLOW_COPY_AND_ASSIGN(GainController2);
};
diff --git a/modules/audio_processing/include/aec_dump.cc b/modules/audio_processing/include/aec_dump.cc
index c243b52..67809d0 100644
--- a/modules/audio_processing/include/aec_dump.cc
+++ b/modules/audio_processing/include/aec_dump.cc
@@ -32,8 +32,6 @@
hpf_enabled == other.hpf_enabled && ns_enabled == other.ns_enabled &&
ns_level == other.ns_level &&
transient_suppression_enabled == other.transient_suppression_enabled &&
- intelligibility_enhancer_enabled ==
- other.intelligibility_enhancer_enabled &&
noise_robust_agc_enabled == other.noise_robust_agc_enabled &&
pre_amplifier_enabled == other.pre_amplifier_enabled &&
pre_amplifier_fixed_gain_factor ==
diff --git a/modules/audio_processing/include/aec_dump.h b/modules/audio_processing/include/aec_dump.h
index 25c08b8..e32fa67 100644
--- a/modules/audio_processing/include/aec_dump.h
+++ b/modules/audio_processing/include/aec_dump.h
@@ -49,7 +49,6 @@
bool ns_enabled = false;
int ns_level = 0;
bool transient_suppression_enabled = false;
- bool intelligibility_enhancer_enabled = false;
bool noise_robust_agc_enabled = false;
bool pre_amplifier_enabled = false;
float pre_amplifier_fixed_gain_factor = 1.f;
@@ -76,7 +75,11 @@
virtual ~AecDump() = default;
// Logs Event::Type INIT message.
- virtual void WriteInitMessage(const ProcessingConfig& api_format) = 0;
+ virtual void WriteInitMessage(const ProcessingConfig& api_format,
+ int64_t time_now_ms) = 0;
+ RTC_DEPRECATED void WriteInitMessage(const ProcessingConfig& api_format) {
+ WriteInitMessage(api_format, 0);
+ }
// Logs Event::Type STREAM message. To log an input/output pair,
// call the AddCapture* and AddAudioProcessingState methods followed
diff --git a/modules/audio_processing/include/audio_processing.h b/modules/audio_processing/include/audio_processing.h
index 9d27f16..f05d7b6 100644
--- a/modules/audio_processing/include/audio_processing.h
+++ b/modules/audio_processing/include/audio_processing.h
@@ -34,7 +34,6 @@
#include "rtc_base/platform_file.h"
#include "rtc_base/refcount.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -54,12 +53,10 @@
class HighPassFilter;
class LevelEstimator;
class NoiseSuppression;
+class CustomAudioAnalyzer;
class CustomProcessing;
class VoiceDetection;
-// webrtc:8665, addedd temporarily to avoid breaking dependencies.
-typedef CustomProcessing PostProcessing;
-
// Use to enable the extended filter mode in the AEC, along with robustness
// measures around the reported system delays. It comes with a significant
// increase in AEC complexity, but is much more robust to unreliable reported
@@ -125,10 +122,10 @@
explicit ExperimentalAgc(bool enabled) : enabled(enabled) {}
ExperimentalAgc(bool enabled,
bool enabled_agc2_level_estimator,
- bool enabled_agc2_digital_adaptive)
+ bool digital_adaptive_disabled)
: enabled(enabled),
enabled_agc2_level_estimator(enabled_agc2_level_estimator),
- enabled_agc2_digital_adaptive(enabled_agc2_digital_adaptive) {}
+ digital_adaptive_disabled(digital_adaptive_disabled) {}
ExperimentalAgc(bool enabled, int startup_min_volume)
: enabled(enabled), startup_min_volume(startup_min_volume) {}
@@ -142,7 +139,7 @@
// Lowest microphone level that will be applied in response to clipping.
int clipped_level_min = kClippedLevelMin;
bool enabled_agc2_level_estimator = false;
- bool enabled_agc2_digital_adaptive = false;
+ bool digital_adaptive_disabled = false;
};
// Use to enable experimental noise suppression. It can be set in the
@@ -154,17 +151,6 @@
bool enabled;
};
-// Use to enable intelligibility enhancer in audio processing.
-//
-// Note: If enabled and the reverse stream has more than one output channel,
-// the reverse stream will become an upmixed mono signal.
-struct Intelligibility {
- Intelligibility() : enabled(false) {}
- explicit Intelligibility(bool enabled) : enabled(enabled) {}
- static const ConfigOptionID identifier = ConfigOptionID::kIntelligibility;
- bool enabled;
-};
-
// The Audio Processing Module (APM) provides a collection of voice processing
// components designed for real-time communications software.
//
@@ -253,6 +239,15 @@
// by changing the default values in the AudioProcessing::Config struct.
// The config is applied by passing the struct to the ApplyConfig method.
struct Config {
+ // TODO(bugs.webrtc.org/9535): Currently unused. Use this to determine AEC.
+ struct EchoCanceller {
+ bool enabled = false;
+ bool mobile_mode = false;
+ // Recommended not to use. Will be removed in the future.
+ // APM components are not fine-tuned for legacy suppression levels.
+ bool legacy_moderate_suppression_level = false;
+ } echo_canceller;
+
struct ResidualEchoDetector {
bool enabled = true;
} residual_echo_detector;
@@ -268,12 +263,15 @@
float fixed_gain_factor = 1.f;
} pre_amplifier;
- // Enables the next generation AGC functionality. This feature
- // replaces the standard methods of gain control in the previous
- // AGC. This functionality is currently only partially
- // implemented.
+ // Enables the next generation AGC functionality. This feature replaces the
+ // standard methods of gain control in the previous AGC. Enabling this
+ // submodule enables an adaptive digital AGC followed by a limiter. By
+ // setting |fixed_gain_db|, the limiter can be turned into a compressor that
+ // first applies a fixed gain. The adaptive digital AGC can be turned off by
+ // setting |adaptive_digital_mode=false|.
struct GainController2 {
bool enabled = false;
+ bool adaptive_digital_mode = true;
float fixed_gain_db = 0.f;
} gain_controller2;
@@ -667,6 +665,9 @@
// The AudioProcessingBuilder takes ownership of the echo_detector.
AudioProcessingBuilder& SetEchoDetector(
rtc::scoped_refptr<EchoDetector> echo_detector);
+ // The AudioProcessingBuilder takes ownership of the capture_analyzer.
+ AudioProcessingBuilder& SetCaptureAnalyzer(
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer);
// This creates an APM instance using the previously set components. Calling
// the Create function resets the AudioProcessingBuilder to its initial state.
AudioProcessing* Create();
@@ -677,6 +678,7 @@
std::unique_ptr<CustomProcessing> capture_post_processing_;
std::unique_ptr<CustomProcessing> render_pre_processing_;
rtc::scoped_refptr<EchoDetector> echo_detector_;
+ std::unique_ptr<CustomAudioAnalyzer> capture_analyzer_;
RTC_DISALLOW_COPY_AND_ASSIGN(AudioProcessingBuilder);
};
@@ -1010,6 +1012,19 @@
virtual ~NoiseSuppression() {}
};
+// Experimental interface for a custom analysis submodule.
+class CustomAudioAnalyzer {
+ public:
+ // (Re-) Initializes the submodule.
+ virtual void Initialize(int sample_rate_hz, int num_channels) = 0;
+ // Analyzes the given capture or render signal.
+ virtual void Analyze(const AudioBuffer* audio) = 0;
+ // Returns a string representation of the module state.
+ virtual std::string ToString() const = 0;
+
+ virtual ~CustomAudioAnalyzer() {}
+};
+
// Interface for a custom processing submodule.
class CustomProcessing {
public:
diff --git a/modules/audio_processing/include/config.h b/modules/audio_processing/include/config.h
index 9232b2e..398aab6 100644
--- a/modules/audio_processing/include/config.h
+++ b/modules/audio_processing/include/config.h
@@ -30,9 +30,9 @@
kDelayAgnostic,
kExperimentalAgc,
kExperimentalNs,
- kBeamforming, // Deprecated
- kIntelligibility,
- kEchoCanceller3, // Deprecated
+ kBeamforming, // Deprecated
+ kIntelligibility, // Deprecated
+ kEchoCanceller3, // Deprecated
kAecRefinedAdaptiveFilter,
kLevelControl // Deprecated
};
diff --git a/modules/audio_processing/include/mock_audio_processing.h b/modules/audio_processing/include/mock_audio_processing.h
index 9ceee10..2864e48 100644
--- a/modules/audio_processing/include/mock_audio_processing.h
+++ b/modules/audio_processing/include/mock_audio_processing.h
@@ -115,6 +115,14 @@
MOCK_CONST_METHOD0(ToString, std::string());
};
+class MockCustomAudioAnalyzer : public CustomAudioAnalyzer {
+ public:
+ virtual ~MockCustomAudioAnalyzer() {}
+ MOCK_METHOD2(Initialize, void(int sample_rate_hz, int num_channels));
+ MOCK_METHOD1(Analyze, void(const AudioBuffer* audio));
+ MOCK_CONST_METHOD0(ToString, std::string());
+};
+
class MockEchoControl : public EchoControl {
public:
virtual ~MockEchoControl() {}
diff --git a/modules/audio_processing/intelligibility/intelligibility_enhancer.cc b/modules/audio_processing/intelligibility/intelligibility_enhancer.cc
deleted file mode 100644
index 0f7b118..0000000
--- a/modules/audio_processing/intelligibility/intelligibility_enhancer.cc
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (c) 2014 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 "modules/audio_processing/intelligibility/intelligibility_enhancer.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <algorithm>
-#include <limits>
-#include <numeric>
-
-#include "common_audio/include/audio_util.h"
-#include "common_audio/window_generator.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/logging.h"
-#include "rtc_base/numerics/safe_minmax.h"
-
-namespace webrtc {
-
-namespace {
-
-const size_t kErbResolution = 2;
-const int kWindowSizeMs = 16;
-const int kChunkSizeMs = 10; // Size provided by APM.
-const float kClipFreqKhz = 0.2f;
-const float kKbdAlpha = 1.5f;
-const float kLambdaBot = -1.f; // Extreme values in bisection
-const float kLambdaTop = -1e-5f; // search for lamda.
-const float kVoiceProbabilityThreshold = 0.5f;
-// Number of chunks after voice activity which is still considered speech.
-const size_t kSpeechOffsetDelay = 10;
-const float kDecayRate = 0.995f; // Power estimation decay rate.
-const float kMaxRelativeGainChange = 0.005f;
-const float kRho = 0.0004f; // Default production and interpretation SNR.
-const float kPowerNormalizationFactor = 1.f / (1 << 30);
-const float kMaxActiveSNR = 128.f; // 21dB
-const float kMinInactiveSNR = 32.f; // 15dB
-const size_t kGainUpdatePeriod = 10u;
-
-// Returns dot product of vectors |a| and |b| with size |length|.
-float DotProduct(const float* a, const float* b, size_t length) {
- float ret = 0.f;
- for (size_t i = 0; i < length; ++i) {
- ret += a[i] * b[i];
- }
- return ret;
-}
-
-// Computes the power across ERB bands from the power spectral density |pow|.
-// Stores it in |result|.
-void MapToErbBands(const float* pow,
- const std::vector<std::vector<float>>& filter_bank,
- float* result) {
- for (size_t i = 0; i < filter_bank.size(); ++i) {
- RTC_DCHECK_GT(filter_bank[i].size(), 0);
- result[i] = kPowerNormalizationFactor *
- DotProduct(filter_bank[i].data(), pow, filter_bank[i].size());
- }
-}
-
-} // namespace
-
-IntelligibilityEnhancer::IntelligibilityEnhancer(int sample_rate_hz,
- size_t num_render_channels,
- size_t num_bands,
- size_t num_noise_bins)
- : freqs_(RealFourier::ComplexLength(
- RealFourier::FftOrder(sample_rate_hz * kWindowSizeMs / 1000))),
- num_noise_bins_(num_noise_bins),
- chunk_length_(static_cast<size_t>(sample_rate_hz * kChunkSizeMs / 1000)),
- bank_size_(GetBankSize(sample_rate_hz, kErbResolution)),
- sample_rate_hz_(sample_rate_hz),
- num_render_channels_(num_render_channels),
- clear_power_estimator_(freqs_, kDecayRate),
- noise_power_estimator_(num_noise_bins, kDecayRate),
- filtered_clear_pow_(bank_size_, 0.f),
- filtered_noise_pow_(num_noise_bins, 0.f),
- center_freqs_(bank_size_),
- capture_filter_bank_(CreateErbBank(num_noise_bins)),
- render_filter_bank_(CreateErbBank(freqs_)),
- gains_eq_(bank_size_),
- gain_applier_(freqs_, kMaxRelativeGainChange),
- audio_s16_(chunk_length_),
- chunks_since_voice_(kSpeechOffsetDelay),
- is_speech_(false),
- snr_(kMaxActiveSNR),
- is_active_(false),
- num_chunks_(0u),
- num_active_chunks_(0u),
- noise_estimation_buffer_(num_noise_bins),
- noise_estimation_queue_(kMaxNumNoiseEstimatesToBuffer,
- std::vector<float>(num_noise_bins),
- RenderQueueItemVerifier<float>(num_noise_bins)) {
- RTC_DCHECK_LE(kRho, 1.f);
-
- const size_t erb_index = static_cast<size_t>(
- ceilf(11.17f * logf((kClipFreqKhz + 0.312f) / (kClipFreqKhz + 14.6575f)) +
- 43.f));
- start_freq_ = std::max(static_cast<size_t>(1), erb_index * kErbResolution);
-
- size_t window_size = static_cast<size_t>(1) << RealFourier::FftOrder(freqs_);
- std::vector<float> kbd_window(window_size);
- WindowGenerator::KaiserBesselDerived(kKbdAlpha, window_size,
- kbd_window.data());
- render_mangler_.reset(new LappedTransform(
- num_render_channels_, num_render_channels_, chunk_length_,
- kbd_window.data(), window_size, window_size / 2, this));
-
- const size_t initial_delay = render_mangler_->initial_delay();
- for (size_t i = 0u; i < num_bands - 1; ++i) {
- high_bands_buffers_.push_back(std::unique_ptr<intelligibility::DelayBuffer>(
- new intelligibility::DelayBuffer(initial_delay, num_render_channels_)));
- }
-}
-
-IntelligibilityEnhancer::~IntelligibilityEnhancer() {
- // Don't rely on this log, since the destructor isn't called when the
- // app/tab is killed.
- if (num_chunks_ > 0) {
- RTC_LOG(LS_INFO) << "Intelligibility Enhancer was active for "
- << 100.f * static_cast<float>(num_active_chunks_) /
- num_chunks_
- << "% of the call.";
- } else {
- RTC_LOG(LS_INFO) << "Intelligibility Enhancer processed no chunk.";
- }
-}
-
-void IntelligibilityEnhancer::SetCaptureNoiseEstimate(std::vector<float> noise,
- float gain) {
- RTC_DCHECK_EQ(noise.size(), num_noise_bins_);
- for (auto& bin : noise) {
- bin *= gain;
- }
- // Disregarding return value since buffer overflow is acceptable, because it
- // is not critical to get each noise estimate.
- if (noise_estimation_queue_.Insert(&noise)) {
- };
-}
-
-void IntelligibilityEnhancer::ProcessRenderAudio(AudioBuffer* audio) {
- RTC_DCHECK_EQ(num_render_channels_, audio->num_channels());
- while (noise_estimation_queue_.Remove(&noise_estimation_buffer_)) {
- noise_power_estimator_.Step(noise_estimation_buffer_.data());
- }
- float* const* low_band = audio->split_channels_f(kBand0To8kHz);
- is_speech_ = IsSpeech(low_band[0]);
- render_mangler_->ProcessChunk(low_band, low_band);
- DelayHighBands(audio);
-}
-
-void IntelligibilityEnhancer::ProcessAudioBlock(
- const std::complex<float>* const* in_block,
- size_t in_channels,
- size_t frames,
- size_t /* out_channels */,
- std::complex<float>* const* out_block) {
- RTC_DCHECK_EQ(freqs_, frames);
- if (is_speech_) {
- clear_power_estimator_.Step(in_block[0]);
- }
- SnrBasedEffectActivation();
- ++num_chunks_;
- if (is_active_) {
- ++num_active_chunks_;
- if (num_chunks_ % kGainUpdatePeriod == 0) {
- MapToErbBands(clear_power_estimator_.power().data(), render_filter_bank_,
- filtered_clear_pow_.data());
- MapToErbBands(noise_power_estimator_.power().data(), capture_filter_bank_,
- filtered_noise_pow_.data());
- SolveForGainsGivenLambda(kLambdaTop, start_freq_, gains_eq_.data());
- const float power_target =
- std::accumulate(filtered_clear_pow_.data(),
- filtered_clear_pow_.data() + bank_size_, 0.f);
- const float power_top =
- DotProduct(gains_eq_.data(), filtered_clear_pow_.data(), bank_size_);
- SolveForGainsGivenLambda(kLambdaBot, start_freq_, gains_eq_.data());
- const float power_bot =
- DotProduct(gains_eq_.data(), filtered_clear_pow_.data(), bank_size_);
- if (power_target >= power_bot && power_target <= power_top) {
- SolveForLambda(power_target);
- UpdateErbGains();
- } // Else experiencing power underflow, so do nothing.
- }
- }
- for (size_t i = 0; i < in_channels; ++i) {
- gain_applier_.Apply(in_block[i], out_block[i]);
- }
-}
-
-void IntelligibilityEnhancer::SnrBasedEffectActivation() {
- const float* clear_psd = clear_power_estimator_.power().data();
- const float* noise_psd = noise_power_estimator_.power().data();
- const float clear_power = std::accumulate(clear_psd, clear_psd + freqs_, 0.f);
- const float noise_power = std::accumulate(noise_psd, noise_psd + freqs_, 0.f);
- snr_ = kDecayRate * snr_ +
- (1.f - kDecayRate) * clear_power /
- (noise_power + std::numeric_limits<float>::epsilon());
- if (is_active_) {
- if (snr_ > kMaxActiveSNR) {
- RTC_LOG(LS_INFO) << "Intelligibility Enhancer was deactivated at chunk "
- << num_chunks_;
- is_active_ = false;
- // Set the target gains to unity.
- float* gains = gain_applier_.target();
- for (size_t i = 0; i < freqs_; ++i) {
- gains[i] = 1.f;
- }
- }
- } else {
- if (snr_ < kMinInactiveSNR) {
- RTC_LOG(LS_INFO) << "Intelligibility Enhancer was activated at chunk "
- << num_chunks_;
- is_active_ = true;
- }
- }
-}
-
-void IntelligibilityEnhancer::SolveForLambda(float power_target) {
- const float kConvergeThresh = 0.001f; // TODO(ekmeyerson): Find best values
- const int kMaxIters = 100; // for these, based on experiments.
-
- const float reciprocal_power_target =
- 1.f / (power_target + std::numeric_limits<float>::epsilon());
- float lambda_bot = kLambdaBot;
- float lambda_top = kLambdaTop;
- float power_ratio = 2.f; // Ratio of achieved power to target power.
- int iters = 0;
- while (std::fabs(power_ratio - 1.f) > kConvergeThresh && iters <= kMaxIters) {
- const float lambda = (lambda_bot + lambda_top) / 2.f;
- SolveForGainsGivenLambda(lambda, start_freq_, gains_eq_.data());
- const float power =
- DotProduct(gains_eq_.data(), filtered_clear_pow_.data(), bank_size_);
- if (power < power_target) {
- lambda_bot = lambda;
- } else {
- lambda_top = lambda;
- }
- power_ratio = std::fabs(power * reciprocal_power_target);
- ++iters;
- }
-}
-
-void IntelligibilityEnhancer::UpdateErbGains() {
- // (ERB gain) = filterbank' * (freq gain)
- float* gains = gain_applier_.target();
- for (size_t i = 0; i < freqs_; ++i) {
- gains[i] = 0.f;
- for (size_t j = 0; j < bank_size_; ++j) {
- gains[i] += render_filter_bank_[j][i] * gains_eq_[j];
- }
- }
-}
-
-size_t IntelligibilityEnhancer::GetBankSize(int sample_rate,
- size_t erb_resolution) {
- float freq_limit = sample_rate / 2000.f;
- size_t erb_scale = static_cast<size_t>(ceilf(
- 11.17f * logf((freq_limit + 0.312f) / (freq_limit + 14.6575f)) + 43.f));
- return erb_scale * erb_resolution;
-}
-
-std::vector<std::vector<float>> IntelligibilityEnhancer::CreateErbBank(
- size_t num_freqs) {
- std::vector<std::vector<float>> filter_bank(bank_size_);
- size_t lf = 1, rf = 4;
-
- for (size_t i = 0; i < bank_size_; ++i) {
- float abs_temp = fabsf((i + 1.f) / static_cast<float>(kErbResolution));
- center_freqs_[i] = 676170.4f / (47.06538f - expf(0.08950404f * abs_temp));
- center_freqs_[i] -= 14678.49f;
- }
- float last_center_freq = center_freqs_[bank_size_ - 1];
- for (size_t i = 0; i < bank_size_; ++i) {
- center_freqs_[i] *= 0.5f * sample_rate_hz_ / last_center_freq;
- }
-
- for (size_t i = 0; i < bank_size_; ++i) {
- filter_bank[i].resize(num_freqs);
- }
-
- for (size_t i = 1; i <= bank_size_; ++i) {
- size_t lll = static_cast<size_t>(
- round(center_freqs_[rtc::SafeMax<size_t>(1, i - lf) - 1] * num_freqs /
- (0.5f * sample_rate_hz_)));
- size_t ll = static_cast<size_t>(
- round(center_freqs_[rtc::SafeMax<size_t>(1, i) - 1] * num_freqs /
- (0.5f * sample_rate_hz_)));
- lll = rtc::SafeClamp<size_t>(lll, 1, num_freqs) - 1;
- ll = rtc::SafeClamp<size_t>(ll, 1, num_freqs) - 1;
-
- size_t rrr = static_cast<size_t>(
- round(center_freqs_[rtc::SafeMin<size_t>(bank_size_, i + rf) - 1] *
- num_freqs / (0.5f * sample_rate_hz_)));
- size_t rr = static_cast<size_t>(
- round(center_freqs_[rtc::SafeMin<size_t>(bank_size_, i + 1) - 1] *
- num_freqs / (0.5f * sample_rate_hz_)));
- rrr = rtc::SafeClamp<size_t>(rrr, 1, num_freqs) - 1;
- rr = rtc::SafeClamp<size_t>(rr, 1, num_freqs) - 1;
-
- float step = ll == lll ? 0.f : 1.f / (ll - lll);
- float element = 0.f;
- for (size_t j = lll; j <= ll; ++j) {
- filter_bank[i - 1][j] = element;
- element += step;
- }
- step = rr == rrr ? 0.f : 1.f / (rrr - rr);
- element = 1.f;
- for (size_t j = rr; j <= rrr; ++j) {
- filter_bank[i - 1][j] = element;
- element -= step;
- }
- for (size_t j = ll; j <= rr; ++j) {
- filter_bank[i - 1][j] = 1.f;
- }
- }
-
- for (size_t i = 0; i < num_freqs; ++i) {
- float sum = 0.f;
- for (size_t j = 0; j < bank_size_; ++j) {
- sum += filter_bank[j][i];
- }
- for (size_t j = 0; j < bank_size_; ++j) {
- filter_bank[j][i] /= sum;
- }
- }
- return filter_bank;
-}
-
-void IntelligibilityEnhancer::SolveForGainsGivenLambda(float lambda,
- size_t start_freq,
- float* sols) {
- const float kMinPower = 1e-5f;
-
- const float* pow_x0 = filtered_clear_pow_.data();
- const float* pow_n0 = filtered_noise_pow_.data();
-
- for (size_t n = 0; n < start_freq; ++n) {
- sols[n] = 1.f;
- }
-
- // Analytic solution for optimal gains. See paper for derivation.
- for (size_t n = start_freq; n < bank_size_; ++n) {
- if (pow_x0[n] < kMinPower || pow_n0[n] < kMinPower) {
- sols[n] = 1.f;
- } else {
- const float gamma0 = 0.5f * kRho * pow_x0[n] * pow_n0[n] +
- lambda * pow_x0[n] * pow_n0[n] * pow_n0[n];
- const float beta0 =
- lambda * pow_x0[n] * (2.f - kRho) * pow_x0[n] * pow_n0[n];
- const float alpha0 =
- lambda * pow_x0[n] * (1.f - kRho) * pow_x0[n] * pow_x0[n];
- RTC_DCHECK_LT(alpha0, 0.f);
- // The quadratic equation should always have real roots, but to guard
- // against numerical errors we limit it to a minimum of zero.
- sols[n] = std::max(
- 0.f, (-beta0 - std::sqrt(std::max(
- 0.f, beta0 * beta0 - 4.f * alpha0 * gamma0))) /
- (2.f * alpha0));
- }
- }
-}
-
-bool IntelligibilityEnhancer::IsSpeech(const float* audio) {
- FloatToS16(audio, chunk_length_, audio_s16_.data());
- vad_.ProcessChunk(audio_s16_.data(), chunk_length_, sample_rate_hz_);
- if (vad_.last_voice_probability() > kVoiceProbabilityThreshold) {
- chunks_since_voice_ = 0;
- } else if (chunks_since_voice_ < kSpeechOffsetDelay) {
- ++chunks_since_voice_;
- }
- return chunks_since_voice_ < kSpeechOffsetDelay;
-}
-
-void IntelligibilityEnhancer::DelayHighBands(AudioBuffer* audio) {
- RTC_DCHECK_EQ(audio->num_bands(), high_bands_buffers_.size() + 1);
- for (size_t i = 0u; i < high_bands_buffers_.size(); ++i) {
- Band band = static_cast<Band>(i + 1);
- high_bands_buffers_[i]->Delay(audio->split_channels_f(band), chunk_length_);
- }
-}
-
-} // namespace webrtc
diff --git a/modules/audio_processing/intelligibility/intelligibility_enhancer.h b/modules/audio_processing/intelligibility/intelligibility_enhancer.h
deleted file mode 100644
index 3513092..0000000
--- a/modules/audio_processing/intelligibility/intelligibility_enhancer.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2014 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 MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_ENHANCER_H_
-#define MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_ENHANCER_H_
-
-#include <complex>
-#include <memory>
-#include <vector>
-
-#include "common_audio/channel_buffer.h"
-#include "common_audio/lapped_transform.h"
-#include "modules/audio_processing/audio_buffer.h"
-#include "modules/audio_processing/intelligibility/intelligibility_utils.h"
-#include "modules/audio_processing/render_queue_item_verifier.h"
-#include "modules/audio_processing/vad/voice_activity_detector.h"
-#include "rtc_base/swap_queue.h"
-
-namespace webrtc {
-
-// Speech intelligibility enhancement module. Reads render and capture
-// audio streams and modifies the render stream with a set of gains per
-// frequency bin to enhance speech against the noise background.
-// Details of the model and algorithm can be found in the original paper:
-// http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6882788
-class IntelligibilityEnhancer : public LappedTransform::Callback {
- public:
- IntelligibilityEnhancer(int sample_rate_hz,
- size_t num_render_channels,
- size_t num_bands,
- size_t num_noise_bins);
-
- ~IntelligibilityEnhancer() override;
-
- // Sets the capture noise magnitude spectrum estimate.
- void SetCaptureNoiseEstimate(std::vector<float> noise, float gain);
-
- // Reads chunk of speech in time domain and updates with modified signal.
- void ProcessRenderAudio(AudioBuffer* audio);
- bool active() const;
-
- protected:
- // All in frequency domain, receives input |in_block|, applies
- // intelligibility enhancement, and writes result to |out_block|.
- void ProcessAudioBlock(const std::complex<float>* const* in_block,
- size_t in_channels,
- size_t frames,
- size_t out_channels,
- std::complex<float>* const* out_block) override;
-
- private:
- FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, TestRenderUpdate);
- FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, TestErbCreation);
- FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, TestSolveForGains);
- FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest,
- TestNoiseGainHasExpectedResult);
- FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest,
- TestAllBandsHaveSameDelay);
-
- // Updates the SNR estimation and enables or disables this component using a
- // hysteresis.
- void SnrBasedEffectActivation();
-
- // Bisection search for optimal |lambda|.
- void SolveForLambda(float power_target);
-
- // Transforms freq gains to ERB gains.
- void UpdateErbGains();
-
- // Returns number of ERB filters.
- static size_t GetBankSize(int sample_rate, size_t erb_resolution);
-
- // Initializes ERB filterbank.
- std::vector<std::vector<float>> CreateErbBank(size_t num_freqs);
-
- // Analytically solves quadratic for optimal gains given |lambda|.
- // Negative gains are set to 0. Stores the results in |sols|.
- void SolveForGainsGivenLambda(float lambda, size_t start_freq, float* sols);
-
- // Returns true if the audio is speech.
- bool IsSpeech(const float* audio);
-
- // Delays the high bands to compensate for the processing delay in the low
- // band.
- void DelayHighBands(AudioBuffer* audio);
-
- static const size_t kMaxNumNoiseEstimatesToBuffer = 5;
-
- const size_t freqs_; // Num frequencies in frequency domain.
- const size_t num_noise_bins_;
- const size_t chunk_length_; // Chunk size in samples.
- const size_t bank_size_; // Num ERB filters.
- const int sample_rate_hz_;
- const size_t num_render_channels_;
-
- intelligibility::PowerEstimator<std::complex<float>> clear_power_estimator_;
- intelligibility::PowerEstimator<float> noise_power_estimator_;
- std::vector<float> filtered_clear_pow_;
- std::vector<float> filtered_noise_pow_;
- std::vector<float> center_freqs_;
- std::vector<std::vector<float>> capture_filter_bank_;
- std::vector<std::vector<float>> render_filter_bank_;
- size_t start_freq_;
-
- std::vector<float> gains_eq_; // Pre-filter modified gains.
- intelligibility::GainApplier gain_applier_;
-
- std::unique_ptr<LappedTransform> render_mangler_;
-
- VoiceActivityDetector vad_;
- std::vector<int16_t> audio_s16_;
- size_t chunks_since_voice_;
- bool is_speech_;
- float snr_;
- bool is_active_;
-
- unsigned long int num_chunks_;
- unsigned long int num_active_chunks_;
-
- std::vector<float> noise_estimation_buffer_;
- SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>
- noise_estimation_queue_;
-
- std::vector<std::unique_ptr<intelligibility::DelayBuffer>>
- high_bands_buffers_;
-};
-
-} // namespace webrtc
-
-#endif // MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_ENHANCER_H_
diff --git a/modules/audio_processing/intelligibility/intelligibility_enhancer_unittest.cc b/modules/audio_processing/intelligibility/intelligibility_enhancer_unittest.cc
deleted file mode 100644
index 98a8dae..0000000
--- a/modules/audio_processing/intelligibility/intelligibility_enhancer_unittest.cc
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * Copyright (c) 2015 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 <math.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <memory>
-#include <vector>
-
-#include "api/array_view.h"
-#include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "modules/audio_processing/audio_buffer.h"
-#include "modules/audio_processing/intelligibility/intelligibility_enhancer.h"
-#include "modules/audio_processing/noise_suppression_impl.h"
-#include "modules/audio_processing/test/audio_buffer_tools.h"
-#include "modules/audio_processing/test/bitexactness_tools.h"
-#include "rtc_base/arraysize.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-
-namespace {
-
-// Target output for ERB create test. Generated with matlab.
-const float kTestCenterFreqs[] = {
- 14.5213f, 29.735f, 45.6781f, 62.3884f, 79.9058f, 98.2691f, 117.521f,
- 137.708f, 158.879f, 181.084f, 204.378f, 228.816f, 254.459f, 281.371f,
- 309.618f, 339.273f, 370.411f, 403.115f, 437.469f, 473.564f, 511.497f,
- 551.371f, 593.293f, 637.386f, 683.77f, 732.581f, 783.96f, 838.06f,
- 895.046f, 955.09f, 1018.38f, 1085.13f, 1155.54f, 1229.85f, 1308.32f,
- 1391.22f, 1478.83f, 1571.5f, 1669.55f, 1773.37f, 1883.37f, 2000.f};
-const float kTestFilterBank[][33] = {
- {0.2f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.2f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.2f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.2f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.2f, 0.25f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.25f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.25f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.25f, 0.25f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.25f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.25f, 0.142857f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.25f, 0.285714f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.285714f, 0.142857f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.285714f, 0.285714f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.285714f, 0.142857f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.285714f, 0.285714f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f, 0.142857f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f, 0.285714f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f, 0.142857f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f, 0.285714f, 0.157895f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f, 0.210526f, 0.117647f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f, 0.315789f, 0.176471f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.315789f, 0.352941f, 0.142857f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.352941f, 0.285714f,
- 0.157895f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.285714f,
- 0.210526f, 0.111111f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.285714f, 0.315789f, 0.222222f, 0.111111f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.315789f, 0.333333f, 0.222222f, 0.111111f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.333333f, 0.333333f, 0.222222f, 0.111111f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.333333f, 0.333333f, 0.222222f, 0.111111f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.333333f, 0.333333f, 0.222222f, 0.111111f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.333333f, 0.333333f, 0.222222f,
- 0.108108f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.333333f, 0.333333f,
- 0.243243f, 0.153846f, 0.0833333f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.333333f,
- 0.324324f, 0.230769f, 0.166667f, 0.0909091f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.324324f, 0.307692f, 0.25f, 0.181818f, 0.0833333f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.307692f, 0.333333f,
- 0.363636f, 0.25f, 0.151515f, 0.0793651f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.166667f, 0.363636f, 0.333333f, 0.242424f,
- 0.190476f, 0.133333f, 0.0689655f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.333333f, 0.30303f, 0.253968f, 0.2f, 0.137931f,
- 0.0714286f, 0.f, 0.f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.30303f, 0.31746f, 0.333333f, 0.275862f, 0.214286f,
- 0.125f, 0.0655738f, 0.f, 0.f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.15873f, 0.333333f, 0.344828f, 0.357143f,
- 0.25f, 0.196721f, 0.137931f, 0.0816327f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.172414f, 0.357143f,
- 0.3125f, 0.245902f, 0.172414f, 0.102041f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.3125f, 0.327869f, 0.344828f, 0.204082f, 0.f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.163934f, 0.344828f, 0.408163f, 0.5f},
- {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.204082f, 0.5f}};
-static_assert(arraysize(kTestCenterFreqs) == arraysize(kTestFilterBank),
- "Test filterbank badly initialized.");
-
-// Target output for gain solving test. Generated with matlab.
-const size_t kTestStartFreq = 12; // Lowest integral frequency for ERBs.
-const float kTestZeroVar = 1.f;
-const float kTestNonZeroVarLambdaTop[] = {
- 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f,
- 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
-static_assert(arraysize(kTestCenterFreqs) ==
- arraysize(kTestNonZeroVarLambdaTop),
- "Power test data badly initialized.");
-const float kMaxTestError = 0.005f;
-
-// Enhancer initialization parameters.
-const int kSamples = 10000;
-const int kSampleRate = 4000;
-const int kNumChannels = 1;
-const int kFragmentSize = kSampleRate / 100;
-const size_t kNumNoiseBins = 129;
-const size_t kNumBands = 1;
-
-// Number of frames to process in the bitexactness tests.
-const size_t kNumFramesToProcess = 1000;
-
-int IntelligibilityEnhancerSampleRate(int sample_rate_hz) {
- return (sample_rate_hz > AudioProcessing::kSampleRate16kHz
- ? AudioProcessing::kSampleRate16kHz
- : sample_rate_hz);
-}
-
-// Process one frame of data and produce the output.
-void ProcessOneFrame(int sample_rate_hz,
- AudioBuffer* render_audio_buffer,
- AudioBuffer* capture_audio_buffer,
- NoiseSuppressionImpl* noise_suppressor,
- IntelligibilityEnhancer* intelligibility_enhancer) {
- if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
- render_audio_buffer->SplitIntoFrequencyBands();
- capture_audio_buffer->SplitIntoFrequencyBands();
- }
-
- intelligibility_enhancer->ProcessRenderAudio(render_audio_buffer);
-
- noise_suppressor->AnalyzeCaptureAudio(capture_audio_buffer);
- noise_suppressor->ProcessCaptureAudio(capture_audio_buffer);
-
- intelligibility_enhancer->SetCaptureNoiseEstimate(
- noise_suppressor->NoiseEstimate(), 0);
-
- if (sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
- render_audio_buffer->MergeFrequencyBands();
- }
-}
-
-// Processes a specified amount of frames, verifies the results and reports
-// any errors.
-void RunBitexactnessTest(int sample_rate_hz,
- size_t num_channels,
- rtc::ArrayView<const float> output_reference) {
- const StreamConfig render_config(sample_rate_hz, num_channels, false);
- AudioBuffer render_buffer(
- render_config.num_frames(), render_config.num_channels(),
- render_config.num_frames(), render_config.num_channels(),
- render_config.num_frames());
- test::InputAudioFile render_file(
- test::GetApmRenderTestVectorFileName(sample_rate_hz));
- std::vector<float> render_input(render_buffer.num_frames() *
- render_buffer.num_channels());
-
- const StreamConfig capture_config(sample_rate_hz, num_channels, false);
- AudioBuffer capture_buffer(
- capture_config.num_frames(), capture_config.num_channels(),
- capture_config.num_frames(), capture_config.num_channels(),
- capture_config.num_frames());
- test::InputAudioFile capture_file(
- test::GetApmCaptureTestVectorFileName(sample_rate_hz));
- std::vector<float> capture_input(render_buffer.num_frames() *
- capture_buffer.num_channels());
-
- rtc::CriticalSection crit_capture;
- NoiseSuppressionImpl noise_suppressor(&crit_capture);
- noise_suppressor.Initialize(capture_config.num_channels(), sample_rate_hz);
- noise_suppressor.Enable(true);
-
- IntelligibilityEnhancer intelligibility_enhancer(
- IntelligibilityEnhancerSampleRate(sample_rate_hz),
- render_config.num_channels(), kNumBands,
- NoiseSuppressionImpl::num_noise_bins());
-
- for (size_t frame_no = 0u; frame_no < kNumFramesToProcess; ++frame_no) {
- ReadFloatSamplesFromStereoFile(render_buffer.num_frames(),
- render_buffer.num_channels(), &render_file,
- render_input);
- ReadFloatSamplesFromStereoFile(capture_buffer.num_frames(),
- capture_buffer.num_channels(), &capture_file,
- capture_input);
-
- test::CopyVectorToAudioBuffer(render_config, render_input, &render_buffer);
- test::CopyVectorToAudioBuffer(capture_config, capture_input,
- &capture_buffer);
-
- ProcessOneFrame(sample_rate_hz, &render_buffer, &capture_buffer,
- &noise_suppressor, &intelligibility_enhancer);
- }
-
- // Extract and verify the test results.
- std::vector<float> render_output;
- test::ExtractVectorFromAudioBuffer(render_config, &render_buffer,
- &render_output);
-
- const float kElementErrorBound = 1.f / static_cast<float>(1 << 15);
-
- // Compare the output with the reference. Only the first values of the output
- // from last frame processed are compared in order not having to specify all
- // preceeding frames as testvectors. As the algorithm being tested has a
- // memory, testing only the last frame implicitly also tests the preceeding
- // frames.
- EXPECT_TRUE(test::VerifyDeinterleavedArray(
- render_buffer.num_frames(), render_config.num_channels(),
- output_reference, render_output, kElementErrorBound));
-}
-
-float float_rand() {
- return std::rand() * 2.f / RAND_MAX - 1;
-}
-
-} // namespace
-
-class IntelligibilityEnhancerTest : public ::testing::Test {
- protected:
- IntelligibilityEnhancerTest()
- : clear_buffer_(kFragmentSize,
- kNumChannels,
- kFragmentSize,
- kNumChannels,
- kFragmentSize),
- stream_config_(kSampleRate, kNumChannels),
- clear_data_(kSamples),
- noise_data_(kNumNoiseBins),
- orig_data_(kSamples) {
- std::srand(1);
- enh_.reset(new IntelligibilityEnhancer(kSampleRate, kNumChannels, kNumBands,
- kNumNoiseBins));
- }
-
- bool CheckUpdate() {
- enh_.reset(new IntelligibilityEnhancer(kSampleRate, kNumChannels, kNumBands,
- kNumNoiseBins));
- float* clear_cursor = clear_data_.data();
- for (int i = 0; i < kSamples; i += kFragmentSize) {
- enh_->SetCaptureNoiseEstimate(noise_data_, 1);
- clear_buffer_.CopyFrom(&clear_cursor, stream_config_);
- enh_->ProcessRenderAudio(&clear_buffer_);
- clear_buffer_.CopyTo(stream_config_, &clear_cursor);
- clear_cursor += kFragmentSize;
- }
- for (int i = initial_delay_; i < kSamples; i++) {
- if (std::fabs(clear_data_[i] - orig_data_[i - initial_delay_]) >
- kMaxTestError) {
- return true;
- }
- }
- return false;
- }
-
- std::unique_ptr<IntelligibilityEnhancer> enh_;
- // Render clean speech buffer.
- AudioBuffer clear_buffer_;
- StreamConfig stream_config_;
- std::vector<float> clear_data_;
- std::vector<float> noise_data_;
- std::vector<float> orig_data_;
- size_t initial_delay_;
-};
-
-// For each class of generated data, tests that render stream is updated when
-// it should be.
-TEST_F(IntelligibilityEnhancerTest, TestRenderUpdate) {
- initial_delay_ = enh_->render_mangler_->initial_delay();
- std::fill(noise_data_.begin(), noise_data_.end(), 0.f);
- std::fill(orig_data_.begin(), orig_data_.end(), 0.f);
- std::fill(clear_data_.begin(), clear_data_.end(), 0.f);
- EXPECT_FALSE(CheckUpdate());
- std::generate(clear_data_.begin(), clear_data_.end(), float_rand);
- orig_data_ = clear_data_;
- EXPECT_FALSE(CheckUpdate());
- std::generate(clear_data_.begin(), clear_data_.end(), float_rand);
- orig_data_ = clear_data_;
- std::generate(noise_data_.begin(), noise_data_.end(), float_rand);
- FloatToFloatS16(noise_data_.data(), noise_data_.size(), noise_data_.data());
- EXPECT_TRUE(CheckUpdate());
-}
-
-// Tests ERB bank creation, comparing against matlab output.
-TEST_F(IntelligibilityEnhancerTest, TestErbCreation) {
- ASSERT_EQ(arraysize(kTestCenterFreqs), enh_->bank_size_);
- for (size_t i = 0; i < enh_->bank_size_; ++i) {
- EXPECT_NEAR(kTestCenterFreqs[i], enh_->center_freqs_[i], kMaxTestError);
- ASSERT_EQ(arraysize(kTestFilterBank[0]), enh_->freqs_);
- for (size_t j = 0; j < enh_->freqs_; ++j) {
- EXPECT_NEAR(kTestFilterBank[i][j], enh_->render_filter_bank_[i][j],
- kMaxTestError);
- }
- }
-}
-
-// Tests analytic solution for optimal gains, comparing
-// against matlab output.
-TEST_F(IntelligibilityEnhancerTest, TestSolveForGains) {
- ASSERT_EQ(kTestStartFreq, enh_->start_freq_);
- std::vector<float> sols(enh_->bank_size_);
- float lambda = -0.001f;
- for (size_t i = 0; i < enh_->bank_size_; i++) {
- enh_->filtered_clear_pow_[i] = 0.f;
- enh_->filtered_noise_pow_[i] = 0.f;
- }
- enh_->SolveForGainsGivenLambda(lambda, enh_->start_freq_, sols.data());
- for (size_t i = 0; i < enh_->bank_size_; i++) {
- EXPECT_NEAR(kTestZeroVar, sols[i], kMaxTestError);
- }
- for (size_t i = 0; i < enh_->bank_size_; i++) {
- enh_->filtered_clear_pow_[i] = static_cast<float>(i + 1);
- enh_->filtered_noise_pow_[i] = static_cast<float>(enh_->bank_size_ - i);
- }
- enh_->SolveForGainsGivenLambda(lambda, enh_->start_freq_, sols.data());
- for (size_t i = 0; i < enh_->bank_size_; i++) {
- EXPECT_NEAR(kTestNonZeroVarLambdaTop[i], sols[i], kMaxTestError);
- }
- lambda = -1.f;
- enh_->SolveForGainsGivenLambda(lambda, enh_->start_freq_, sols.data());
- for (size_t i = 0; i < enh_->bank_size_; i++) {
- EXPECT_NEAR(kTestNonZeroVarLambdaTop[i], sols[i], kMaxTestError);
- }
-}
-
-TEST_F(IntelligibilityEnhancerTest, TestNoiseGainHasExpectedResult) {
- const float kGain = 2.f;
- const float kTolerance = 0.007f;
- std::vector<float> noise(kNumNoiseBins);
- std::vector<float> noise_psd(kNumNoiseBins);
- std::generate(noise.begin(), noise.end(), float_rand);
- for (size_t i = 0; i < kNumNoiseBins; ++i) {
- noise_psd[i] = kGain * kGain * noise[i] * noise[i];
- }
- float* clear_cursor = clear_data_.data();
- for (size_t i = 0; i < kNumFramesToProcess; ++i) {
- enh_->SetCaptureNoiseEstimate(noise, kGain);
- clear_buffer_.CopyFrom(&clear_cursor, stream_config_);
- enh_->ProcessRenderAudio(&clear_buffer_);
- }
- const std::vector<float>& estimated_psd =
- enh_->noise_power_estimator_.power();
- for (size_t i = 0; i < kNumNoiseBins; ++i) {
- EXPECT_LT(std::abs(estimated_psd[i] - noise_psd[i]) / noise_psd[i],
- kTolerance);
- }
-}
-
-TEST_F(IntelligibilityEnhancerTest, TestAllBandsHaveSameDelay) {
- const int kTestSampleRate = AudioProcessing::kSampleRate32kHz;
- const int kTestSplitRate = AudioProcessing::kSampleRate16kHz;
- const size_t kTestNumBands =
- rtc::CheckedDivExact(kTestSampleRate, kTestSplitRate);
- const size_t kTestFragmentSize = rtc::CheckedDivExact(kTestSampleRate, 100);
- const size_t kTestSplitFragmentSize =
- rtc::CheckedDivExact(kTestSplitRate, 100);
- enh_.reset(new IntelligibilityEnhancer(kTestSplitRate, kNumChannels,
- kTestNumBands, kNumNoiseBins));
- size_t initial_delay = enh_->render_mangler_->initial_delay();
- std::vector<float> rand_gen_buf(kTestFragmentSize);
- AudioBuffer original_buffer(kTestFragmentSize, kNumChannels,
- kTestFragmentSize, kNumChannels,
- kTestFragmentSize);
- AudioBuffer audio_buffer(kTestFragmentSize, kNumChannels, kTestFragmentSize,
- kNumChannels, kTestFragmentSize);
- for (size_t i = 0u; i < kTestNumBands; ++i) {
- std::generate(rand_gen_buf.begin(), rand_gen_buf.end(), float_rand);
- original_buffer.split_data_f()->SetDataForTesting(rand_gen_buf.data(),
- rand_gen_buf.size());
- audio_buffer.split_data_f()->SetDataForTesting(rand_gen_buf.data(),
- rand_gen_buf.size());
- }
- enh_->ProcessRenderAudio(&audio_buffer);
- for (size_t i = 0u; i < kTestNumBands; ++i) {
- const float* original_ptr = original_buffer.split_bands_const_f(0)[i];
- const float* audio_ptr = audio_buffer.split_bands_const_f(0)[i];
- for (size_t j = initial_delay; j < kTestSplitFragmentSize; ++j) {
- EXPECT_LT(std::fabs(original_ptr[j - initial_delay] - audio_ptr[j]),
- kMaxTestError);
- }
- }
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Mono8kHz) {
- const float kOutputReference[] = {-0.001892f, -0.003296f, -0.001953f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate8kHz, 1, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Mono16kHz) {
- const float kOutputReference[] = {-0.000977f, -0.003296f, -0.002441f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate16kHz, 1, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Mono32kHz) {
- const float kOutputReference[] = {0.003021f, -0.011780f, -0.008209f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate32kHz, 1, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Mono48kHz) {
- const float kOutputReference[] = {-0.027696f, -0.026253f, -0.018001f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate48kHz, 1, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Stereo8kHz) {
- const float kOutputReference[] = {0.021454f, 0.035919f, 0.026428f,
- -0.000641f, 0.000366f, 0.000641f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate8kHz, 2, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Stereo16kHz) {
- const float kOutputReference[] = {0.021362f, 0.035736f, 0.023895f,
- -0.001404f, -0.001465f, 0.000549f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate16kHz, 2, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Stereo32kHz) {
- const float kOutputReference[] = {0.030641f, 0.027406f, 0.028321f,
- -0.001343f, -0.004578f, 0.000977f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate32kHz, 2, kOutputReference);
-}
-
-TEST(IntelligibilityEnhancerBitExactnessTest, DISABLED_Stereo48kHz) {
- const float kOutputReference[] = {-0.009276f, -0.001601f, -0.008255f,
- -0.012975f, -0.015940f, -0.017820f};
-
- RunBitexactnessTest(AudioProcessing::kSampleRate48kHz, 2, kOutputReference);
-}
-
-} // namespace webrtc
diff --git a/modules/audio_processing/intelligibility/intelligibility_utils.cc b/modules/audio_processing/intelligibility/intelligibility_utils.cc
deleted file mode 100644
index b606d95..0000000
--- a/modules/audio_processing/intelligibility/intelligibility_utils.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2014 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 "modules/audio_processing/intelligibility/intelligibility_utils.h"
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <algorithm>
-#include <limits>
-
-#include "rtc_base/numerics/safe_minmax.h"
-
-namespace webrtc {
-
-namespace intelligibility {
-
-namespace {
-
-const float kMinFactor = 0.01f;
-const float kMaxFactor = 100.f;
-
-// Return |current| changed towards |target|, with the relative change being at
-// most |limit|.
-float UpdateFactor(float target, float current, float limit) {
- const float gain = target / (current + std::numeric_limits<float>::epsilon());
- const float clamped_gain = rtc::SafeClamp(gain, 1 - limit, 1 + limit);
- return rtc::SafeClamp(current * clamped_gain, kMinFactor, kMaxFactor);
-}
-
-} // namespace
-
-template <typename T>
-PowerEstimator<T>::PowerEstimator(size_t num_freqs, float decay)
- : power_(num_freqs, 0.f), decay_(decay) {}
-
-template <typename T>
-void PowerEstimator<T>::Step(const T* data) {
- for (size_t i = 0; i < power_.size(); ++i) {
- power_[i] = decay_ * power_[i] +
- (1.f - decay_) * std::abs(data[i]) * std::abs(data[i]);
- }
-}
-
-template class PowerEstimator<float>;
-template class PowerEstimator<std::complex<float>>;
-
-GainApplier::GainApplier(size_t freqs, float relative_change_limit)
- : num_freqs_(freqs),
- relative_change_limit_(relative_change_limit),
- target_(freqs, 1.f),
- current_(freqs, 1.f) {}
-
-GainApplier::~GainApplier() {}
-
-void GainApplier::Apply(const std::complex<float>* in_block,
- std::complex<float>* out_block) {
- for (size_t i = 0; i < num_freqs_; ++i) {
- current_[i] = UpdateFactor(target_[i], current_[i], relative_change_limit_);
- out_block[i] = sqrtf(fabsf(current_[i])) * in_block[i];
- }
-}
-
-DelayBuffer::DelayBuffer(size_t delay, size_t num_channels)
- : buffer_(num_channels, std::vector<float>(delay, 0.f)), read_index_(0u) {}
-
-DelayBuffer::~DelayBuffer() {}
-
-void DelayBuffer::Delay(float* const* data, size_t length) {
- size_t sample_index = read_index_;
- for (size_t i = 0u; i < buffer_.size(); ++i) {
- sample_index = read_index_;
- for (size_t j = 0u; j < length; ++j) {
- float swap = data[i][j];
- data[i][j] = buffer_[i][sample_index];
- buffer_[i][sample_index] = swap;
- if (++sample_index == buffer_.size()) {
- sample_index = 0u;
- }
- }
- }
- read_index_ = sample_index;
-}
-
-} // namespace intelligibility
-
-} // namespace webrtc
diff --git a/modules/audio_processing/intelligibility/intelligibility_utils.h b/modules/audio_processing/intelligibility/intelligibility_utils.h
deleted file mode 100644
index 4dc17d5..0000000
--- a/modules/audio_processing/intelligibility/intelligibility_utils.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2014 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 MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_
-#define MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_
-
-#include <complex>
-#include <vector>
-
-namespace webrtc {
-
-namespace intelligibility {
-
-// Internal helper for computing the power of a stream of arrays.
-// The result is an array of power per position: the i-th power is the power of
-// the stream of data on the i-th positions in the input arrays.
-template <typename T>
-class PowerEstimator {
- public:
- // Construct an instance for the given input array length (|freqs|), with the
- // appropriate parameters. |decay| is the forgetting factor.
- PowerEstimator(size_t freqs, float decay);
-
- // Add a new data point to the series.
- void Step(const T* data);
-
- // The current power array.
- const std::vector<float>& power() { return power_; };
-
- private:
- // The current power array.
- std::vector<float> power_;
-
- const float decay_;
-};
-
-// Helper class for smoothing gain changes. On each application step, the
-// currently used gains are changed towards a set of settable target gains,
-// constrained by a limit on the relative changes.
-class GainApplier {
- public:
- GainApplier(size_t freqs, float relative_change_limit);
-
- ~GainApplier();
-
- // Copy |in_block| to |out_block|, multiplied by the current set of gains,
- // and step the current set of gains towards the target set.
- void Apply(const std::complex<float>* in_block,
- std::complex<float>* out_block);
-
- // Return the current target gain set. Modify this array to set the targets.
- float* target() { return target_.data(); }
-
- private:
- const size_t num_freqs_;
- const float relative_change_limit_;
- std::vector<float> target_;
- std::vector<float> current_;
-};
-
-// Helper class to delay a signal by an integer number of samples.
-class DelayBuffer {
- public:
- DelayBuffer(size_t delay, size_t num_channels);
-
- ~DelayBuffer();
-
- void Delay(float* const* data, size_t length);
-
- private:
- std::vector<std::vector<float>> buffer_;
- size_t read_index_;
-};
-
-} // namespace intelligibility
-
-} // namespace webrtc
-
-#endif // MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_UTILS_H_
diff --git a/modules/audio_processing/intelligibility/intelligibility_utils_unittest.cc b/modules/audio_processing/intelligibility/intelligibility_utils_unittest.cc
deleted file mode 100644
index fea394c..0000000
--- a/modules/audio_processing/intelligibility/intelligibility_utils_unittest.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2015 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 <cmath>
-#include <complex>
-#include <vector>
-
-#include "modules/audio_processing/intelligibility/intelligibility_utils.h"
-#include "rtc_base/arraysize.h"
-#include "test/gtest.h"
-
-namespace webrtc {
-
-namespace intelligibility {
-
-std::vector<std::vector<std::complex<float>>> GenerateTestData(size_t freqs,
- size_t samples) {
- std::vector<std::vector<std::complex<float>>> data(samples);
- for (size_t i = 0; i < samples; ++i) {
- for (size_t j = 0; j < freqs; ++j) {
- const float val = 0.99f / ((i + 1) * (j + 1));
- data[i].push_back(std::complex<float>(val, val));
- }
- }
- return data;
-}
-
-// Tests PowerEstimator, for all power step types.
-TEST(IntelligibilityUtilsTest, TestPowerEstimator) {
- const size_t kFreqs = 10;
- const size_t kSamples = 100;
- const float kDecay = 0.5f;
- const std::vector<std::vector<std::complex<float>>> test_data(
- GenerateTestData(kFreqs, kSamples));
- PowerEstimator<std::complex<float>> power_estimator(kFreqs, kDecay);
- EXPECT_EQ(0, power_estimator.power()[0]);
-
- // Makes sure Step is doing something.
- power_estimator.Step(test_data[0].data());
- for (size_t i = 1; i < kSamples; ++i) {
- power_estimator.Step(test_data[i].data());
- for (size_t j = 0; j < kFreqs; ++j) {
- EXPECT_GE(power_estimator.power()[j], 0.f);
- EXPECT_LE(power_estimator.power()[j], 1.f);
- }
- }
-}
-
-// Tests gain applier.
-TEST(IntelligibilityUtilsTest, TestGainApplier) {
- const size_t kFreqs = 10;
- const size_t kSamples = 100;
- const float kChangeLimit = 0.1f;
- GainApplier gain_applier(kFreqs, kChangeLimit);
- const std::vector<std::vector<std::complex<float>>> in_data(
- GenerateTestData(kFreqs, kSamples));
- std::vector<std::vector<std::complex<float>>> out_data(
- GenerateTestData(kFreqs, kSamples));
- for (size_t i = 0; i < kSamples; ++i) {
- gain_applier.Apply(in_data[i].data(), out_data[i].data());
- for (size_t j = 0; j < kFreqs; ++j) {
- EXPECT_GT(out_data[i][j].real(), 0.f);
- EXPECT_LT(out_data[i][j].real(), 1.f);
- EXPECT_GT(out_data[i][j].imag(), 0.f);
- EXPECT_LT(out_data[i][j].imag(), 1.f);
- }
- }
-}
-
-} // namespace intelligibility
-
-} // namespace webrtc
diff --git a/modules/audio_processing/module.mk b/modules/audio_processing/module.mk
index d45b414..7d8b360 100644
--- a/modules/audio_processing/module.mk
+++ b/modules/audio_processing/module.mk
@@ -14,7 +14,9 @@
modules/audio_processing/audio_buffer.o \
modules/audio_processing/audio_processing_impl.o \
modules/audio_processing/echo_cancellation_impl.o \
+ modules/audio_processing/echo_cancellation_proxy.o \
modules/audio_processing/echo_control_mobile_impl.o \
+ modules/audio_processing/echo_control_mobile_proxy.o \
modules/audio_processing/echo_detector/circular_buffer.o \
modules/audio_processing/echo_detector/mean_variance_estimator.o \
modules/audio_processing/echo_detector/moving_max.o \
@@ -90,11 +92,11 @@
modules/audio_processing/aec3/aec3_common.o \
modules/audio_processing/aec3/aec3_fft.o \
modules/audio_processing/aec3/aec_state.o \
+ modules/audio_processing/aec3/block_delay_buffer.o \
modules/audio_processing/aec3/block_framer.o \
modules/audio_processing/aec3/block_processor.o \
modules/audio_processing/aec3/block_processor_metrics.o \
modules/audio_processing/aec3/cascaded_biquad_filter.o \
- modules/audio_processing/aec3/coherence_gain.o \
modules/audio_processing/aec3/comfort_noise_generator.o \
modules/audio_processing/aec3/decimator.o \
modules/audio_processing/aec3/downsampled_render_buffer.o \
@@ -120,6 +122,8 @@
modules/audio_processing/aec3/render_delay_controller_metrics.o \
modules/audio_processing/aec3/render_signal_analyzer.o \
modules/audio_processing/aec3/residual_echo_estimator.o \
+ modules/audio_processing/aec3/reverb_decay_estimator.o \
+ modules/audio_processing/aec3/reverb_frequency_response.o \
modules/audio_processing/aec3/reverb_model.o \
modules/audio_processing/aec3/reverb_model_estimator.o \
modules/audio_processing/aec3/reverb_model_fallback.o \
diff --git a/modules/audio_processing/ns/noise_suppression.h b/modules/audio_processing/ns/noise_suppression.h
index fd6aa96..0775ffa 100644
--- a/modules/audio_processing/ns/noise_suppression.h
+++ b/modules/audio_processing/ns/noise_suppression.h
@@ -12,8 +12,7 @@
#define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_H_
#include <stddef.h>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
typedef struct NsHandleT NsHandle;
diff --git a/modules/audio_processing/ns/noise_suppression_x.h b/modules/audio_processing/ns/noise_suppression_x.h
index f25fb7a..972784e 100644
--- a/modules/audio_processing/ns/noise_suppression_x.h
+++ b/modules/audio_processing/ns/noise_suppression_x.h
@@ -12,8 +12,7 @@
#define MODULES_AUDIO_PROCESSING_NS_NOISE_SUPPRESSION_X_H_
#include <stddef.h>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
typedef struct NsxHandleT NsxHandle;
diff --git a/modules/audio_processing/ns/ns_core.c b/modules/audio_processing/ns/ns_core.c
index c87713a..bc5dd6d 100644
--- a/modules/audio_processing/ns/ns_core.c
+++ b/modules/audio_processing/ns/ns_core.c
@@ -13,8 +13,8 @@
#include <stdlib.h>
#include "rtc_base/checks.h"
-#include "common_audio/fft4g.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "common_audio/third_party/fft4g/fft4g.h"
#include "modules/audio_processing/ns/noise_suppression.h"
#include "modules/audio_processing/ns/ns_core.h"
#include "modules/audio_processing/ns/windows_private.h"
diff --git a/modules/audio_processing/ns/nsx_core.h b/modules/audio_processing/ns/nsx_core.h
index 479e90c..9e9d142 100644
--- a/modules/audio_processing/ns/nsx_core.h
+++ b/modules/audio_processing/ns/nsx_core.h
@@ -17,7 +17,6 @@
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "modules/audio_processing/ns/nsx_defines.h"
-#include "typedefs.h" // NOLINT(build/include)
typedef struct NoiseSuppressionFixedC_ {
uint32_t fs;
diff --git a/modules/audio_processing/rms_level.h b/modules/audio_processing/rms_level.h
index ae45a45..9aa549a 100644
--- a/modules/audio_processing/rms_level.h
+++ b/modules/audio_processing/rms_level.h
@@ -13,7 +13,6 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/dyadic_decimator.h b/modules/audio_processing/transient/dyadic_decimator.h
index e5b1961..fcb56b7 100644
--- a/modules/audio_processing/transient/dyadic_decimator.h
+++ b/modules/audio_processing/transient/dyadic_decimator.h
@@ -13,8 +13,6 @@
#include <cstdlib>
-#include "typedefs.h" // NOLINT(build/include)
-
// Provides a set of static methods to perform dyadic decimations.
namespace webrtc {
diff --git a/modules/audio_processing/transient/file_utils.cc b/modules/audio_processing/transient/file_utils.cc
index 40732b9..58f9932 100644
--- a/modules/audio_processing/transient/file_utils.cc
+++ b/modules/audio_processing/transient/file_utils.cc
@@ -13,7 +13,6 @@
#include <memory>
#include "rtc_base/system/file_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/file_utils.h b/modules/audio_processing/transient/file_utils.h
index 4b04fac..6184017 100644
--- a/modules/audio_processing/transient/file_utils.h
+++ b/modules/audio_processing/transient/file_utils.h
@@ -14,7 +14,6 @@
#include <string.h>
#include "rtc_base/system/file_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/file_utils_unittest.cc b/modules/audio_processing/transient/file_utils_unittest.cc
index 05f8341..89902ec 100644
--- a/modules/audio_processing/transient/file_utils_unittest.cc
+++ b/modules/audio_processing/transient/file_utils_unittest.cc
@@ -18,7 +18,6 @@
#include "rtc_base/system/file_wrapper.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/moving_moments.cc b/modules/audio_processing/transient/moving_moments.cc
index 4be4d6a..a199bb0 100644
--- a/modules/audio_processing/transient/moving_moments.cc
+++ b/modules/audio_processing/transient/moving_moments.cc
@@ -10,8 +10,7 @@
#include "modules/audio_processing/transient/moving_moments.h"
-#include <math.h>
-#include <string.h>
+#include <cmath>
#include "rtc_base/checks.h"
@@ -44,7 +43,7 @@
sum_ += in[i] - old_value;
sum_of_squares_ += in[i] * in[i] - old_value * old_value;
first[i] = sum_ / length_;
- second[i] = sum_of_squares_ / length_;
+ second[i] = std::max(0.f, sum_of_squares_ / length_);
}
}
diff --git a/modules/audio_processing/transient/transient_detector_unittest.cc b/modules/audio_processing/transient/transient_detector_unittest.cc
index 69a669f..d1eb7af 100644
--- a/modules/audio_processing/transient/transient_detector_unittest.cc
+++ b/modules/audio_processing/transient/transient_detector_unittest.cc
@@ -19,7 +19,6 @@
#include "rtc_base/system/file_wrapper.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/transient_suppression_test.cc b/modules/audio_processing/transient/transient_suppression_test.cc
index 00e1989..9e7ecd5 100644
--- a/modules/audio_processing/transient/transient_suppression_test.cc
+++ b/modules/audio_processing/transient/transient_suppression_test.cc
@@ -22,7 +22,6 @@
#include "rtc_base/flags.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"
-#include "typedefs.h" // NOLINT(build/include)
DEFINE_string(in_file_name, "", "PCM file that contains the signal.");
DEFINE_string(detection_file_name,
diff --git a/modules/audio_processing/transient/transient_suppressor.cc b/modules/audio_processing/transient/transient_suppressor.cc
index 28eb666..1a5ed56 100644
--- a/modules/audio_processing/transient/transient_suppressor.cc
+++ b/modules/audio_processing/transient/transient_suppressor.cc
@@ -17,15 +17,14 @@
#include <deque>
#include <set>
-#include "common_audio/fft4g.h"
#include "common_audio/include/audio_util.h"
#include "common_audio/signal_processing/include/signal_processing_library.h"
+#include "common_audio/third_party/fft4g/fft4g.h"
#include "modules/audio_processing/ns/windows_private.h"
#include "modules/audio_processing/transient/common.h"
#include "modules/audio_processing/transient/transient_detector.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/transient_suppressor.h b/modules/audio_processing/transient/transient_suppressor.h
index 27b096c..9ae3fc6 100644
--- a/modules/audio_processing/transient/transient_suppressor.h
+++ b/modules/audio_processing/transient/transient_suppressor.h
@@ -16,7 +16,6 @@
#include <set>
#include "rtc_base/gtest_prod_util.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/transient/wpd_node.h b/modules/audio_processing/transient/wpd_node.h
index 117a633..6a52fb7 100644
--- a/modules/audio_processing/transient/wpd_node.h
+++ b/modules/audio_processing/transient/wpd_node.h
@@ -13,8 +13,6 @@
#include <memory>
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
class FIRFilter;
diff --git a/modules/audio_processing/typing_detection.h b/modules/audio_processing/typing_detection.h
index 14dfe1d..70fd903 100644
--- a/modules/audio_processing/typing_detection.h
+++ b/modules/audio_processing/typing_detection.h
@@ -11,8 +11,6 @@
#ifndef MODULES_AUDIO_PROCESSING_TYPING_DETECTION_H_
#define MODULES_AUDIO_PROCESSING_TYPING_DETECTION_H_
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
class TypingDetection {
diff --git a/modules/audio_processing/utility/BUILD.gn b/modules/audio_processing/utility/BUILD.gn
index cd23d01..6a4304d 100644
--- a/modules/audio_processing/utility/BUILD.gn
+++ b/modules/audio_processing/utility/BUILD.gn
@@ -28,7 +28,6 @@
"delay_estimator_wrapper.h",
]
deps = [
- "../../..:typedefs",
"../../../rtc_base:checks",
]
}
@@ -40,7 +39,7 @@
"ooura_fft_tables_common.h",
]
deps = [
- "../../..:typedefs",
+ "../../../rtc_base/system:arch",
"../../../system_wrappers:cpu_features_api",
]
cflags = []
@@ -64,9 +63,7 @@
deps += [ "../../../common_audio" ]
if (current_cpu != "arm64") {
- # Enable compilation for the NEON instruction set. This is needed
- # since //build/config/arm.gni only enables NEON for iOS, not Android.
- # This provides the same functionality as webrtc/build/arm_neon.gypi.
+ # Enable compilation for the NEON instruction set.
suppressed_configs += [ "//build/config/compiler:compiler_arm_fpu" ]
cflags += [ "-mfpu=neon" ]
}
@@ -109,7 +106,6 @@
]
deps = [
":legacy_delay_estimator",
- "../../..:typedefs",
"../../../rtc_base:rtc_base_approved",
"../../../test:test_support",
"//testing/gtest",
diff --git a/modules/audio_processing/utility/delay_estimator.h b/modules/audio_processing/utility/delay_estimator.h
index 11483ec..2f47e26 100644
--- a/modules/audio_processing/utility/delay_estimator.h
+++ b/modules/audio_processing/utility/delay_estimator.h
@@ -14,7 +14,7 @@
#ifndef MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
#define MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
static const int32_t kMaxBitCountsQ9 = (32 << 9); // 32 matching bits in Q9.
diff --git a/modules/audio_processing/utility/delay_estimator_internal.h b/modules/audio_processing/utility/delay_estimator_internal.h
index 46eea3e..e99fe21 100644
--- a/modules/audio_processing/utility/delay_estimator_internal.h
+++ b/modules/audio_processing/utility/delay_estimator_internal.h
@@ -14,7 +14,6 @@
#define MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_INTERNAL_H_
#include "modules/audio_processing/utility/delay_estimator.h"
-#include "typedefs.h" // NOLINT(build/include)
typedef union {
float float_;
diff --git a/modules/audio_processing/utility/delay_estimator_unittest.cc b/modules/audio_processing/utility/delay_estimator_unittest.cc
index 8d65cb9..324bc37 100644
--- a/modules/audio_processing/utility/delay_estimator_unittest.cc
+++ b/modules/audio_processing/utility/delay_estimator_unittest.cc
@@ -12,7 +12,6 @@
#include "modules/audio_processing/utility/delay_estimator_internal.h"
#include "modules/audio_processing/utility/delay_estimator_wrapper.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace {
diff --git a/modules/audio_processing/utility/delay_estimator_wrapper.h b/modules/audio_processing/utility/delay_estimator_wrapper.h
index 6b6e51f..995470f 100644
--- a/modules/audio_processing/utility/delay_estimator_wrapper.h
+++ b/modules/audio_processing/utility/delay_estimator_wrapper.h
@@ -14,7 +14,7 @@
#ifndef MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
#define MODULES_AUDIO_PROCESSING_UTILITY_DELAY_ESTIMATOR_WRAPPER_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
// Releases the memory allocated by WebRtc_CreateDelayEstimatorFarend(...)
void WebRtc_FreeDelayEstimatorFarend(void* handle);
diff --git a/modules/audio_processing/utility/ooura_fft.cc b/modules/audio_processing/utility/ooura_fft.cc
index 2add4eb..c3333ce 100644
--- a/modules/audio_processing/utility/ooura_fft.cc
+++ b/modules/audio_processing/utility/ooura_fft.cc
@@ -26,8 +26,8 @@
#include <math.h>
#include "modules/audio_processing/utility/ooura_fft_tables_common.h"
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/utility/ooura_fft.h b/modules/audio_processing/utility/ooura_fft.h
index 96d57dc..0cdd6aa 100644
--- a/modules/audio_processing/utility/ooura_fft.h
+++ b/modules/audio_processing/utility/ooura_fft.h
@@ -11,7 +11,7 @@
#ifndef MODULES_AUDIO_PROCESSING_UTILITY_OOURA_FFT_H_
#define MODULES_AUDIO_PROCESSING_UTILITY_OOURA_FFT_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include "rtc_base/system/arch.h"
namespace webrtc {
diff --git a/modules/audio_processing/utility/ooura_fft_mips.cc b/modules/audio_processing/utility/ooura_fft_mips.cc
index c782ee7..9fe577d 100644
--- a/modules/audio_processing/utility/ooura_fft_mips.cc
+++ b/modules/audio_processing/utility/ooura_fft_mips.cc
@@ -11,7 +11,6 @@
#include "modules/audio_processing/utility/ooura_fft.h"
#include "modules/audio_processing/utility/ooura_fft_tables_common.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/utility/ooura_fft_sse2.cc b/modules/audio_processing/utility/ooura_fft_sse2.cc
index b44458e..9b5d0f3 100644
--- a/modules/audio_processing/utility/ooura_fft_sse2.cc
+++ b/modules/audio_processing/utility/ooura_fft_sse2.cc
@@ -14,6 +14,7 @@
#include "modules/audio_processing/utility/ooura_fft_tables_common.h"
#include "modules/audio_processing/utility/ooura_fft_tables_neon_sse2.h"
+#include "rtc_base/system/arch.h"
namespace webrtc {
diff --git a/modules/audio_processing/utility/ooura_fft_tables_neon_sse2.h b/modules/audio_processing/utility/ooura_fft_tables_neon_sse2.h
index 1c44ae7..b6e4a07 100644
--- a/modules/audio_processing/utility/ooura_fft_tables_neon_sse2.h
+++ b/modules/audio_processing/utility/ooura_fft_tables_neon_sse2.h
@@ -12,6 +12,7 @@
#define MODULES_AUDIO_PROCESSING_UTILITY_OOURA_FFT_TABLES_NEON_SSE2_H_
#include "modules/audio_processing/utility/ooura_fft.h"
+#include "rtc_base/system/arch.h"
#ifdef _MSC_VER /* visual c++ */
#define ALIGN16_BEG __declspec(align(16))
diff --git a/modules/audio_processing/vad/BUILD.gn b/modules/audio_processing/vad/BUILD.gn
index e16b57f..6c64e94 100644
--- a/modules/audio_processing/vad/BUILD.gn
+++ b/modules/audio_processing/vad/BUILD.gn
@@ -35,11 +35,10 @@
"voice_gmm_tables.h",
]
deps = [
- "../../..:typedefs",
"../../../audio/utility:audio_frame_operations",
"../../../common_audio",
"../../../common_audio:common_audio_c",
- "../../../common_audio:fft4g",
+ "../../../common_audio/third_party/fft4g:fft4g",
"../../../rtc_base:checks",
"../../audio_coding:isac_vad",
]
diff --git a/modules/audio_processing/vad/gmm.cc b/modules/audio_processing/vad/gmm.cc
index 266ca44..cd8a1a8 100644
--- a/modules/audio_processing/vad/gmm.cc
+++ b/modules/audio_processing/vad/gmm.cc
@@ -13,8 +13,6 @@
#include <math.h>
#include <stdlib.h>
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
static const int kMaxDimension = 10;
diff --git a/modules/audio_processing/vad/pitch_based_vad.h b/modules/audio_processing/vad/pitch_based_vad.h
index 584dcc7..4d32765 100644
--- a/modules/audio_processing/vad/pitch_based_vad.h
+++ b/modules/audio_processing/vad/pitch_based_vad.h
@@ -15,7 +15,6 @@
#include "modules/audio_processing/vad/common.h"
#include "modules/audio_processing/vad/gmm.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/vad/pole_zero_filter.h b/modules/audio_processing/vad/pole_zero_filter.h
index 283deec..11a0511 100644
--- a/modules/audio_processing/vad/pole_zero_filter.h
+++ b/modules/audio_processing/vad/pole_zero_filter.h
@@ -11,9 +11,8 @@
#ifndef MODULES_AUDIO_PROCESSING_VAD_POLE_ZERO_FILTER_H_
#define MODULES_AUDIO_PROCESSING_VAD_POLE_ZERO_FILTER_H_
-#include <cstddef>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stddef.h>
+#include <stdint.h>
namespace webrtc {
diff --git a/modules/audio_processing/vad/standalone_vad.cc b/modules/audio_processing/vad/standalone_vad.cc
index 813d375..19a5282 100644
--- a/modules/audio_processing/vad/standalone_vad.cc
+++ b/modules/audio_processing/vad/standalone_vad.cc
@@ -14,7 +14,6 @@
#include "audio/utility/audio_frame_operations.h"
#include "rtc_base/checks.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/vad/standalone_vad.h b/modules/audio_processing/vad/standalone_vad.h
index 3f6eb7f..79650fb 100644
--- a/modules/audio_processing/vad/standalone_vad.h
+++ b/modules/audio_processing/vad/standalone_vad.h
@@ -13,7 +13,6 @@
#include "common_audio/vad/include/webrtc_vad.h"
#include "modules/audio_processing/vad/common.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/audio_processing/vad/vad_audio_proc.cc b/modules/audio_processing/vad/vad_audio_proc.cc
index e9007c6..53eb6de 100644
--- a/modules/audio_processing/vad/vad_audio_proc.cc
+++ b/modules/audio_processing/vad/vad_audio_proc.cc
@@ -14,7 +14,7 @@
#include <stdio.h>
#include <string.h>
-#include "common_audio/fft4g.h"
+#include "common_audio/third_party/fft4g/fft4g.h"
#include "modules/audio_processing/vad/pitch_internal.h"
#include "modules/audio_processing/vad/pole_zero_filter.h"
#include "modules/audio_processing/vad/vad_audio_proc_internal.h"
diff --git a/modules/audio_processing/vad/vad_audio_proc.h b/modules/audio_processing/vad/vad_audio_proc.h
index b1441a0..e34091b 100644
--- a/modules/audio_processing/vad/vad_audio_proc.h
+++ b/modules/audio_processing/vad/vad_audio_proc.h
@@ -14,7 +14,6 @@
#include <memory>
#include "modules/audio_processing/vad/common.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/include/module.h b/modules/include/module.h
index fc2a1b5..3b1e046 100644
--- a/modules/include/module.h
+++ b/modules/include/module.h
@@ -11,7 +11,7 @@
#ifndef MODULES_INCLUDE_MODULE_H_
#define MODULES_INCLUDE_MODULE_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
namespace webrtc {
diff --git a/modules/include/module_common_types.h b/modules/include/module_common_types.h
index 47fd3c2..8ee2369 100644
--- a/modules/include/module_common_types.h
+++ b/modules/include/module_common_types.h
@@ -29,13 +29,9 @@
#include "rtc_base/deprecation.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/timeutils.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
-// TODO(nisse): Deprecated, use webrtc::VideoCodecType instead.
-using RtpVideoCodecTypes = VideoCodecType;
-
struct WebRtcRTPHeader {
RTPVideoHeader& video_header() { return video; }
const RTPVideoHeader& video_header() const { return video; }
diff --git a/modules/include/module_common_types_public.h b/modules/include/module_common_types_public.h
index 2afd9af..345e45c 100644
--- a/modules/include/module_common_types_public.h
+++ b/modules/include/module_common_types_public.h
@@ -14,7 +14,6 @@
#include <limits>
#include "absl/types/optional.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -84,11 +83,15 @@
using SequenceNumberUnwrapper = Unwrapper<uint16_t>;
using TimestampUnwrapper = Unwrapper<uint32_t>;
+// NB: Doesn't fulfill strict weak ordering requirements.
+// Mustn't be used as std::map Compare function.
inline bool IsNewerSequenceNumber(uint16_t sequence_number,
uint16_t prev_sequence_number) {
return IsNewer(sequence_number, prev_sequence_number);
}
+// NB: Doesn't fulfill strict weak ordering requirements.
+// Mustn't be used as std::map Compare function.
inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
return IsNewer(timestamp, prev_timestamp);
}
diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn
index da546cd..055d712 100644
--- a/modules/rtp_rtcp/BUILD.gn
+++ b/modules/rtp_rtcp/BUILD.gn
@@ -87,7 +87,6 @@
deps = [
"..:module_api",
"../..:webrtc_common",
- "../../:typedefs",
"../../api:array_view",
"../../api:libjingle_peerconnection_api",
"../../api/audio_codecs:audio_codecs_api",
@@ -114,6 +113,8 @@
"include/rtp_receiver.h",
"include/rtp_rtcp.h",
"include/ulpfec_receiver.h",
+ "source/contributing_sources.cc",
+ "source/contributing_sources.h",
"source/dtmf_queue.cc",
"source/dtmf_queue.h",
"source/fec_private_tables_bursty.cc",
@@ -196,12 +197,13 @@
":rtp_rtcp_format",
"..:module_api",
"../..:webrtc_common",
- "../../:typedefs",
"../../api:array_view",
"../../api:libjingle_peerconnection_api",
"../../api:transport_api",
"../../api/audio_codecs:audio_codecs_api",
"../../api/video:video_bitrate_allocation",
+ "../../api/video:video_bitrate_allocator",
+ "../../api/video:video_frame",
"../../api/video_codecs:video_codecs_api",
"../../common_video",
"../../logging:rtc_event_audio",
@@ -268,6 +270,7 @@
"../../:webrtc_common",
"../../api/video:video_frame",
"../../modules/video_coding:codec_globals_headers",
+ "//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/types:variant",
]
}
@@ -350,6 +353,7 @@
sources = [
"source/byte_io_unittest.cc",
+ "source/contributing_sources_unittest.cc",
"source/fec_private_tables_bursty_unittest.cc",
"source/flexfec_header_reader_writer_unittest.cc",
"source/flexfec_receiver_unittest.cc",
@@ -421,11 +425,11 @@
":rtp_rtcp_format",
"..:module_api",
"../..:webrtc_common",
- "../../:typedefs",
"../../api:array_view",
"../../api:libjingle_peerconnection_api",
"../../api:transport_api",
"../../api/video:video_bitrate_allocation",
+ "../../api/video:video_bitrate_allocator",
"../../api/video:video_frame",
"../../api/video_codecs:video_codecs_api",
"../../call:rtp_receiver",
diff --git a/modules/rtp_rtcp/include/receive_statistics.h b/modules/rtp_rtcp/include/receive_statistics.h
index a3b4798..fe72ada 100644
--- a/modules/rtp_rtcp/include/receive_statistics.h
+++ b/modules/rtp_rtcp/include/receive_statistics.h
@@ -18,7 +18,7 @@
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
-#include "typedefs.h" // NOLINT(build/include)
+#include "rtc_base/deprecation.h"
namespace webrtc {
@@ -46,10 +46,6 @@
StreamDataCounters* data_counters) const = 0;
virtual uint32_t BitrateReceived() const = 0;
-
- // Returns true if the packet with RTP header |header| is likely to be a
- // retransmitted packet, false otherwise.
- virtual bool IsRetransmitOfOldPacket(const RTPHeader& header) const = 0;
};
class ReceiveStatistics : public ReceiveStatisticsProvider {
@@ -60,8 +56,16 @@
// Updates the receive statistics with this packet.
virtual void IncomingPacket(const RTPHeader& rtp_header,
- size_t packet_length,
- bool retransmitted) = 0;
+ size_t packet_length) = 0;
+
+ // TODO(nisse): Wrapper for backwards compatibility. Delete as soon as
+ // downstream callers are updated.
+ RTC_DEPRECATED
+ void IncomingPacket(const RTPHeader& rtp_header,
+ size_t packet_length,
+ bool retransmitted) {
+ IncomingPacket(rtp_header, packet_length);
+ }
// Increment counter for number of FEC packets received.
virtual void FecPacketReceived(const RTPHeader& header,
@@ -72,6 +76,9 @@
// Sets the max reordering threshold in number of packets.
virtual void SetMaxReorderingThreshold(int max_reordering_threshold) = 0;
+ // Detect retransmissions, enabling updates of the retransmitted counters. The
+ // default is false.
+ virtual void EnableRetransmitDetection(uint32_t ssrc, bool enable) = 0;
// Called on new RTCP stats creation.
virtual void RegisterRtcpStatisticsCallback(
diff --git a/modules/rtp_rtcp/include/rtp_header_parser.h b/modules/rtp_rtcp/include/rtp_header_parser.h
index 59012ce..2d84fc1 100644
--- a/modules/rtp_rtcp/include/rtp_header_parser.h
+++ b/modules/rtp_rtcp/include/rtp_header_parser.h
@@ -11,7 +11,6 @@
#define MODULES_RTP_RTCP_INCLUDE_RTP_HEADER_PARSER_H_
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/include/rtp_payload_registry.h b/modules/rtp_rtcp/include/rtp_payload_registry.h
index be296da..229c71b 100644
--- a/modules/rtp_rtcp/include/rtp_payload_registry.h
+++ b/modules/rtp_rtcp/include/rtp_payload_registry.h
@@ -45,20 +45,6 @@
absl::optional<RtpUtility::Payload> PayloadTypeToPayload(
uint8_t payload_type) const;
- void ResetLastReceivedPayloadTypes() {
- rtc::CritScope cs(&crit_sect_);
- last_received_payload_type_ = -1;
- }
-
- int8_t last_received_payload_type() const {
- rtc::CritScope cs(&crit_sect_);
- return last_received_payload_type_;
- }
- void set_last_received_payload_type(int8_t last_received_payload_type) {
- rtc::CritScope cs(&crit_sect_);
- last_received_payload_type_ = last_received_payload_type;
- }
-
private:
// Prunes the payload type map of the specific payload type, if it exists.
void DeregisterAudioCodecOrRedTypeRegardlessOfPayloadType(
@@ -66,7 +52,6 @@
rtc::CriticalSection crit_sect_;
std::map<int, RtpUtility::Payload> payload_type_map_;
- int8_t last_received_payload_type_;
// As a first step in splitting this class up in separate cases for audio and
// video, DCHECK that no instance is used for both audio and video.
diff --git a/modules/rtp_rtcp/include/rtp_receiver.h b/modules/rtp_rtcp/include/rtp_receiver.h
index d2d73b4..d93d656 100644
--- a/modules/rtp_rtcp/include/rtp_receiver.h
+++ b/modules/rtp_rtcp/include/rtp_receiver.h
@@ -15,28 +15,12 @@
#include "api/rtpreceiverinterface.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
class RTPPayloadRegistry;
class VideoCodec;
-class TelephoneEventHandler {
- public:
- virtual ~TelephoneEventHandler() {}
-
- // The following three methods implement the TelephoneEventHandler interface.
- // Forward DTMFs to decoder for playout.
- virtual void SetTelephoneEventForwardToDecoder(bool forward_to_decoder) = 0;
-
- // Is forwarding of outband telephone events turned on/off?
- virtual bool TelephoneEventForwardToDecoder() const = 0;
-
- // Is TelephoneEvent configured with payload type payload_type
- virtual bool TelephoneEventPayloadType(const int8_t payload_type) const = 0;
-};
-
class RtpReceiver {
public:
// Creates a video-enabled RTP receiver.
@@ -53,9 +37,6 @@
virtual ~RtpReceiver() {}
- // Returns a TelephoneEventHandler if available.
- virtual TelephoneEventHandler* GetTelephoneEventHandler() = 0;
-
// Registers a receive payload in the payload registry and notifies the media
// receiver strategy.
virtual int32_t RegisterReceivePayload(
@@ -98,9 +79,6 @@
// Returns the remote SSRC of the currently received RTP stream.
virtual uint32_t SSRC() const = 0;
- // Returns the current remote CSRCs.
- virtual int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const = 0;
-
virtual std::vector<RtpSource> GetSources() const = 0;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index 94237e0..f982a9b 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -33,7 +33,6 @@
class ReceiveStatisticsProvider;
class RemoteBitrateEstimator;
class RtcEventLog;
-class RtpReceiver;
class Transport;
class VideoBitrateAllocationObserver;
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.cc b/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
index ad9bd45..f86b238 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.cc
@@ -16,7 +16,19 @@
constexpr size_t StreamId::kMaxSize;
-bool StreamId::IsLegalName(rtc::ArrayView<const char> name) {
+// Check if passed character is a "token-char" from RFC 4566.
+static bool IsTokenChar(char ch) {
+ return ch == 0x21 || (ch >= 0x23 && ch <= 0x27) || ch == 0x2a || ch == 0x2b ||
+ ch == 0x2d || ch == 0x2e || (ch >= 0x30 && ch <= 0x39) ||
+ (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x5e && ch <= 0x7e);
+}
+
+bool StreamId::IsLegalMidName(rtc::ArrayView<const char> name) {
+ return (name.size() <= kMaxSize && name.size() > 0 &&
+ std::all_of(name.data(), name.data() + name.size(), IsTokenChar));
+}
+
+bool StreamId::IsLegalRsidName(rtc::ArrayView<const char> name) {
return (name.size() <= kMaxSize && name.size() > 0 &&
std::all_of(name.data(), name.data() + name.size(), isalnum));
}
diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
index cfd9030..34c7428 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp_defines.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.h
@@ -21,11 +21,9 @@
#include "common_types.h" // NOLINT(build/include)
#include "modules/include/module_common_types.h"
#include "system_wrappers/include/clock.h"
-#include "typedefs.h" // NOLINT(build/include)
#define RTCP_CNAME_SIZE 256 // RFC 3550 page 44, including null termination
#define IP_PACKET_SIZE 1500 // we assume ethernet
-#define MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS 10
namespace webrtc {
namespace rtcp {
@@ -91,8 +89,6 @@
absl::variant<AudioPayload, VideoPayload> payload_;
};
-enum RTPAliveType { kRtpDead = 0, kRtpNoRtp = 1, kRtpAlive = 2 };
-
enum ProtectionType { kUnprotectedPacket, kProtectedPacket };
enum StorageType { kDontRetransmit, kAllowRetransmission };
@@ -197,7 +193,7 @@
uint32_t sender_ssrc; // SSRC of sender of this report.
uint32_t source_ssrc; // SSRC of the RTP packet sender.
uint8_t fraction_lost;
- uint32_t packets_lost; // 24 bits valid.
+ int32_t packets_lost; // 24 bits valid.
uint32_t extended_highest_sequence_number;
uint32_t jitter;
uint32_t last_sender_report_timestamp;
diff --git a/modules/rtp_rtcp/include/ulpfec_receiver.h b/modules/rtp_rtcp/include/ulpfec_receiver.h
index 6ea8496..fce6e88 100644
--- a/modules/rtp_rtcp/include/ulpfec_receiver.h
+++ b/modules/rtp_rtcp/include/ulpfec_receiver.h
@@ -12,7 +12,6 @@
#define MODULES_RTP_RTCP_INCLUDE_ULPFEC_RECEIVER_H_
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/byte_io.h b/modules/rtp_rtcp/source/byte_io.h
index f9d973b..955bce7 100644
--- a/modules/rtp_rtcp/source/byte_io.h
+++ b/modules/rtp_rtcp/source/byte_io.h
@@ -34,10 +34,9 @@
// These classes are implemented as recursive templetizations, inteded to make
// it easy for the compiler to completely inline the reading/writing.
+#include <stdint.h>
#include <limits>
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
// According to ISO C standard ISO/IEC 9899, section 6.2.6.2 (2), the three
diff --git a/modules/rtp_rtcp/source/contributing_sources.cc b/modules/rtp_rtcp/source/contributing_sources.cc
new file mode 100644
index 0000000..853706c
--- /dev/null
+++ b/modules/rtp_rtcp/source/contributing_sources.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2018 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 "modules/rtp_rtcp/source/contributing_sources.h"
+
+namespace webrtc {
+
+namespace {
+
+// Allow some stale records to accumulate before cleaning.
+constexpr int64_t kPruningIntervalMs = 15 * rtc::kNumMillisecsPerSec;
+
+} // namespace
+
+constexpr int64_t ContributingSources::kHistoryMs;
+
+ContributingSources::ContributingSources() = default;
+ContributingSources::~ContributingSources() = default;
+
+void ContributingSources::Update(int64_t now_ms,
+ rtc::ArrayView<const uint32_t> csrcs) {
+ for (uint32_t csrc : csrcs) {
+ last_seen_ms_[csrc] = now_ms;
+ }
+ if (!next_pruning_ms_) {
+ next_pruning_ms_ = now_ms + kPruningIntervalMs;
+ } else if (now_ms > next_pruning_ms_) {
+ // To prevent unlimited growth, prune it every 15 seconds.
+ DeleteOldEntries(now_ms);
+ }
+}
+
+// Return contributing sources seen the last 10 s.
+// TODO(nisse): It would be more efficient to delete any stale entries while
+// iterating over the mapping, but then we'd have to make the method
+// non-const.
+std::vector<RtpSource> ContributingSources::GetSources(int64_t now_ms) const {
+ std::vector<RtpSource> sources;
+ for (auto& record : last_seen_ms_) {
+ if (record.second >= now_ms - kHistoryMs) {
+ sources.emplace_back(record.second, record.first, RtpSourceType::CSRC);
+ }
+ }
+
+ return sources;
+}
+
+// Delete stale entries.
+void ContributingSources::DeleteOldEntries(int64_t now_ms) {
+ for (auto it = last_seen_ms_.begin(); it != last_seen_ms_.end();) {
+ if (it->second >= now_ms - kHistoryMs) {
+ // Still relevant.
+ ++it;
+ } else {
+ it = last_seen_ms_.erase(it);
+ }
+ }
+ next_pruning_ms_ = now_ms + kPruningIntervalMs;
+}
+
+} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/contributing_sources.h b/modules/rtp_rtcp/source/contributing_sources.h
new file mode 100644
index 0000000..1a4a572
--- /dev/null
+++ b/modules/rtp_rtcp/source/contributing_sources.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018 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 MODULES_RTP_RTCP_SOURCE_CONTRIBUTING_SOURCES_H_
+#define MODULES_RTP_RTCP_SOURCE_CONTRIBUTING_SOURCES_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "api/array_view.h"
+#include "api/rtpreceiverinterface.h"
+
+namespace webrtc {
+
+class ContributingSources {
+ public:
+ // Set by the spec, see
+ // https://www.w3.org/TR/webrtc/#dom-rtcrtpreceiver-getcontributingsources
+ static constexpr int64_t kHistoryMs = 10 * rtc::kNumMillisecsPerSec;
+
+ ContributingSources();
+ ~ContributingSources();
+
+ // TODO(bugs.webrtc.org/3333): Needs to be extended with audio-level, to
+ // support RFC6465.
+ void Update(int64_t now_ms, rtc::ArrayView<const uint32_t> csrcs);
+
+ // Returns contributing sources seen the last 10 s.
+ std::vector<RtpSource> GetSources(int64_t now_ms) const;
+
+ private:
+ void DeleteOldEntries(int64_t now_ms);
+
+ // Indexed by csrc.
+ std::map<uint32_t, int64_t> last_seen_ms_;
+ absl::optional<int64_t> next_pruning_ms_;
+};
+
+} // namespace webrtc
+
+#endif // MODULES_RTP_RTCP_SOURCE_CONTRIBUTING_SOURCES_H_
diff --git a/modules/rtp_rtcp/source/contributing_sources_unittest.cc b/modules/rtp_rtcp/source/contributing_sources_unittest.cc
new file mode 100644
index 0000000..8b22d26
--- /dev/null
+++ b/modules/rtp_rtcp/source/contributing_sources_unittest.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2018 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 "modules/rtp_rtcp/source/contributing_sources.h"
+
+#include "rtc_base/timeutils.h"
+
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace {
+
+using ::testing::UnorderedElementsAre;
+
+constexpr uint32_t kCsrc1 = 111;
+constexpr uint32_t kCsrc2 = 222;
+constexpr uint32_t kCsrc3 = 333;
+
+} // namespace
+
+TEST(ContributingSourcesTest, RecordSources) {
+ ContributingSources csrcs;
+ constexpr uint32_t kCsrcs[] = {kCsrc1, kCsrc2};
+ constexpr int64_t kTime1 = 10;
+ csrcs.Update(kTime1, kCsrcs);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime1),
+ UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
+ RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
+}
+
+TEST(ContributingSourcesTest, UpdateSources) {
+ ContributingSources csrcs;
+ // TODO(nisse): When migrating to absl::Span, the named constant arrays should
+ // be replaced by unnamed literals where they are passed to csrcs.Update(...).
+ constexpr uint32_t kCsrcs1[] = {kCsrc1, kCsrc2};
+ constexpr uint32_t kCsrcs2[] = {kCsrc2, kCsrc3};
+ constexpr int64_t kTime1 = 10;
+ constexpr int64_t kTime2 = kTime1 + 5 * rtc::kNumMillisecsPerSec;
+ csrcs.Update(kTime1, kCsrcs1);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime1),
+ UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
+ RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
+ csrcs.Update(kTime2, kCsrcs2);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime2),
+ UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
+ RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC),
+ RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC)));
+}
+
+TEST(ContributingSourcesTest, ReturnRecentOnly) {
+ ContributingSources csrcs;
+ constexpr uint32_t kCsrcs1[] = {kCsrc1, kCsrc2};
+ constexpr uint32_t kCsrcs2[] = {kCsrc2, kCsrc3};
+ constexpr int64_t kTime1 = 10;
+ constexpr int64_t kTime2 = kTime1 + 5 * rtc::kNumMillisecsPerSec;
+ constexpr int64_t kTime3 = kTime1 + 12 * rtc::kNumMillisecsPerSec;
+ csrcs.Update(kTime1, kCsrcs1);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime1),
+ UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
+ RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
+ csrcs.Update(kTime2, kCsrcs2);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime3),
+ UnorderedElementsAre(RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC),
+ RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC)));
+}
+
+TEST(ContributingSourcesTest, PurgeOldSources) {
+ ContributingSources csrcs;
+ constexpr uint32_t kCsrcs1[] = {kCsrc1, kCsrc2};
+ constexpr uint32_t kCsrcs2[] = {kCsrc2, kCsrc3};
+ constexpr int64_t kTime1 = 10;
+ constexpr int64_t kTime2 = kTime1 + 10 * rtc::kNumMillisecsPerSec;
+ constexpr int64_t kTime3 = kTime1 + 20 * rtc::kNumMillisecsPerSec;
+ csrcs.Update(kTime1, kCsrcs1);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime2),
+ UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
+ RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC)));
+ csrcs.Update(kTime2, kCsrcs2);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime2),
+ UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC),
+ RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC),
+ RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC)));
+ csrcs.Update(kTime3, kCsrcs2);
+ EXPECT_THAT(
+ csrcs.GetSources(kTime3),
+ UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC),
+ RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC)));
+ // Query at an earlier time; check that old sources really have been purged
+ // and don't reappear.
+ EXPECT_THAT(
+ csrcs.GetSources(kTime2),
+ UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC),
+ RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC)));
+}
+
+} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/fec_private_tables_bursty.h b/modules/rtp_rtcp/source/fec_private_tables_bursty.h
index 4120cf9..5d67292 100644
--- a/modules/rtp_rtcp/source/fec_private_tables_bursty.h
+++ b/modules/rtp_rtcp/source/fec_private_tables_bursty.h
@@ -25,9 +25,7 @@
// (i.e., more packets/symbols in the code, so larger (k,m), i.e., k > 4,
// m > 3).
-#include <cstddef>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
namespace webrtc {
namespace fec_private_tables {
diff --git a/modules/rtp_rtcp/source/fec_private_tables_random.h b/modules/rtp_rtcp/source/fec_private_tables_random.h
index 96c3cef..cc7b929 100644
--- a/modules/rtp_rtcp/source/fec_private_tables_random.h
+++ b/modules/rtp_rtcp/source/fec_private_tables_random.h
@@ -15,9 +15,7 @@
// this table are specifically designed to favor recovery to random loss.
// These packet masks are defined to protect up to maximum of 48 media packets.
-#include <cstddef>
-
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
namespace webrtc {
namespace fec_private_tables {
diff --git a/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
index 53ff5d5..7ecec76 100644
--- a/modules/rtp_rtcp/source/nack_rtx_unittest.cc
+++ b/modules/rtp_rtcp/source/nack_rtx_unittest.cc
@@ -202,9 +202,10 @@
uint32_t timestamp = 3000;
uint16_t nack_list[kVideoNackListSize];
for (int frame = 0; frame < kNumFrames; ++frame) {
+ RTPVideoHeader video_header;
EXPECT_TRUE(rtp_rtcp_module_->SendOutgoingData(
webrtc::kVideoFrameDelta, kPayloadType, timestamp, timestamp / 90,
- payload_data, payload_data_length, nullptr, nullptr, nullptr));
+ payload_data, payload_data_length, nullptr, &video_header, nullptr));
// Min required delay until retransmit = 5 + RTT ms (RTT = 0).
fake_clock.AdvanceTimeMilliseconds(5);
int length = BuildNackList(nack_list);
@@ -250,9 +251,10 @@
// Send 30 frames which at the default size is roughly what we need to get
// enough packets.
for (int frame = 0; frame < kNumFrames; ++frame) {
+ RTPVideoHeader video_header;
EXPECT_TRUE(rtp_rtcp_module_->SendOutgoingData(
webrtc::kVideoFrameDelta, kPayloadType, timestamp, timestamp / 90,
- payload_data, payload_data_length, nullptr, nullptr, nullptr));
+ payload_data, payload_data_length, nullptr, &video_header, nullptr));
// Prepare next frame.
timestamp += 3000;
fake_clock.AdvanceTimeMilliseconds(33);
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.cc b/modules/rtp_rtcp/source/receive_statistics_impl.cc
index 362a7cf..80b8c9b 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.cc
@@ -31,6 +31,7 @@
StreamStatisticianImpl::StreamStatisticianImpl(
uint32_t ssrc,
Clock* clock,
+ bool enable_retransmit_detection,
RtcpStatisticsCallback* rtcp_callback,
StreamDataCountersCallback* rtp_callback)
: ssrc_(ssrc),
@@ -38,6 +39,7 @@
incoming_bitrate_(kStatisticsProcessIntervalMs,
RateStatistics::kBpsScale),
max_reordering_threshold_(kDefaultMaxReorderingThreshold),
+ enable_retransmit_detection_(enable_retransmit_detection),
jitter_q4_(0),
cumulative_loss_(0),
last_receive_time_ms_(0),
@@ -55,9 +57,15 @@
StreamStatisticianImpl::~StreamStatisticianImpl() = default;
void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
- size_t packet_length,
- bool retransmitted) {
- auto counters = UpdateCounters(header, packet_length, retransmitted);
+ size_t packet_length) {
+ StreamDataCounters counters;
+ {
+ rtc::CritScope cs(&stream_lock_);
+
+ bool retransmitted =
+ enable_retransmit_detection_ && IsRetransmitOfOldPacket(header);
+ counters = UpdateCounters(header, packet_length, retransmitted);
+ }
rtp_callback_->DataCountersUpdated(counters, ssrc_);
}
@@ -65,7 +73,6 @@
const RTPHeader& header,
size_t packet_length,
bool retransmitted) {
- rtc::CritScope cs(&stream_lock_);
bool in_order = InOrderPacketInternal(header.sequenceNumber);
RTC_DCHECK_EQ(ssrc_, header.ssrc);
incoming_bitrate_.Update(packet_length, clock_->TimeInMilliseconds());
@@ -152,6 +159,11 @@
max_reordering_threshold_ = max_reordering_threshold;
}
+void StreamStatisticianImpl::EnableRetransmitDetection(bool enable) {
+ rtc::CritScope cs(&stream_lock_);
+ enable_retransmit_detection_ = enable;
+}
+
bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
bool reset) {
{
@@ -300,7 +312,6 @@
bool StreamStatisticianImpl::IsRetransmitOfOldPacket(
const RTPHeader& header) const {
- rtc::CritScope cs(&stream_lock_);
if (InOrderPacketInternal(header.sequenceNumber)) {
return false;
}
@@ -362,8 +373,7 @@
}
void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
- size_t packet_length,
- bool retransmitted) {
+ size_t packet_length) {
StreamStatisticianImpl* impl;
{
rtc::CritScope cs(&receive_statistics_lock_);
@@ -371,7 +381,9 @@
if (it != statisticians_.end()) {
impl = it->second;
} else {
- impl = new StreamStatisticianImpl(header.ssrc, clock_, this, this);
+ impl = new StreamStatisticianImpl(
+ header.ssrc, clock_, /* enable_retransmit_detection = */ false, this,
+ this);
statisticians_[header.ssrc] = impl;
}
}
@@ -379,7 +391,7 @@
// this whole ReceiveStatisticsImpl is destroyed. StreamStatisticianImpl has
// it's own locking so don't hold receive_statistics_lock_ (potential
// deadlock).
- impl->IncomingPacket(header, packet_length, retransmitted);
+ impl->IncomingPacket(header, packet_length);
}
void ReceiveStatisticsImpl::FecPacketReceived(const RTPHeader& header,
@@ -413,6 +425,21 @@
}
}
+void ReceiveStatisticsImpl::EnableRetransmitDetection(uint32_t ssrc,
+ bool enable) {
+ StreamStatisticianImpl* impl;
+ {
+ rtc::CritScope cs(&receive_statistics_lock_);
+ StreamStatisticianImpl*& impl_ref = statisticians_[ssrc];
+ if (impl_ref == nullptr) { // new element
+ impl_ref = new StreamStatisticianImpl(ssrc, clock_, enable, this, this);
+ return;
+ }
+ impl = impl_ref;
+ }
+ impl->EnableRetransmitDetection(enable);
+}
+
void ReceiveStatisticsImpl::RegisterRtcpStatisticsCallback(
RtcpStatisticsCallback* callback) {
rtc::CritScope cs(&receive_statistics_lock_);
diff --git a/modules/rtp_rtcp/source/receive_statistics_impl.h b/modules/rtp_rtcp/source/receive_statistics_impl.h
index 5559b7c..f94256a 100644
--- a/modules/rtp_rtcp/source/receive_statistics_impl.h
+++ b/modules/rtp_rtcp/source/receive_statistics_impl.h
@@ -27,6 +27,7 @@
public:
StreamStatisticianImpl(uint32_t ssrc,
Clock* clock,
+ bool enable_retransmit_detection,
RtcpStatisticsCallback* rtcp_callback,
StreamDataCountersCallback* rtp_callback);
~StreamStatisticianImpl() override;
@@ -39,49 +40,54 @@
void GetReceiveStreamDataCounters(
StreamDataCounters* data_counters) const override;
uint32_t BitrateReceived() const override;
- bool IsRetransmitOfOldPacket(const RTPHeader& header) const override;
- void IncomingPacket(const RTPHeader& rtp_header,
- size_t packet_length,
- bool retransmitted);
+ void IncomingPacket(const RTPHeader& rtp_header, size_t packet_length);
void FecPacketReceived(const RTPHeader& header, size_t packet_length);
void SetMaxReorderingThreshold(int max_reordering_threshold);
+ void EnableRetransmitDetection(bool enable);
private:
- bool InOrderPacketInternal(uint16_t sequence_number) const;
+ bool IsRetransmitOfOldPacket(const RTPHeader& header) const
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
+ bool InOrderPacketInternal(uint16_t sequence_number) const
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
RtcpStatistics CalculateRtcpStatistics()
RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
- void UpdateJitter(const RTPHeader& header, NtpTime receive_time);
+ void UpdateJitter(const RTPHeader& header, NtpTime receive_time)
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
StreamDataCounters UpdateCounters(const RTPHeader& rtp_header,
size_t packet_length,
- bool retransmitted);
+ bool retransmitted)
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(stream_lock_);
const uint32_t ssrc_;
Clock* const clock_;
rtc::CriticalSection stream_lock_;
- RateStatistics incoming_bitrate_;
- int max_reordering_threshold_; // In number of packets or sequence numbers.
+ RateStatistics incoming_bitrate_ RTC_GUARDED_BY(&stream_lock_);
+ // In number of packets or sequence numbers.
+ int max_reordering_threshold_ RTC_GUARDED_BY(&stream_lock_);
+ bool enable_retransmit_detection_ RTC_GUARDED_BY(&stream_lock_);
// Stats on received RTP packets.
- uint32_t jitter_q4_;
- uint32_t cumulative_loss_;
+ uint32_t jitter_q4_ RTC_GUARDED_BY(&stream_lock_);
+ uint32_t cumulative_loss_ RTC_GUARDED_BY(&stream_lock_);
- int64_t last_receive_time_ms_;
- NtpTime last_receive_time_ntp_;
- uint32_t last_received_timestamp_;
- uint16_t received_seq_first_;
- uint16_t received_seq_max_;
- uint16_t received_seq_wraps_;
+ int64_t last_receive_time_ms_ RTC_GUARDED_BY(&stream_lock_);
+ NtpTime last_receive_time_ntp_ RTC_GUARDED_BY(&stream_lock_);
+ uint32_t last_received_timestamp_ RTC_GUARDED_BY(&stream_lock_);
+ uint16_t received_seq_first_ RTC_GUARDED_BY(&stream_lock_);
+ uint16_t received_seq_max_ RTC_GUARDED_BY(&stream_lock_);
+ uint16_t received_seq_wraps_ RTC_GUARDED_BY(&stream_lock_);
// Current counter values.
- size_t received_packet_overhead_;
- StreamDataCounters receive_counters_;
+ size_t received_packet_overhead_ RTC_GUARDED_BY(&stream_lock_);
+ StreamDataCounters receive_counters_ RTC_GUARDED_BY(&stream_lock_);
// Counter values when we sent the last report.
- uint32_t last_report_inorder_packets_;
- uint32_t last_report_old_packets_;
- uint16_t last_report_seq_max_;
- RtcpStatistics last_reported_statistics_;
+ uint32_t last_report_inorder_packets_ RTC_GUARDED_BY(&stream_lock_);
+ uint32_t last_report_old_packets_ RTC_GUARDED_BY(&stream_lock_);
+ uint16_t last_report_seq_max_ RTC_GUARDED_BY(&stream_lock_);
+ RtcpStatistics last_reported_statistics_ RTC_GUARDED_BY(&stream_lock_);
// stream_lock_ shouldn't be held when calling callbacks.
RtcpStatisticsCallback* const rtcp_callback_;
@@ -100,13 +106,12 @@
std::vector<rtcp::ReportBlock> RtcpReportBlocks(size_t max_blocks) override;
// Implement ReceiveStatistics.
- void IncomingPacket(const RTPHeader& header,
- size_t packet_length,
- bool retransmitted) override;
+ void IncomingPacket(const RTPHeader& header, size_t packet_length) override;
void FecPacketReceived(const RTPHeader& header,
size_t packet_length) override;
StreamStatistician* GetStatistician(uint32_t ssrc) const override;
void SetMaxReorderingThreshold(int max_reordering_threshold) override;
+ void EnableRetransmitDetection(uint32_t ssrc, bool enable) override;
void RegisterRtcpStatisticsCallback(
RtcpStatisticsCallback* callback) override;
diff --git a/modules/rtp_rtcp/source/receive_statistics_unittest.cc b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
index 29fc88d..b721b03 100644
--- a/modules/rtp_rtcp/source/receive_statistics_unittest.cc
+++ b/modules/rtp_rtcp/source/receive_statistics_unittest.cc
@@ -34,6 +34,7 @@
memset(&header, 0, sizeof(header));
header.ssrc = ssrc;
header.sequenceNumber = 100;
+ header.payload_type_frequency = 90000;
return header;
}
@@ -53,14 +54,14 @@
};
TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2);
++header2_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(100);
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2);
++header2_.sequenceNumber;
StreamStatistician* statistician =
@@ -83,9 +84,9 @@
EXPECT_EQ(2u, receive_statistics_->RtcpReportBlocks(3).size());
// Add more incoming packets and verify that they are registered in both
// access methods.
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2);
++header2_.sequenceNumber;
receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
@@ -103,9 +104,9 @@
RTPHeader header1 = CreateRtpHeader(kSsrc1);
RTPHeader header2 = CreateRtpHeader(kSsrc2);
RTPHeader header3 = CreateRtpHeader(kSsrc3);
- receive_statistics_->IncomingPacket(header1, kPacketSize1, false);
- receive_statistics_->IncomingPacket(header2, kPacketSize1, false);
- receive_statistics_->IncomingPacket(header3, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1, kPacketSize1);
+ receive_statistics_->IncomingPacket(header2, kPacketSize1);
+ receive_statistics_->IncomingPacket(header3, kPacketSize1);
EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
EXPECT_THAT(receive_statistics_->RtcpReportBlocks(2), SizeIs(2));
@@ -118,10 +119,10 @@
RTPHeader header2 = CreateRtpHeader(kSsrc2);
RTPHeader header3 = CreateRtpHeader(kSsrc3);
RTPHeader header4 = CreateRtpHeader(kSsrc4);
- receive_statistics_->IncomingPacket(header1, kPacketSize1, false);
- receive_statistics_->IncomingPacket(header2, kPacketSize1, false);
- receive_statistics_->IncomingPacket(header3, kPacketSize1, false);
- receive_statistics_->IncomingPacket(header4, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1, kPacketSize1);
+ receive_statistics_->IncomingPacket(header2, kPacketSize1);
+ receive_statistics_->IncomingPacket(header3, kPacketSize1);
+ receive_statistics_->IncomingPacket(header4, kPacketSize1);
std::vector<uint32_t> observed_ssrcs;
std::vector<rtcp::ReportBlock> report_blocks =
@@ -140,10 +141,10 @@
}
TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(1000);
- receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
+ receive_statistics_->IncomingPacket(header2_, kPacketSize2);
++header2_.sequenceNumber;
// Nothing should time out since only 1000 ms has passed since the first
// packet came in.
@@ -157,7 +158,7 @@
// kSsrc2 should have timed out.
EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
// kSsrc1 should be active again and the data counters should have survived.
EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
@@ -171,8 +172,19 @@
EXPECT_EQ(2u, packets_received);
}
+TEST_F(ReceiveStatisticsTest,
+ DoesntCreateRtcpReportBlockUntilFirstReceivedPacketForSsrc) {
+ // Creates a statistician object for the ssrc.
+ receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
+ EXPECT_TRUE(receive_statistics_->GetStatistician(kSsrc1) != nullptr);
+ EXPECT_EQ(0u, receive_statistics_->RtcpReportBlocks(3).size());
+ // Receive first packet
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
+ EXPECT_EQ(1u, receive_statistics_->RtcpReportBlocks(3).size());
+}
+
TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
StreamStatistician* statistician =
receive_statistics_->GetStatistician(kSsrc1);
ASSERT_TRUE(statistician != NULL);
@@ -182,7 +194,7 @@
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(1u, counters.transmitted.packets);
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
statistician->GetReceiveStreamDataCounters(&counters);
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(2u, counters.transmitted.packets);
@@ -210,24 +222,25 @@
} callback;
receive_statistics_->RegisterRtcpStatisticsCallback(&callback);
+ receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
// Add some arbitrary data, with loss and jitter.
header1_.sequenceNumber = 1;
clock_.AdvanceTimeMilliseconds(7);
header1_.timestamp += 3;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
header1_.sequenceNumber += 2;
clock_.AdvanceTimeMilliseconds(9);
header1_.timestamp += 9;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
--header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(13);
header1_.timestamp += 47;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
header1_.sequenceNumber += 3;
clock_.AdvanceTimeMilliseconds(11);
header1_.timestamp += 17;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
EXPECT_EQ(0u, callback.num_calls_);
@@ -247,7 +260,7 @@
EXPECT_EQ(51, statistics.fraction_lost);
EXPECT_EQ(1, statistics.packets_lost);
EXPECT_EQ(5u, statistics.extended_highest_sequence_number);
- EXPECT_EQ(4u, statistics.jitter);
+ EXPECT_EQ(177u, statistics.jitter);
receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
@@ -255,19 +268,19 @@
header1_.sequenceNumber = 1;
clock_.AdvanceTimeMilliseconds(7);
header1_.timestamp += 3;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
header1_.sequenceNumber += 2;
clock_.AdvanceTimeMilliseconds(9);
header1_.timestamp += 9;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
--header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(13);
header1_.timestamp += 47;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
header1_.sequenceNumber += 3;
clock_.AdvanceTimeMilliseconds(11);
header1_.timestamp += 17;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1);
++header1_.sequenceNumber;
receive_statistics_->GetStatistician(kSsrc1)->GetStatistics(&statistics,
@@ -316,14 +329,14 @@
TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
RtpTestCallback callback;
receive_statistics_->RegisterRtpStatisticsCallback(&callback);
+ receive_statistics_->EnableRetransmitDetection(kSsrc1, true);
const size_t kHeaderLength = 20;
const size_t kPaddingLength = 9;
// One packet of size kPacketSize1.
header1_.headerLength = kHeaderLength;
- receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength,
- false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength);
StreamDataCounters expected;
expected.transmitted.payload_bytes = kPacketSize1;
expected.transmitted.header_bytes = kHeaderLength;
@@ -341,7 +354,7 @@
header1_.paddingLength = 9;
// Another packet of size kPacketSize1 with 9 bytes padding.
receive_statistics_->IncomingPacket(
- header1_, kPacketSize1 + kHeaderLength + kPaddingLength, false);
+ header1_, kPacketSize1 + kHeaderLength + kPaddingLength);
expected.transmitted.payload_bytes = kPacketSize1 * 2;
expected.transmitted.header_bytes = kHeaderLength * 2;
expected.transmitted.padding_bytes = kPaddingLength;
@@ -351,7 +364,7 @@
clock_.AdvanceTimeMilliseconds(5);
// Retransmit last packet.
receive_statistics_->IncomingPacket(
- header1_, kPacketSize1 + kHeaderLength + kPaddingLength, true);
+ header1_, kPacketSize1 + kHeaderLength + kPaddingLength);
expected.transmitted.payload_bytes = kPacketSize1 * 3;
expected.transmitted.header_bytes = kHeaderLength * 3;
expected.transmitted.padding_bytes = kPaddingLength * 2;
@@ -366,8 +379,7 @@
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(5);
// One FEC packet.
- receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength,
- false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength);
receive_statistics_->FecPacketReceived(header1_,
kPacketSize1 + kHeaderLength);
expected.transmitted.payload_bytes = kPacketSize1 * 4;
@@ -383,8 +395,7 @@
// New stats, but callback should not be called.
++header1_.sequenceNumber;
clock_.AdvanceTimeMilliseconds(5);
- receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength,
- true);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength);
callback.Matches(5, kSsrc1, expected);
}
@@ -400,8 +411,7 @@
kPacketSize1 + kHeaderLength);
EXPECT_EQ(0u, callback.num_calls_);
- receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength,
- false);
+ receive_statistics_->IncomingPacket(header1_, kPacketSize1 + kHeaderLength);
StreamDataCounters expected;
expected.transmitted.payload_bytes = kPacketSize1;
expected.transmitted.header_bytes = kHeaderLength;
diff --git a/modules/rtp_rtcp/source/rtcp_packet/report_block.cc b/modules/rtp_rtcp/source/rtcp_packet/report_block.cc
index 4f98963..d4579fc 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/report_block.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/report_block.cc
@@ -54,7 +54,7 @@
source_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[0]);
fraction_lost_ = buffer[4];
- cumulative_lost_ = ByteReader<uint32_t, 3>::ReadBigEndian(&buffer[5]);
+ cumulative_lost_ = ByteReader<int32_t, 3>::ReadBigEndian(&buffer[5]);
extended_high_seq_num_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[8]);
jitter_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[12]);
last_sr_ = ByteReader<uint32_t>::ReadBigEndian(&buffer[16]);
diff --git a/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc b/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc
index a074a2f..5cc102f 100644
--- a/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_packet/report_block_unittest.cc
@@ -91,5 +91,20 @@
EXPECT_EQ(0u, rb.cumulative_lost());
}
+TEST(RtcpPacketReportBlockTest, ParseNegativeCumulativeLost) {
+ // CumulativeLost is a signed 24-bit integer.
+ const int32_t kNegativeCumulativeLost = -123;
+ ReportBlock rb;
+ EXPECT_TRUE(rb.SetCumulativeLost(kNegativeCumulativeLost));
+
+ uint8_t buffer[kBufferLength];
+ rb.Create(buffer);
+
+ ReportBlock parsed;
+ EXPECT_TRUE(parsed.Parse(buffer, kBufferLength));
+
+ EXPECT_EQ(kNegativeCumulativeLost, parsed.cumulative_lost_signed());
+}
+
} // namespace
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index 491bd45..4966754 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -19,8 +19,8 @@
#include <vector>
#include "api/video/video_bitrate_allocation.h"
+#include "api/video/video_bitrate_allocator.h"
#include "common_types.h" // NOLINT(build/include)
-#include "common_video/include/video_bitrate_allocator.h"
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.h b/modules/rtp_rtcp/source/rtcp_receiver.h
index c868837..a863cae 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -23,7 +23,6 @@
#include "rtc_base/criticalsection.h"
#include "rtc_base/thread_annotations.h"
#include "system_wrappers/include/ntp_time.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
class VideoBitrateAllocationObserver;
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 41d4725..6cd953c 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -12,8 +12,8 @@
#include "api/array_view.h"
#include "api/video/video_bitrate_allocation.h"
+#include "api/video/video_bitrate_allocator.h"
#include "common_types.h" // NOLINT(build/include)
-#include "common_video/include/video_bitrate_allocator.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
@@ -441,7 +441,7 @@
TEST_F(RtcpReceiverTest, InjectRrPacketsFromTwoRemoteSsrcs) {
const uint32_t kSenderSsrc2 = 0x20304;
const uint16_t kSequenceNumbers[] = {10, 12423};
- const uint32_t kCumLost[] = {13, 555};
+ const int32_t kCumLost[] = {13, 555};
const uint8_t kFracLost[] = {20, 11};
rtcp::ReportBlock rb1;
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index e274915..133bf68 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -33,7 +33,6 @@
#include "rtc_base/criticalsection.h"
#include "rtc_base/random.h"
#include "rtc_base/thread_annotations.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 974f19f..bccf96d 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -99,7 +99,7 @@
header.timestamp = 12345;
header.headerLength = 12;
size_t kPacketLength = 100;
- receive_statistics_->IncomingPacket(header, kPacketLength, false);
+ receive_statistics_->IncomingPacket(header, kPacketLength);
}
test::RtcpPacketParser* parser() { return &test_transport_.parser_; }
diff --git a/modules/rtp_rtcp/source/rtp_format.cc b/modules/rtp_rtcp/source/rtp_format.cc
index 8bd27a7..72beb17 100644
--- a/modules/rtp_rtcp/source/rtp_format.cc
+++ b/modules/rtp_rtcp/source/rtp_format.cc
@@ -12,37 +12,53 @@
#include <utility>
+#include "absl/memory/memory.h"
#include "modules/rtp_rtcp/source/rtp_format_h264.h"
#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "modules/rtp_rtcp/source/rtp_format_vp8.h"
#include "modules/rtp_rtcp/source/rtp_format_vp9.h"
namespace webrtc {
-RtpPacketizer* RtpPacketizer::Create(VideoCodecType type,
- size_t max_payload_len,
- size_t last_packet_reduction_len,
- const RTPVideoHeader* rtp_video_header,
- FrameType frame_type) {
+
+std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
+ VideoCodecType type,
+ rtc::ArrayView<const uint8_t> payload,
+ PayloadSizeLimits limits,
+ // Codec-specific details.
+ const RTPVideoHeader& rtp_video_header,
+ FrameType frame_type,
+ const RTPFragmentationHeader* fragmentation) {
switch (type) {
- case kVideoCodecH264:
- RTC_CHECK(rtp_video_header);
- return new RtpPacketizerH264(max_payload_len, last_packet_reduction_len,
- rtp_video_header->h264().packetization_mode);
- case kVideoCodecVP8:
- RTC_CHECK(rtp_video_header);
- return new RtpPacketizerVp8(rtp_video_header->vp8(), max_payload_len,
- last_packet_reduction_len);
- case kVideoCodecVP9:
- RTC_CHECK(rtp_video_header);
- return new RtpPacketizerVp9(rtp_video_header->vp9(), max_payload_len,
- last_packet_reduction_len);
- case kVideoCodecGeneric:
- return new RtpPacketizerGeneric(frame_type, max_payload_len,
- last_packet_reduction_len);
- default:
- RTC_NOTREACHED();
+ case kVideoCodecH264: {
+ const auto& h264 =
+ absl::get<RTPVideoHeaderH264>(rtp_video_header.video_type_header);
+ auto packetizer = absl::make_unique<RtpPacketizerH264>(
+ limits.max_payload_len, limits.last_packet_reduction_len,
+ h264.packetization_mode);
+ packetizer->SetPayloadData(payload.data(), payload.size(), fragmentation);
+ return std::move(packetizer);
+ }
+ case kVideoCodecVP8: {
+ const auto& vp8 =
+ absl::get<RTPVideoHeaderVP8>(rtp_video_header.video_type_header);
+ return absl::make_unique<RtpPacketizerVp8>(payload, limits, vp8);
+ }
+ case kVideoCodecVP9: {
+ const auto& vp9 =
+ absl::get<RTPVideoHeaderVP9>(rtp_video_header.video_type_header);
+ auto packetizer = absl::make_unique<RtpPacketizerVp9>(
+ vp9, limits.max_payload_len, limits.last_packet_reduction_len);
+ packetizer->SetPayloadData(payload.data(), payload.size(), nullptr);
+ return std::move(packetizer);
+ }
+ default: {
+ auto packetizer = absl::make_unique<RtpPacketizerGeneric>(
+ rtp_video_header, frame_type, limits.max_payload_len,
+ limits.last_packet_reduction_len);
+ packetizer->SetPayloadData(payload.data(), payload.size(), nullptr);
+ return std::move(packetizer);
+ }
}
- return nullptr;
}
RtpDepacketizer* RtpDepacketizer::Create(VideoCodecType type) {
@@ -53,11 +69,8 @@
return new RtpDepacketizerVp8();
case kVideoCodecVP9:
return new RtpDepacketizerVp9();
- case kVideoCodecGeneric:
- return new RtpDepacketizerGeneric();
default:
- RTC_NOTREACHED();
+ return new RtpDepacketizerGeneric();
}
- return nullptr;
}
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_format.h b/modules/rtp_rtcp/source/rtp_format.h
index 76d7f47..007ddbc 100644
--- a/modules/rtp_rtcp/source/rtp_format.h
+++ b/modules/rtp_rtcp/source/rtp_format.h
@@ -11,8 +11,10 @@
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H_
#define MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_H_
+#include <memory>
#include <string>
+#include "api/array_view.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -23,26 +25,28 @@
class RtpPacketizer {
public:
- static RtpPacketizer* Create(VideoCodecType type,
- size_t max_payload_len,
- size_t last_packet_reduction_len,
- const RTPVideoHeader* rtp_video_header,
- FrameType frame_type);
+ struct PayloadSizeLimits {
+ size_t max_payload_len = 1200;
+ size_t last_packet_reduction_len = 0;
+ };
+ static std::unique_ptr<RtpPacketizer> Create(
+ VideoCodecType type,
+ rtc::ArrayView<const uint8_t> payload,
+ PayloadSizeLimits limits,
+ // Codec-specific details.
+ const RTPVideoHeader& rtp_video_header,
+ FrameType frame_type,
+ const RTPFragmentationHeader* fragmentation);
- virtual ~RtpPacketizer() {}
+ virtual ~RtpPacketizer() = default;
- // Returns total number of packets which would be produced by the packetizer.
- virtual size_t SetPayloadData(
- const uint8_t* payload_data,
- size_t payload_size,
- const RTPFragmentationHeader* fragmentation) = 0;
+ // Returns number of remaining packets to produce by the packetizer.
+ virtual size_t NumPackets() const = 0;
// Get the next payload with payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
virtual bool NextPacket(RtpPacketToSend* packet) = 0;
-
- virtual std::string ToString() = 0;
};
// TODO(sprang): Update the depacketizer to return a std::unqie_ptr with a copy
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.cc b/modules/rtp_rtcp/source/rtp_format_h264.cc
index 0b8c15f..373cce9 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264.cc
@@ -182,6 +182,10 @@
return num_packets_left_;
}
+size_t RtpPacketizerH264::NumPackets() const {
+ return num_packets_left_;
+}
+
bool RtpPacketizerH264::GeneratePackets() {
for (size_t i = 0; i < input_fragments_.size();) {
switch (packetization_mode_) {
@@ -408,10 +412,6 @@
packets_.pop();
}
-std::string RtpPacketizerH264::ToString() {
- return "RtpPacketizerH264";
-}
-
RtpDepacketizerH264::RtpDepacketizerH264() : offset_(0), length_(0) {}
RtpDepacketizerH264::~RtpDepacketizerH264() {}
@@ -429,7 +429,8 @@
modified_buffer_.reset();
uint8_t nal_type = payload_data[0] & kTypeMask;
- parsed_payload->video_header().h264().nalus_length = 0;
+ parsed_payload->video_header()
+ .video_type_header.emplace<RTPVideoHeaderH264>();
if (nal_type == H264::NaluType::kFuA) {
// Fragmented NAL units (FU-A).
if (!ParseFuaNalu(parsed_payload, payload_data))
@@ -458,7 +459,8 @@
parsed_payload->video_header().codec = kVideoCodecH264;
parsed_payload->video_header().simulcastIdx = 0;
parsed_payload->video_header().is_first_packet_in_frame = true;
- RTPVideoHeaderH264* h264_header = &parsed_payload->video_header().h264();
+ auto& h264_header = absl::get<RTPVideoHeaderH264>(
+ parsed_payload->video_header().video_type_header);
const uint8_t* nalu_start = payload_data + kNalHeaderSize;
const size_t nalu_length = length_ - kNalHeaderSize;
@@ -476,13 +478,13 @@
return false;
}
- h264_header->packetization_type = kH264StapA;
+ h264_header.packetization_type = kH264StapA;
nal_type = payload_data[kStapAHeaderSize] & kTypeMask;
} else {
- h264_header->packetization_type = kH264SingleNalu;
+ h264_header.packetization_type = kH264SingleNalu;
nalu_start_offsets.push_back(0);
}
- h264_header->nalu_type = nal_type;
+ h264_header.nalu_type = nal_type;
parsed_payload->frame_type = kVideoFrameDelta;
nalu_start_offsets.push_back(length_ + kLengthFieldSize); // End offset.
@@ -528,7 +530,7 @@
}
// Rewrite length field to new SPS size.
- if (h264_header->packetization_type == kH264StapA) {
+ if (h264_header.packetization_type == kH264StapA) {
size_t length_field_offset =
start_offset - (H264::kNaluTypeSize + kLengthFieldSize);
// Stap-A Length includes payload data and type header.
@@ -617,13 +619,13 @@
RTC_LOG(LS_WARNING) << "Unexpected STAP-A or FU-A received.";
return false;
}
- RTPVideoHeaderH264* h264 = &parsed_payload->video_header().h264();
- if (h264->nalus_length == kMaxNalusPerPacket) {
+
+ if (h264_header.nalus_length == kMaxNalusPerPacket) {
RTC_LOG(LS_WARNING)
<< "Received packet containing more than " << kMaxNalusPerPacket
<< " NAL units. Will not keep track sps and pps ids for all of them.";
} else {
- h264->nalus[h264->nalus_length++] = nalu;
+ h264_header.nalus[h264_header.nalus_length++] = nalu;
}
}
@@ -676,12 +678,13 @@
parsed_payload->video_header().codec = kVideoCodecH264;
parsed_payload->video_header().simulcastIdx = 0;
parsed_payload->video_header().is_first_packet_in_frame = first_fragment;
- RTPVideoHeaderH264* h264 = &parsed_payload->video_header().h264();
- h264->packetization_type = kH264FuA;
- h264->nalu_type = original_nal_type;
+ auto& h264_header = absl::get<RTPVideoHeaderH264>(
+ parsed_payload->video_header().video_type_header);
+ h264_header.packetization_type = kH264FuA;
+ h264_header.nalu_type = original_nal_type;
if (first_fragment) {
- h264->nalus[h264->nalus_length] = nalu;
- h264->nalus_length = 1;
+ h264_header.nalus[h264_header.nalus_length] = nalu;
+ h264_header.nalus_length = 1;
}
return true;
}
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.h b/modules/rtp_rtcp/source/rtp_format_h264.h
index 99b080b..1f6702a 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.h
+++ b/modules/rtp_rtcp/source/rtp_format_h264.h
@@ -34,15 +34,15 @@
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
- const RTPFragmentationHeader* fragmentation) override;
+ const RTPFragmentationHeader* fragmentation);
+
+ size_t NumPackets() const override;
// Get the next payload with H264 payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
bool NextPacket(RtpPacketToSend* rtp_packet) override;
- std::string ToString() override;
-
private:
// Input fragments (NAL units), with an optionally owned temporary buffer,
// used in case the fragment gets modified.
diff --git a/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc b/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
index dc17b4f..0183a6a 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
@@ -16,7 +16,7 @@
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "modules/rtp_rtcp/source/byte_io.h"
-#include "modules/rtp_rtcp/source/rtp_format.h"
+#include "modules/rtp_rtcp/source/rtp_format_h264.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "test/gmock.h"
#include "test/gtest.h"
@@ -26,6 +26,12 @@
using ::testing::ElementsAreArray;
+struct H264ParsedPayload : public RtpDepacketizer::ParsedPayload {
+ RTPVideoHeaderH264& h264() {
+ return absl::get<RTPVideoHeaderH264>(video.video_type_header);
+ }
+};
+
constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
const size_t kMaxPayloadSize = 1200;
const size_t kLengthFieldLength = 2;
@@ -62,13 +68,12 @@
kNalHeaderSize + frameSize - payloadOffset;
}
-RtpPacketizer* CreateH264Packetizer(H264PacketizationMode mode,
- size_t max_payload_size,
- size_t last_packet_reduction) {
- RTPVideoHeader header;
- header.h264().packetization_mode = mode;
- return RtpPacketizer::Create(kVideoCodecH264, max_payload_size,
- last_packet_reduction, &header, kEmptyFrame);
+std::unique_ptr<RtpPacketizerH264> CreateH264Packetizer(
+ H264PacketizationMode mode,
+ size_t max_payload_size,
+ size_t last_packet_reduction) {
+ return absl::make_unique<RtpPacketizerH264>(max_payload_size,
+ last_packet_reduction, mode);
}
void VerifyFua(size_t fua_index,
@@ -111,7 +116,7 @@
fragmentation.VerifyAndAllocateFragmentationHeader(1);
fragmentation.fragmentationOffset[0] = 0;
fragmentation.fragmentationLength[0] = frame_size;
- std::unique_ptr<RtpPacketizer> packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
max_payload_size, last_packet_reduction));
EXPECT_EQ(
@@ -184,7 +189,7 @@
fragmentation.VerifyAndAllocateFragmentationHeader(1);
fragmentation.fragmentationOffset[0] = 0;
fragmentation.fragmentationLength[0] = sizeof(frame);
- std::unique_ptr<RtpPacketizer> packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
ASSERT_EQ(1u,
packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation));
@@ -211,7 +216,7 @@
frame[fragmentation.fragmentationOffset[0]] = 0x01;
frame[fragmentation.fragmentationOffset[1]] = 0x01;
- std::unique_ptr<RtpPacketizer> packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@@ -244,7 +249,7 @@
frame[i + kPayloadOffset] = i;
RTPFragmentationHeader fragmentation;
CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
- std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(1u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@@ -279,7 +284,7 @@
fragmentation.fragmentationOffset[2] = 4;
fragmentation.fragmentationLength[2] =
kNalHeaderSize + kFrameSize - kPayloadOffset;
- std::unique_ptr<RtpPacketizer> packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
kMaxPayloadSize, kLastPacketReduction));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@@ -316,7 +321,7 @@
frame[i + kPayloadOffset] = i;
RTPFragmentationHeader fragmentation;
CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
- std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
@@ -345,7 +350,7 @@
fragmentation.fragmentationOffset[2] = 4;
fragmentation.fragmentationLength[2] =
kNalHeaderSize + kFrameSize - kPayloadOffset;
- std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@@ -390,7 +395,7 @@
frame[nalu_offset + j] = i + j;
}
}
- std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(3u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
@@ -479,7 +484,7 @@
// Set NAL headers.
frame[fragmentation.fragmentationOffset[0]] = 0x01;
- std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
+ std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
EXPECT_EQ(0u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
}
@@ -517,16 +522,16 @@
protected:
rtc::Buffer in_buffer_;
RTPFragmentationHeader fragmentation_header_;
- std::unique_ptr<RtpPacketizer> packetizer_;
+ std::unique_ptr<RtpPacketizerH264> packetizer_;
};
TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
const size_t kHeaderOverhead = kFuAHeaderSize + 1;
// Set size to fragment SPS into two FU-A packets.
- packetizer_.reset(
+ packetizer_ =
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
- sizeof(kOriginalSps) - 2 + kHeaderOverhead, 0));
+ sizeof(kOriginalSps) - 2 + kHeaderOverhead, 0);
packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
&fragmentation_header_);
@@ -557,9 +562,8 @@
sizeof(kIdrTwo) + (kLengthFieldLength * 3);
// Set size to include SPS and the rest of the packets in a Stap-A package.
- packetizer_.reset(CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
- kExpectedTotalSize + kHeaderOverhead,
- 0));
+ packetizer_ = CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
+ kExpectedTotalSize + kHeaderOverhead, 0);
packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
&fragmentation_header_);
@@ -579,7 +583,7 @@
RtpDepacketizerH264Test()
: depacketizer_(RtpDepacketizer::Create(kVideoCodecH264)) {}
- void ExpectPacket(RtpDepacketizer::ParsedPayload* parsed_payload,
+ void ExpectPacket(H264ParsedPayload* parsed_payload,
const uint8_t* data,
size_t length) {
ASSERT_TRUE(parsed_payload != NULL);
@@ -594,29 +598,29 @@
TEST_F(RtpDepacketizerH264Test, TestSingleNalu) {
uint8_t packet[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5 (IDR).
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
ExpectPacket(&payload, packet, sizeof(packet));
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264SingleNalu, payload.video_header().h264().packetization_type);
- EXPECT_EQ(kIdr, payload.video_header().h264().nalu_type);
+ EXPECT_EQ(kH264SingleNalu, payload.h264().packetization_type);
+ EXPECT_EQ(kIdr, payload.h264().nalu_type);
}
TEST_F(RtpDepacketizerH264Test, TestSingleNaluSpsWithResolution) {
uint8_t packet[] = {kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50,
0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0,
0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
ExpectPacket(&payload, packet, sizeof(packet));
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264SingleNalu, payload.video_header().h264().packetization_type);
+ EXPECT_EQ(kH264SingleNalu, payload.h264().packetization_type);
EXPECT_EQ(1280u, payload.video_header().width);
EXPECT_EQ(720u, payload.video_header().height);
}
@@ -639,13 +643,13 @@
0x85, 0xB8, 0x0, 0x4, 0x0, 0x0, 0x13, 0x93, 0x12, 0x0};
// clang-format on
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
ExpectPacket(&payload, packet, sizeof(packet));
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- const RTPVideoHeaderH264& h264 = payload.video_header().h264();
+ const RTPVideoHeaderH264& h264 = payload.h264();
EXPECT_EQ(kH264StapA, h264.packetization_type);
// NALU type for aggregated packets is the type of the first packet only.
EXPECT_EQ(kSps, h264.nalu_type);
@@ -669,14 +673,14 @@
0x00, 0x03, kIdr, 0xFF, 0x00, 0x00, 0x04, kIdr, 0xFF,
0x00, 0x11};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
ExpectPacket(&payload, packet, sizeof(packet));
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264StapA, payload.video_header().h264().packetization_type);
+ EXPECT_EQ(kH264StapA, payload.h264().packetization_type);
EXPECT_EQ(1280u, payload.video_header().width);
EXPECT_EQ(720u, payload.video_header().height);
}
@@ -693,7 +697,7 @@
uint8_t trailing_empty_packet[] = {kStapA, 0x00, 0x03, kIdr,
0xFF, 0x00, 0x00, 0x00};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_FALSE(depacketizer_->Parse(&payload, lone_empty_packet,
sizeof(lone_empty_packet)));
@@ -732,7 +736,7 @@
out_buffer.AppendData(kHeader, 2);
out_buffer.AppendData(kIdrTwo);
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_TRUE(
depacketizer_->Parse(&payload, in_buffer.data(), in_buffer.size()));
@@ -779,7 +783,7 @@
out_buffer.AppendData(kHeader, 2);
out_buffer.AppendData(kIdrTwo);
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_TRUE(
depacketizer_->Parse(&payload, in_buffer.data(), in_buffer.size()));
@@ -796,16 +800,16 @@
// Length, nal header, payload.
0, 0x02, kSlice, 0xFF, 0, 0x03, kSlice, 0xFF, 0x00, 0,
0x04, kSlice, 0xFF, 0x00, 0x11};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
ExpectPacket(&payload, packet, sizeof(packet));
EXPECT_EQ(kVideoFrameDelta, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264StapA, payload.video_header().h264().packetization_type);
+ EXPECT_EQ(kH264StapA, payload.h264().packetization_type);
// NALU type for aggregated packets is the type of the first packet only.
- EXPECT_EQ(kSlice, payload.video_header().h264().nalu_type);
+ EXPECT_EQ(kSlice, payload.h264().nalu_type);
}
TEST_F(RtpDepacketizerH264Test, TestFuA) {
@@ -833,7 +837,7 @@
};
const uint8_t kExpected3[] = {0x03};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
// We expect that the first packet is one byte shorter since the FU-A header
// has been replaced by the original nal header.
@@ -842,7 +846,7 @@
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- const RTPVideoHeaderH264& h264 = payload.video_header().h264();
+ const RTPVideoHeaderH264& h264 = payload.h264();
EXPECT_EQ(kH264FuA, h264.packetization_type);
EXPECT_EQ(kIdr, h264.nalu_type);
ASSERT_EQ(1u, h264.nalus_length);
@@ -852,28 +856,28 @@
// Following packets will be 2 bytes shorter since they will only be appended
// onto the first packet.
- payload = RtpDepacketizer::ParsedPayload();
+ payload = H264ParsedPayload();
ASSERT_TRUE(depacketizer_->Parse(&payload, packet2, sizeof(packet2)));
ExpectPacket(&payload, kExpected2, sizeof(kExpected2));
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_FALSE(payload.video_header().is_first_packet_in_frame);
{
- const RTPVideoHeaderH264& h264 = payload.video_header().h264();
+ const RTPVideoHeaderH264& h264 = payload.h264();
EXPECT_EQ(kH264FuA, h264.packetization_type);
EXPECT_EQ(kIdr, h264.nalu_type);
// NALU info is only expected for the first FU-A packet.
EXPECT_EQ(0u, h264.nalus_length);
}
- payload = RtpDepacketizer::ParsedPayload();
+ payload = H264ParsedPayload();
ASSERT_TRUE(depacketizer_->Parse(&payload, packet3, sizeof(packet3)));
ExpectPacket(&payload, kExpected3, sizeof(kExpected3));
EXPECT_EQ(kVideoFrameKey, payload.frame_type);
EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
EXPECT_FALSE(payload.video_header().is_first_packet_in_frame);
{
- const RTPVideoHeaderH264& h264 = payload.video_header().h264();
+ const RTPVideoHeaderH264& h264 = payload.h264();
EXPECT_EQ(kH264FuA, h264.packetization_type);
EXPECT_EQ(kIdr, h264.nalu_type);
// NALU info is only expected for the first FU-A packet.
@@ -884,37 +888,37 @@
TEST_F(RtpDepacketizerH264Test, TestEmptyPayload) {
// Using a wild pointer to crash on accesses from inside the depacketizer.
uint8_t* garbage_ptr = reinterpret_cast<uint8_t*>(0x4711);
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_FALSE(depacketizer_->Parse(&payload, garbage_ptr, 0));
}
TEST_F(RtpDepacketizerH264Test, TestTruncatedFuaNalu) {
const uint8_t kPayload[] = {0x9c};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
}
TEST_F(RtpDepacketizerH264Test, TestTruncatedSingleStapANalu) {
const uint8_t kPayload[] = {0xd8, 0x27};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
}
TEST_F(RtpDepacketizerH264Test, TestStapAPacketWithTruncatedNalUnits) {
const uint8_t kPayload[] = {0x58, 0xCB, 0xED, 0xDF};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
}
TEST_F(RtpDepacketizerH264Test, TestTruncationJustAfterSingleStapANalu) {
const uint8_t kPayload[] = {0x38, 0x27, 0x27};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
}
TEST_F(RtpDepacketizerH264Test, TestShortSpsPacket) {
const uint8_t kPayload[] = {0x27, 0x80, 0x00};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
EXPECT_TRUE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
}
@@ -923,9 +927,9 @@
kSei, // F=0, NRI=0, Type=6.
0x03, 0x03, 0x03, 0x03 // Payload.
};
- RtpDepacketizer::ParsedPayload payload;
+ H264ParsedPayload payload;
ASSERT_TRUE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
- const RTPVideoHeaderH264& h264 = payload.video_header().h264();
+ const RTPVideoHeaderH264& h264 = payload.h264();
EXPECT_EQ(kVideoFrameDelta, payload.frame_type);
EXPECT_EQ(kH264SingleNalu, h264.packetization_type);
EXPECT_EQ(kSei, h264.nalu_type);
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.cc b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
index a2a3ad1..1731237 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.cc
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.cc
@@ -18,13 +18,21 @@
namespace webrtc {
static const size_t kGenericHeaderLength = 1;
+static const size_t kExtendedHeaderLength = 2;
-RtpPacketizerGeneric::RtpPacketizerGeneric(FrameType frame_type,
- size_t max_payload_len,
- size_t last_packet_reduction_len)
- : payload_data_(NULL),
+RtpPacketizerGeneric::RtpPacketizerGeneric(
+ const RTPVideoHeader& rtp_video_header,
+ FrameType frame_type,
+ size_t max_payload_len,
+ size_t last_packet_reduction_len)
+ : picture_id_(rtp_video_header.generic
+ ? absl::optional<uint16_t>(
+ rtp_video_header.generic->frame_id & 0x7FFF)
+ : absl::nullopt),
+ payload_data_(nullptr),
payload_size_(0),
- max_payload_len_(max_payload_len - kGenericHeaderLength),
+ max_payload_len_(max_payload_len - kGenericHeaderLength -
+ (picture_id_.has_value() ? kExtendedHeaderLength : 0)),
last_packet_reduction_len_(last_packet_reduction_len),
frame_type_(frame_type),
num_packets_left_(0),
@@ -62,6 +70,14 @@
if (frame_type_ == kVideoFrameKey) {
generic_header_ |= RtpFormatVideoGeneric::kKeyFrameBit;
}
+ if (picture_id_.has_value()) {
+ generic_header_ |= RtpFormatVideoGeneric::kExtendedHeaderBit;
+ }
+
+ return num_packets_left_;
+}
+
+size_t RtpPacketizerGeneric::NumPackets() const {
return num_packets_left_;
}
@@ -86,16 +102,24 @@
}
RTC_DCHECK_LE(next_packet_payload_len, max_payload_len_);
- uint8_t* out_ptr =
- packet->AllocatePayload(kGenericHeaderLength + next_packet_payload_len);
+ size_t total_length = next_packet_payload_len + kGenericHeaderLength +
+ (picture_id_.has_value() ? kExtendedHeaderLength : 0);
+ uint8_t* out_ptr = packet->AllocatePayload(total_length);
+
// Put generic header in packet.
out_ptr[0] = generic_header_;
+ out_ptr += kGenericHeaderLength;
+
+ if (picture_id_.has_value()) {
+ WriteExtendedHeader(out_ptr);
+ out_ptr += kExtendedHeaderLength;
+ }
+
// Remove first-packet bit, following packets are intermediate.
generic_header_ &= ~RtpFormatVideoGeneric::kFirstPacketBit;
// Put payload in packet.
- memcpy(out_ptr + kGenericHeaderLength, payload_data_,
- next_packet_payload_len);
+ memcpy(out_ptr, payload_data_, next_packet_payload_len);
payload_data_ += next_packet_payload_len;
payload_size_ -= next_packet_payload_len;
--num_packets_left_;
@@ -107,8 +131,11 @@
return true;
}
-std::string RtpPacketizerGeneric::ToString() {
- return "RtpPacketizerGeneric";
+void RtpPacketizerGeneric::WriteExtendedHeader(uint8_t* out_ptr) {
+ // Store bottom 15 bits of the the sequence number. Only 15 bits are used for
+ // compatibility with other packetizer implemenetations that also use 15 bits.
+ out_ptr[0] = (*picture_id_ >> 8) & 0x7F;
+ out_ptr[1] = *picture_id_ & 0xFF;
}
RtpDepacketizerGeneric::~RtpDepacketizerGeneric() = default;
@@ -118,7 +145,7 @@
size_t payload_data_length) {
assert(parsed_payload != NULL);
if (payload_data_length == 0) {
- RTC_LOG(LS_ERROR) << "Empty payload.";
+ RTC_LOG(LS_WARNING) << "Empty payload.";
return false;
}
@@ -135,6 +162,18 @@
parsed_payload->video_header().width = 0;
parsed_payload->video_header().height = 0;
+ if (generic_header & RtpFormatVideoGeneric::kExtendedHeaderBit) {
+ if (payload_data_length < kExtendedHeaderLength) {
+ RTC_LOG(LS_WARNING) << "Too short payload for generic header.";
+ return false;
+ }
+ parsed_payload->video_header().generic.emplace();
+ parsed_payload->video_header().generic->frame_id =
+ ((payload_data[0] & 0x7F) << 8) | payload_data[1];
+ payload_data += kExtendedHeaderLength;
+ payload_data_length -= kExtendedHeaderLength;
+ }
+
parsed_payload->payload = payload_data;
parsed_payload->payload_length = payload_data_length;
return true;
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic.h b/modules/rtp_rtcp/source/rtp_format_video_generic.h
index 9a916bf..293b6e9 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic.h
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic.h
@@ -15,19 +15,22 @@
#include "common_types.h" // NOLINT(build/include)
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace RtpFormatVideoGeneric {
static const uint8_t kKeyFrameBit = 0x01;
static const uint8_t kFirstPacketBit = 0x02;
+// If this bit is set, there will be an extended header contained in this
+// packet. This was added later so old clients will not send this.
+static const uint8_t kExtendedHeaderBit = 0x04;
} // namespace RtpFormatVideoGeneric
class RtpPacketizerGeneric : public RtpPacketizer {
public:
// Initialize with payload from encoder.
// The payload_data must be exactly one encoded generic frame.
- RtpPacketizerGeneric(FrameType frametype,
+ RtpPacketizerGeneric(const RTPVideoHeader& rtp_video_header,
+ FrameType frametype,
size_t max_payload_len,
size_t last_packet_reduction_len);
@@ -36,16 +39,17 @@
// Returns total number of packets to be generated.
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
- const RTPFragmentationHeader* fragmentation) override;
+ const RTPFragmentationHeader* fragmentation);
+
+ size_t NumPackets() const override;
// Get the next payload with generic payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
bool NextPacket(RtpPacketToSend* packet) override;
- std::string ToString() override;
-
private:
+ const absl::optional<uint16_t> picture_id_;
const uint8_t* payload_data_;
size_t payload_size_;
const size_t max_payload_len_;
@@ -58,6 +62,8 @@
// Number of packets, which will be 1 byte more than the rest.
size_t num_larger_packets_;
+ void WriteExtendedHeader(uint8_t* out_ptr);
+
RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerGeneric);
};
diff --git a/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc b/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc
index 983bd8f..e77dabf 100644
--- a/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_video_generic_unittest.cc
@@ -63,8 +63,8 @@
const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -78,8 +78,8 @@
const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -93,8 +93,8 @@
const size_t kMaxPayloadLen = 6;
const size_t kLastPacketReductionLen = 2;
const size_t kPayloadSize = 13;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -114,8 +114,8 @@
// generic header lengh for each packet minus last packet reduction).
// 4 packets is enough for kPayloadSize.
const size_t kMinNumPackets = 4;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -128,8 +128,8 @@
const size_t kMaxPayloadLen = 8;
const size_t kLastPacketReductionLen = 5;
const size_t kPayloadSize = 28;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -143,8 +143,8 @@
const size_t kMaxPayloadLen = 8;
const size_t kLastPacketReductionLen = 5;
const size_t kPayloadSize = 28;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -158,8 +158,8 @@
const size_t kMaxPayloadLen = 8;
const size_t kLastPacketReductionLen = 5;
const size_t kPayloadSize = 28;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -179,8 +179,8 @@
// generic header lengh for each packet minus last packet reduction).
// 5 packets is enough for kPayloadSize.
const size_t kMinNumPackets = 5;
- RtpPacketizerGeneric packetizer(kVideoFrameKey, kMaxPayloadLen,
- kLastPacketReductionLen);
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
size_t num_packets =
packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
std::vector<size_t> payload_sizes = NextPacketFillPayloadSizes(&packetizer);
@@ -189,4 +189,85 @@
EXPECT_EQ(num_packets, kMinNumPackets);
}
+TEST(RtpPacketizerVideoGeneric, HasFrameIdWritesExtendedHeader) {
+ const size_t kMaxPayloadLen = 6;
+ const size_t kLastPacketReductionLen = 2;
+ const size_t kPayloadSize = 13;
+
+ RTPVideoHeader rtp_video_header;
+ rtp_video_header.generic.emplace().frame_id = 37;
+ RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
+ packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
+
+ RtpPacketToSend packet(nullptr);
+ packetizer.NextPacket(&packet);
+
+ rtc::ArrayView<const uint8_t> payload = packet.payload();
+ EXPECT_TRUE(payload[0] & 0x04); // Extended header bit is set.
+ // Frame id is 37.
+ EXPECT_EQ(0u, payload[1]);
+ EXPECT_EQ(37u, payload[2]);
+}
+
+TEST(RtpPacketizerVideoGeneric, FrameIdOver15bitsWrapsAround) {
+ const size_t kMaxPayloadLen = 6;
+ const size_t kLastPacketReductionLen = 2;
+ const size_t kPayloadSize = 13;
+
+ RTPVideoHeader rtp_video_header;
+ rtp_video_header.generic.emplace().frame_id = 0x8137;
+ RtpPacketizerGeneric packetizer(rtp_video_header, kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
+ packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
+
+ RtpPacketToSend packet(nullptr);
+ packetizer.NextPacket(&packet);
+
+ rtc::ArrayView<const uint8_t> payload = packet.payload();
+ EXPECT_TRUE(payload[0] & 0x04); // Extended header bit is set.
+ // Frame id is 0x137.
+ EXPECT_EQ(0x01u, payload[1]);
+ EXPECT_EQ(0x37u, payload[2]);
+}
+
+TEST(RtpPacketizerVideoGeneric, NoFrameIdDoesNotWriteExtendedHeader) {
+ const size_t kMaxPayloadLen = 6;
+ const size_t kLastPacketReductionLen = 2;
+ const size_t kPayloadSize = 13;
+
+ RtpPacketizerGeneric packetizer(RTPVideoHeader(), kVideoFrameKey,
+ kMaxPayloadLen, kLastPacketReductionLen);
+ packetizer.SetPayloadData(kTestPayload, kPayloadSize, nullptr);
+
+ RtpPacketToSend packet(nullptr);
+ packetizer.NextPacket(&packet);
+
+ rtc::ArrayView<const uint8_t> payload = packet.payload();
+ EXPECT_FALSE(payload[0] & 0x04);
+}
+
+TEST(RtpDepacketizerVideoGeneric, NonExtendedHeaderNoFrameId) {
+ const size_t kPayloadLen = 1;
+ uint8_t payload[kPayloadLen] = {0x01};
+
+ RtpDepacketizerGeneric depacketizer;
+ RtpDepacketizer::ParsedPayload parsed_payload;
+ depacketizer.Parse(&parsed_payload, payload, kPayloadLen);
+
+ EXPECT_FALSE(parsed_payload.video_header().generic);
+}
+
+TEST(RtpDepacketizerVideoGeneric, ExtendedHeaderParsesFrameId) {
+ const size_t kPayloadLen = 3;
+ uint8_t payload[kPayloadLen] = {0x05, 0x13, 0x37};
+
+ RtpDepacketizerGeneric depacketizer;
+ RtpDepacketizer::ParsedPayload parsed_payload;
+ depacketizer.Parse(&parsed_payload, payload, kPayloadLen);
+
+ ASSERT_TRUE(parsed_payload.video_header().generic);
+ EXPECT_EQ(0x1337, parsed_payload.video_header().generic->frame_id);
+}
+
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.cc b/modules/rtp_rtcp/source/rtp_format_vp8.cc
index 48c7351..4a511fc 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp8.cc
@@ -22,6 +22,10 @@
namespace webrtc {
namespace {
+
+// Length of VP8 payload descriptors' fixed part.
+constexpr int kVp8FixedPayloadDescriptorSize = 1;
+
int ParseVP8PictureID(RTPVideoHeaderVP8* vp8,
const uint8_t** data,
size_t* data_length,
@@ -158,29 +162,17 @@
} // namespace
-RtpPacketizerVp8::RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
- size_t max_payload_len,
- size_t last_packet_reduction_len)
- : payload_data_(NULL),
- payload_size_(0),
- vp8_fixed_payload_descriptor_bytes_(1),
- hdr_info_(hdr_info),
- max_payload_len_(max_payload_len),
- last_packet_reduction_len_(last_packet_reduction_len) {
+RtpPacketizerVp8::RtpPacketizerVp8(rtc::ArrayView<const uint8_t> payload,
+ PayloadSizeLimits limits,
+ const RTPVideoHeaderVP8& hdr_info)
+ : payload_data_(payload.data()), hdr_info_(hdr_info), limits_(limits) {
RTC_DCHECK(ValidateHeader(hdr_info));
+ GeneratePackets(payload.size());
}
-RtpPacketizerVp8::~RtpPacketizerVp8() {}
+RtpPacketizerVp8::~RtpPacketizerVp8() = default;
-size_t RtpPacketizerVp8::SetPayloadData(
- const uint8_t* payload_data,
- size_t payload_size,
- const RTPFragmentationHeader* /* fragmentation */) {
- payload_data_ = payload_data;
- payload_size_ = payload_size;
- if (GeneratePackets() < 0) {
- return 0;
- }
+size_t RtpPacketizerVp8::NumPackets() const {
return packets_.size();
}
@@ -192,10 +184,12 @@
InfoStruct packet_info = packets_.front();
packets_.pop();
- uint8_t* buffer = packet->AllocatePayload(
- packets_.empty() ? max_payload_len_ - last_packet_reduction_len_
- : max_payload_len_);
- int bytes = WriteHeaderAndPayload(packet_info, buffer, max_payload_len_);
+ size_t packet_payload_len =
+ packets_.empty()
+ ? limits_.max_payload_len - limits_.last_packet_reduction_len
+ : limits_.max_payload_len;
+ uint8_t* buffer = packet->AllocatePayload(packet_payload_len);
+ int bytes = WriteHeaderAndPayload(packet_info, buffer, packet_payload_len);
if (bytes < 0) {
return false;
}
@@ -204,33 +198,20 @@
return true;
}
-std::string RtpPacketizerVp8::ToString() {
- return "RtpPacketizerVp8";
-}
-
-int RtpPacketizerVp8::GeneratePackets() {
- if (max_payload_len_ < vp8_fixed_payload_descriptor_bytes_ +
- PayloadDescriptorExtraLength() + 1 +
- last_packet_reduction_len_) {
+void RtpPacketizerVp8::GeneratePackets(size_t payload_len) {
+ if (limits_.max_payload_len - limits_.last_packet_reduction_len <
+ kVp8FixedPayloadDescriptorSize + PayloadDescriptorExtraLength() + 1) {
// The provided payload length is not long enough for the payload
// descriptor and one payload byte in the last packet.
- // Return an error.
- return -1;
+ return;
}
- size_t per_packet_capacity =
- max_payload_len_ -
- (vp8_fixed_payload_descriptor_bytes_ + PayloadDescriptorExtraLength());
+ size_t capacity = limits_.max_payload_len - (kVp8FixedPayloadDescriptorSize +
+ PayloadDescriptorExtraLength());
- GeneratePacketsSplitPayloadBalanced(payload_size_, per_packet_capacity);
- return 0;
-}
-
-void RtpPacketizerVp8::GeneratePacketsSplitPayloadBalanced(size_t payload_len,
- size_t capacity) {
// Last packet of the last partition is smaller. Pretend that it's the same
// size, but we must write more payload to it.
- size_t total_bytes = payload_len + last_packet_reduction_len_;
+ size_t total_bytes = payload_len + limits_.last_packet_reduction_len;
// Integer divisions with rounding up.
size_t num_packets_left = (total_bytes + capacity - 1) / capacity;
size_t bytes_per_packet = total_bytes / num_packets_left;
@@ -251,7 +232,7 @@
--current_packet_bytes;
}
QueuePacket(payload_len - remaining_data, current_packet_bytes,
- remaining_data == payload_len);
+ /*first_packet=*/remaining_data == payload_len);
remaining_data -= current_packet_bytes;
--num_packets_left;
}
@@ -299,19 +280,18 @@
if (extension_length < 0)
return -1;
- memcpy(&buffer[vp8_fixed_payload_descriptor_bytes_ + extension_length],
+ memcpy(&buffer[kVp8FixedPayloadDescriptorSize + extension_length],
&payload_data_[packet_info.payload_start_pos], packet_info.size);
// Return total length of written data.
- return packet_info.size + vp8_fixed_payload_descriptor_bytes_ +
- extension_length;
+ return packet_info.size + kVp8FixedPayloadDescriptorSize + extension_length;
}
int RtpPacketizerVp8::WriteExtensionFields(uint8_t* buffer,
size_t buffer_length) const {
size_t extension_length = 0;
if (XFieldPresent()) {
- uint8_t* x_field = buffer + vp8_fixed_payload_descriptor_bytes_;
+ uint8_t* x_field = buffer + kVp8FixedPayloadDescriptorSize;
*x_field = 0;
extension_length = 1; // One octet for the X field.
if (PictureIdPresent()) {
@@ -343,10 +323,10 @@
size_t* extension_length) const {
*x_field |= kIBit;
RTC_DCHECK_GE(buffer_length,
- vp8_fixed_payload_descriptor_bytes_ + *extension_length);
+ kVp8FixedPayloadDescriptorSize + *extension_length);
const int pic_id_length = WritePictureID(
- buffer + vp8_fixed_payload_descriptor_bytes_ + *extension_length,
- buffer_length - vp8_fixed_payload_descriptor_bytes_ - *extension_length);
+ buffer + kVp8FixedPayloadDescriptorSize + *extension_length,
+ buffer_length - kVp8FixedPayloadDescriptorSize - *extension_length);
if (pic_id_length < 0)
return -1;
*extension_length += pic_id_length;
@@ -372,12 +352,11 @@
uint8_t* buffer,
size_t buffer_length,
size_t* extension_length) const {
- if (buffer_length <
- vp8_fixed_payload_descriptor_bytes_ + *extension_length + 1) {
+ if (buffer_length < kVp8FixedPayloadDescriptorSize + *extension_length + 1) {
return -1;
}
*x_field |= kLBit;
- buffer[vp8_fixed_payload_descriptor_bytes_ + *extension_length] =
+ buffer[kVp8FixedPayloadDescriptorSize + *extension_length] =
hdr_info_.tl0PicIdx;
++*extension_length;
return 0;
@@ -387,12 +366,11 @@
uint8_t* buffer,
size_t buffer_length,
size_t* extension_length) const {
- if (buffer_length <
- vp8_fixed_payload_descriptor_bytes_ + *extension_length + 1) {
+ if (buffer_length < kVp8FixedPayloadDescriptorSize + *extension_length + 1) {
return -1;
}
uint8_t* data_field =
- &buffer[vp8_fixed_payload_descriptor_bytes_ + *extension_length];
+ &buffer[kVp8FixedPayloadDescriptorSize + *extension_length];
*data_field = 0;
if (TIDFieldPresent()) {
*x_field |= kTBit;
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.h b/modules/rtp_rtcp/source/rtp_format_vp8.h
index 3f0d7e5..dd66762 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8.h
+++ b/modules/rtp_rtcp/source/rtp_format_vp8.h
@@ -32,7 +32,6 @@
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -41,23 +40,19 @@
public:
// Initialize with payload from encoder.
// The payload_data must be exactly one encoded VP8 frame.
- RtpPacketizerVp8(const RTPVideoHeaderVP8& hdr_info,
- size_t max_payload_len,
- size_t last_packet_reduction_len);
+ RtpPacketizerVp8(rtc::ArrayView<const uint8_t> payload,
+ PayloadSizeLimits limits,
+ const RTPVideoHeaderVP8& hdr_info);
~RtpPacketizerVp8() override;
- size_t SetPayloadData(const uint8_t* payload_data,
- size_t payload_size,
- const RTPFragmentationHeader* fragmentation) override;
+ size_t NumPackets() const override;
// Get the next payload with VP8 payload header.
// Write payload and set marker bit of the |packet|.
// Returns true on success, false otherwise.
bool NextPacket(RtpPacketToSend* packet) override;
- std::string ToString() override;
-
private:
typedef struct {
size_t payload_start_pos;
@@ -78,11 +73,7 @@
static const int kYBit = 0x20;
// Calculate all packet sizes and load to packet info queue.
- int GeneratePackets();
-
- // Splits given part of payload to packets with a given capacity. The last
- // packet should be reduced by last_packet_reduction_len_.
- void GeneratePacketsSplitPayloadBalanced(size_t payload_len, size_t capacity);
+ void GeneratePackets(size_t payload_len);
// Insert packet into packet queue.
void QueuePacket(size_t start_pos, size_t packet_size, bool first_packet);
@@ -142,12 +133,8 @@
bool PictureIdPresent() const { return (PictureIdLength() > 0); }
const uint8_t* payload_data_;
- size_t payload_size_;
- const size_t vp8_fixed_payload_descriptor_bytes_; // Length of VP8 payload
- // descriptors' fixed part.
const RTPVideoHeaderVP8 hdr_info_;
- const size_t max_payload_len_;
- const size_t last_packet_reduction_len_;
+ const PayloadSizeLimits limits_;
InfoQueue packets_;
RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8);
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.cc b/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.cc
index 8dc7ba0..abc0c89 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.cc
@@ -22,7 +22,6 @@
: packet_(kNoExtensions),
payload_data_(NULL),
data_ptr_(NULL),
- fragmentation_(NULL),
hdr_info_(hdr),
payload_start_(0),
payload_size_(0),
@@ -30,7 +29,6 @@
inited_(false) {}
RtpFormatVp8TestHelper::~RtpFormatVp8TestHelper() {
- delete fragmentation_;
delete[] payload_data_;
}
@@ -38,8 +36,6 @@
size_t num_partitions) {
if (inited_)
return false;
- fragmentation_ = new RTPFragmentationHeader;
- fragmentation_->VerifyAndAllocateFragmentationHeader(num_partitions);
payload_size_ = 0;
// Calculate sum payload size.
for (size_t p = 0; p < num_partitions; ++p) {
@@ -49,8 +45,6 @@
size_t j = 0;
// Loop through the partitions again.
for (size_t p = 0; p < num_partitions; ++p) {
- fragmentation_->fragmentationLength[p] = partition_sizes[p];
- fragmentation_->fragmentationOffset[p] = j;
for (size_t i = 0; i < partition_sizes[p]; ++i) {
assert(j < payload_size_);
payload_data_[j++] = p; // Set the payload value to the partition index.
@@ -124,6 +118,7 @@
payload_start_ = 1;
rtc::ArrayView<const uint8_t> buffer = packet_.payload();
EXPECT_BIT_EQ(buffer[0], 6, 0); // Check reserved bit.
+ EXPECT_PART_ID_EQ(buffer[0], 0); // In equal size mode, PartID is always 0.
if (hdr_info_->pictureId != kNoPictureId ||
hdr_info_->temporalIdx != kNoTemporalIdx ||
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h b/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h
index 1ed63ab..7d5a090 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h
+++ b/modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h
@@ -22,7 +22,6 @@
#include "modules/rtp_rtcp/source/rtp_format_vp8.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -39,9 +38,10 @@
const bool* expected_frag_start,
size_t expected_num_packets);
- uint8_t* payload_data() const { return payload_data_; }
+ rtc::ArrayView<const uint8_t> payload() const {
+ return rtc::ArrayView<const uint8_t>(payload_data_, payload_size_);
+ }
size_t payload_size() const { return payload_size_; }
- RTPFragmentationHeader* fragmentation() const { return fragmentation_; }
size_t buffer_size() const {
static constexpr size_t kVp8PayloadDescriptorMaxSize = 6;
return payload_size_ + kVp8PayloadDescriptorMaxSize;
@@ -60,7 +60,6 @@
RtpPacketToSend packet_;
uint8_t* payload_data_;
uint8_t* data_ptr_;
- RTPFragmentationHeader* fragmentation_;
const RTPVideoHeaderVP8* hdr_info_;
int payload_start_;
size_t payload_size_;
diff --git a/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc b/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc
index adcc5a2..b1096d8 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc
@@ -15,7 +15,6 @@
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "test/gmock.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
#define CHECK_ARRAY_SIZE(expected_size, array) \
static_assert(expected_size == sizeof(array) / sizeof(array[0]), \
@@ -107,10 +106,10 @@
ASSERT_TRUE(Init(kSizeVector, kNumPartitions));
hdr_info_.pictureId = 200; // > 0x7F should produce 2-byte PictureID
- const size_t kMaxPayloadSize = 12; // Small enough to produce 4 packets.
- RtpPacketizerVp8 packetizer(hdr_info_, kMaxPayloadSize, 0);
- size_t num_packets = packetizer.SetPayloadData(
- helper_->payload_data(), helper_->payload_size(), nullptr);
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = 12; // Small enough to produce 4 packets.
+ RtpPacketizerVp8 packetizer(helper_->payload(), limits, hdr_info_);
+ size_t num_packets = packetizer.NumPackets();
// Expecting three full packets, and one with the remainder.
const size_t kExpectedSizes[] = {11, 11, 12, 12};
@@ -133,11 +132,11 @@
ASSERT_TRUE(Init(kSizeVector, kNumPartitions));
hdr_info_.pictureId = 200;
- const size_t kMaxPayloadSize = 15; // Small enough to produce 5 packets.
- const size_t kLastPacketReduction = 5;
- RtpPacketizerVp8 packetizer(hdr_info_, kMaxPayloadSize, kLastPacketReduction);
- size_t num_packets = packetizer.SetPayloadData(
- helper_->payload_data(), helper_->payload_size(), nullptr);
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = 15; // Small enough to produce 5 packets.
+ limits.last_packet_reduction_len = 5;
+ RtpPacketizerVp8 packetizer(helper_->payload(), limits, hdr_info_);
+ size_t num_packets = packetizer.NumPackets();
// Calculated by hand. VP8 payload descriptors are 4 byte each. 5 packets is
// minimum possible to fit 43 payload bytes into packets with capacity of
@@ -165,10 +164,10 @@
ASSERT_TRUE(Init(kSizeVector, kNumPartitions));
hdr_info_.nonReference = true;
- const size_t kMaxPayloadSize = 25; // Small enough to produce two packets.
- RtpPacketizerVp8 packetizer(hdr_info_, kMaxPayloadSize, 0);
- size_t num_packets = packetizer.SetPayloadData(
- helper_->payload_data(), helper_->payload_size(), nullptr);
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = 25; // Small enough to produce two packets.
+ RtpPacketizerVp8 packetizer(helper_->payload(), limits, hdr_info_);
+ size_t num_packets = packetizer.NumPackets();
// EqualSize mode => First packet full; other not.
const size_t kExpectedSizes[] = {16, 16};
@@ -194,12 +193,11 @@
hdr_info_.tl0PicIdx = 117;
hdr_info_.temporalIdx = 2;
hdr_info_.layerSync = true;
- // kMaxPayloadSize is only limited by allocated buffer size.
- const size_t kMaxPayloadSize = helper_->buffer_size();
- RtpPacketizerVp8 packetizer(hdr_info_, kMaxPayloadSize, 0);
- size_t num_packets = packetizer.SetPayloadData(helper_->payload_data(),
- helper_->payload_size(),
- helper_->fragmentation());
+ RtpPacketizer::PayloadSizeLimits limits;
+ // max_payload_len is only limited by allocated buffer size.
+ limits.max_payload_len = helper_->buffer_size();
+ RtpPacketizerVp8 packetizer(helper_->payload(), limits, hdr_info_);
+ size_t num_packets = packetizer.NumPackets();
// Expect one single packet of payload_size() + 4 bytes header.
const size_t kExpectedSizes[1] = {helper_->payload_size() + 4};
@@ -221,12 +219,11 @@
ASSERT_TRUE(Init(kSizeVector, kNumPartitions));
hdr_info_.keyIdx = 17;
- // kMaxPayloadSize is only limited by allocated buffer size.
- const size_t kMaxPayloadSize = helper_->buffer_size();
- RtpPacketizerVp8 packetizer(hdr_info_, kMaxPayloadSize, 0);
- size_t num_packets = packetizer.SetPayloadData(helper_->payload_data(),
- helper_->payload_size(),
- helper_->fragmentation());
+ RtpPacketizer::PayloadSizeLimits limits;
+ // max payload len is only limited by allocated buffer size.
+ limits.max_payload_len = helper_->buffer_size();
+ RtpPacketizerVp8 packetizer(helper_->payload(), limits, hdr_info_);
+ size_t num_packets = packetizer.NumPackets();
// Expect one single packet of payload_size() + 3 bytes header.
const size_t kExpectedSizes[1] = {helper_->payload_size() + 3};
@@ -249,12 +246,11 @@
hdr_info_.temporalIdx = 1;
hdr_info_.keyIdx = 5;
- // kMaxPayloadSize is only limited by allocated buffer size.
- const size_t kMaxPayloadSize = helper_->buffer_size();
- RtpPacketizerVp8 packetizer(hdr_info_, kMaxPayloadSize, 0);
- size_t num_packets = packetizer.SetPayloadData(helper_->payload_data(),
- helper_->payload_size(),
- helper_->fragmentation());
+ RtpPacketizer::PayloadSizeLimits limits;
+ // max_payload_len is only limited by allocated buffer size.
+ limits.max_payload_len = helper_->buffer_size();
+ RtpPacketizerVp8 packetizer(helper_->payload(), limits, hdr_info_);
+ size_t num_packets = packetizer.NumPackets();
// Expect one single packet of payload_size() + 3 bytes header.
const size_t kExpectedSizes[1] = {helper_->payload_size() + 3};
@@ -436,8 +432,10 @@
input_header.layerSync = false;
input_header.tl0PicIdx = kNoTl0PicIdx; // Disable.
input_header.keyIdx = 31;
- RtpPacketizerVp8 packetizer(input_header, 20, 0);
- EXPECT_EQ(packetizer.SetPayloadData(data, 10, NULL), 1u);
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = 20;
+ RtpPacketizerVp8 packetizer(data, limits, input_header);
+ EXPECT_EQ(packetizer.NumPackets(), 1u);
ASSERT_TRUE(packetizer.NextPacket(&packet));
EXPECT_TRUE(packet.Marker());
diff --git a/modules/rtp_rtcp/source/rtp_format_vp9.cc b/modules/rtp_rtcp/source/rtp_format_vp9.cc
index 8fd1be8..f800ff8 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp9.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp9.cc
@@ -471,10 +471,6 @@
RtpPacketizerVp9::~RtpPacketizerVp9() {}
-std::string RtpPacketizerVp9::ToString() {
- return "RtpPacketizerVp9";
-}
-
size_t RtpPacketizerVp9::SetPayloadData(
const uint8_t* payload,
size_t payload_size,
@@ -485,6 +481,10 @@
return packets_.size();
}
+size_t RtpPacketizerVp9::NumPackets() const {
+ return packets_.size();
+}
+
// Splits payload in minimal number of roughly equal in size packets.
void RtpPacketizerVp9::GeneratePackets() {
if (max_payload_length_ < PayloadDescriptorLength(hdr_) + 1) {
@@ -719,41 +719,42 @@
parsed_payload->frame_type = p_bit ? kVideoFrameDelta : kVideoFrameKey;
- RTPVideoHeaderVP9* vp9 = &parsed_payload->video_header().vp9();
- vp9->InitRTPVideoHeaderVP9();
- vp9->inter_pic_predicted = p_bit ? true : false;
- vp9->flexible_mode = f_bit ? true : false;
- vp9->beginning_of_frame = b_bit ? true : false;
- vp9->end_of_frame = e_bit ? true : false;
- vp9->ss_data_available = v_bit ? true : false;
- vp9->non_ref_for_inter_layer_pred = z_bit ? true : false;
+ auto& vp9_header = parsed_payload->video_header()
+ .video_type_header.emplace<RTPVideoHeaderVP9>();
+ vp9_header.InitRTPVideoHeaderVP9();
+ vp9_header.inter_pic_predicted = p_bit ? true : false;
+ vp9_header.flexible_mode = f_bit ? true : false;
+ vp9_header.beginning_of_frame = b_bit ? true : false;
+ vp9_header.end_of_frame = e_bit ? true : false;
+ vp9_header.ss_data_available = v_bit ? true : false;
+ vp9_header.non_ref_for_inter_layer_pred = z_bit ? true : false;
// Parse fields that are present.
- if (i_bit && !ParsePictureId(&parser, vp9)) {
+ if (i_bit && !ParsePictureId(&parser, &vp9_header)) {
RTC_LOG(LS_ERROR) << "Failed parsing VP9 picture id.";
return false;
}
- if (l_bit && !ParseLayerInfo(&parser, vp9)) {
+ if (l_bit && !ParseLayerInfo(&parser, &vp9_header)) {
RTC_LOG(LS_ERROR) << "Failed parsing VP9 layer info.";
return false;
}
- if (p_bit && f_bit && !ParseRefIndices(&parser, vp9)) {
+ if (p_bit && f_bit && !ParseRefIndices(&parser, &vp9_header)) {
RTC_LOG(LS_ERROR) << "Failed parsing VP9 ref indices.";
return false;
}
if (v_bit) {
- if (!ParseSsData(&parser, vp9)) {
+ if (!ParseSsData(&parser, &vp9_header)) {
RTC_LOG(LS_ERROR) << "Failed parsing VP9 SS data.";
return false;
}
- if (vp9->spatial_layer_resolution_present) {
+ if (vp9_header.spatial_layer_resolution_present) {
// TODO(asapersson): Add support for spatial layers.
- parsed_payload->video_header().width = vp9->width[0];
- parsed_payload->video_header().height = vp9->height[0];
+ parsed_payload->video_header().width = vp9_header.width[0];
+ parsed_payload->video_header().height = vp9_header.height[0];
}
}
parsed_payload->video_header().is_first_packet_in_frame =
- b_bit && (!l_bit || !vp9->inter_layer_predicted);
+ b_bit && (!l_bit || !vp9_header.inter_layer_predicted);
uint64_t rem_bits = parser.RemainingBitCount();
assert(rem_bits % 8 == 0);
diff --git a/modules/rtp_rtcp/source/rtp_format_vp9.h b/modules/rtp_rtcp/source/rtp_format_vp9.h
index 9017864..61f04d4 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp9.h
+++ b/modules/rtp_rtcp/source/rtp_format_vp9.h
@@ -27,7 +27,6 @@
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -39,12 +38,12 @@
~RtpPacketizerVp9() override;
- std::string ToString() override;
-
// The payload data must be one encoded VP9 layer frame.
size_t SetPayloadData(const uint8_t* payload,
size_t payload_size,
- const RTPFragmentationHeader* fragmentation) override;
+ const RTPFragmentationHeader* fragmentation);
+
+ size_t NumPackets() const override;
// Gets the next payload with VP9 payload header.
// Write payload and set marker bit of the |packet|.
diff --git a/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc b/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc
index b9480ef..66c6091 100644
--- a/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_format_vp9_unittest.cc
@@ -15,7 +15,6 @@
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "test/gmock.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
@@ -83,7 +82,9 @@
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer->Parse(&parsed, packet, expected_length));
EXPECT_EQ(kVideoCodecVP9, parsed.video_header().codec);
- VerifyHeader(expected, parsed.video_header().vp9());
+ auto& vp9_header =
+ absl::get<RTPVideoHeaderVP9>(parsed.video_header().video_type_header);
+ VerifyHeader(expected, vp9_header);
const size_t kExpectedPayloadLength = expected_length - expected_hdr_length;
VerifyPayload(parsed, packet + expected_hdr_length, kExpectedPayloadLength);
}
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc
index 080cac7..b5b8ce5 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.cc
@@ -14,7 +14,9 @@
namespace webrtc {
-constexpr size_t RtpGenericFrameDescriptor::kMaxNumFrameDependencies;
+constexpr int RtpGenericFrameDescriptor::kMaxNumFrameDependencies;
+constexpr int RtpGenericFrameDescriptor::kMaxTemporalLayers;
+constexpr int RtpGenericFrameDescriptor::kMaxSpatialLayers;
RtpGenericFrameDescriptor::RtpGenericFrameDescriptor() = default;
@@ -25,7 +27,7 @@
void RtpGenericFrameDescriptor::SetTemporalLayer(int temporal_layer) {
RTC_DCHECK_GE(temporal_layer, 0);
- RTC_DCHECK_LE(temporal_layer, 7);
+ RTC_DCHECK_LT(temporal_layer, kMaxTemporalLayers);
temporal_layer_ = temporal_layer;
}
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
index 51a9ac0..e4b775e 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h
@@ -20,6 +20,10 @@
// Data to put on the wire for FrameDescriptor rtp header extension.
class RtpGenericFrameDescriptor {
public:
+ static constexpr int kMaxNumFrameDependencies = 8;
+ static constexpr int kMaxTemporalLayers = 8;
+ static constexpr int kMaxSpatialLayers = 8;
+
RtpGenericFrameDescriptor();
bool FirstPacketInSubFrame() const { return beginning_of_subframe_; }
@@ -51,8 +55,6 @@
bool AddFrameDependencyDiff(uint16_t fdiff);
private:
- static constexpr size_t kMaxNumFrameDependencies = 8;
-
bool beginning_of_subframe_ = false;
bool end_of_subframe_ = false;
bool beginning_of_frame_ = false;
diff --git a/modules/rtp_rtcp/source/rtp_header_extension_map_unittest.cc b/modules/rtp_rtcp/source/rtp_header_extension_map_unittest.cc
index 5eb8f1a..ad9f79c 100644
--- a/modules/rtp_rtcp/source/rtp_header_extension_map_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_header_extension_map_unittest.cc
@@ -14,7 +14,6 @@
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_packet.cc b/modules/rtp_rtcp/source/rtp_packet.cc
index 878942b..4387fe7 100644
--- a/modules/rtp_rtcp/source/rtp_packet.cc
+++ b/modules/rtp_rtcp/source/rtp_packet.cc
@@ -107,32 +107,6 @@
return true;
}
-bool RtpPacket::Marker() const {
- RTC_DCHECK_EQ(marker_, (data()[1] & 0x80) != 0);
- return marker_;
-}
-
-uint8_t RtpPacket::PayloadType() const {
- RTC_DCHECK_EQ(payload_type_, data()[1] & 0x7f);
- return payload_type_;
-}
-
-uint16_t RtpPacket::SequenceNumber() const {
- RTC_DCHECK_EQ(sequence_number_,
- ByteReader<uint16_t>::ReadBigEndian(data() + 2));
- return sequence_number_;
-}
-
-uint32_t RtpPacket::Timestamp() const {
- RTC_DCHECK_EQ(timestamp_, ByteReader<uint32_t>::ReadBigEndian(data() + 4));
- return timestamp_;
-}
-
-uint32_t RtpPacket::Ssrc() const {
- RTC_DCHECK_EQ(ssrc_, ByteReader<uint32_t>::ReadBigEndian(data() + 8));
- return ssrc_;
-}
-
std::vector<uint32_t> RtpPacket::Csrcs() const {
size_t num_csrc = data()[0] & 0x0F;
RTC_DCHECK_GE(capacity(), kFixedHeaderSize + num_csrc * 4);
@@ -144,48 +118,6 @@
return csrcs;
}
-size_t RtpPacket::headers_size() const {
- return payload_offset_;
-}
-
-size_t RtpPacket::payload_size() const {
- return payload_size_;
-}
-
-size_t RtpPacket::padding_size() const {
- return padding_size_;
-}
-
-rtc::ArrayView<const uint8_t> RtpPacket::payload() const {
- return rtc::MakeArrayView(data() + payload_offset_, payload_size_);
-}
-
-rtc::CopyOnWriteBuffer RtpPacket::Buffer() const {
- return buffer_;
-}
-
-size_t RtpPacket::capacity() const {
- return buffer_.capacity();
-}
-
-size_t RtpPacket::size() const {
- size_t ret = payload_offset_ + payload_size_ + padding_size_;
- RTC_DCHECK_EQ(buffer_.size(), ret);
- return ret;
-}
-
-const uint8_t* RtpPacket::data() const {
- return buffer_.cdata();
-}
-
-size_t RtpPacket::FreeCapacity() const {
- return capacity() - size();
-}
-
-size_t RtpPacket::MaxPayloadSize() const {
- return capacity() - payload_offset_;
-}
-
void RtpPacket::CopyHeaderFrom(const RtpPacket& packet) {
RTC_DCHECK_GE(capacity(), packet.headers_size());
@@ -235,7 +167,7 @@
ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc);
}
-void RtpPacket::SetCsrcs(const std::vector<uint32_t>& csrcs) {
+void RtpPacket::SetCsrcs(rtc::ArrayView<const uint32_t> csrcs) {
RTC_DCHECK_EQ(extensions_size_, 0);
RTC_DCHECK_EQ(payload_size_, 0);
RTC_DCHECK_EQ(padding_size_, 0);
@@ -251,37 +183,7 @@
buffer_.SetSize(payload_offset_);
}
-bool RtpPacket::HasRawExtension(int id) const {
- if (id == ExtensionManager::kInvalidId)
- return false;
- RTC_DCHECK_GE(id, kMinExtensionId);
- RTC_DCHECK_LE(id, kMaxExtensionId);
- return extension_entries_[id - 1].offset != 0;
-}
-
-rtc::ArrayView<const uint8_t> RtpPacket::GetRawExtension(int id) const {
- if (id == ExtensionManager::kInvalidId)
- return nullptr;
- RTC_DCHECK_GE(id, kMinExtensionId);
- RTC_DCHECK_LE(id, kMaxExtensionId);
- const ExtensionInfo& extension = extension_entries_[id - 1];
- if (extension.offset == 0)
- return nullptr;
- return rtc::MakeArrayView(data() + extension.offset, extension.length);
-}
-
-bool RtpPacket::SetRawExtension(int id, rtc::ArrayView<const uint8_t> data) {
- auto buffer = AllocateRawExtension(id, data.size());
- if (buffer.empty())
- return false;
- RTC_DCHECK_EQ(buffer.size(), data.size());
- memcpy(buffer.data(), data.data(), data.size());
- return true;
-}
-
rtc::ArrayView<uint8_t> RtpPacket::AllocateRawExtension(int id, size_t length) {
- if (id == ExtensionManager::kInvalidId)
- return nullptr;
RTC_DCHECK_GE(id, kMinExtensionId);
RTC_DCHECK_LE(id, kMaxExtensionId);
RTC_DCHECK_GE(length, 1);
@@ -547,12 +449,4 @@
return nullptr;
}
-uint8_t* RtpPacket::WriteAt(size_t offset) {
- return buffer_.data() + offset;
-}
-
-void RtpPacket::WriteAt(size_t offset, uint8_t byte) {
- buffer_.data()[offset] = byte;
-}
-
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_packet.h b/modules/rtp_rtcp/source/rtp_packet.h
index 2f0ef75..21adf62 100644
--- a/modules/rtp_rtcp/source/rtp_packet.h
+++ b/modules/rtp_rtcp/source/rtp_packet.h
@@ -51,27 +51,31 @@
void IdentifyExtensions(const ExtensionManager& extensions);
// Header.
- bool Marker() const;
- uint8_t PayloadType() const;
- uint16_t SequenceNumber() const;
- uint32_t Timestamp() const;
- uint32_t Ssrc() const;
+ bool Marker() const { return marker_; }
+ uint8_t PayloadType() const { return payload_type_; }
+ uint16_t SequenceNumber() const { return sequence_number_; }
+ uint32_t Timestamp() const { return timestamp_; }
+ uint32_t Ssrc() const { return ssrc_; }
std::vector<uint32_t> Csrcs() const;
- size_t headers_size() const;
+ size_t headers_size() const { return payload_offset_; }
// Payload.
- size_t payload_size() const;
- size_t padding_size() const;
- rtc::ArrayView<const uint8_t> payload() const;
+ size_t payload_size() const { return payload_size_; }
+ size_t padding_size() const { return padding_size_; }
+ rtc::ArrayView<const uint8_t> payload() const {
+ return rtc::MakeArrayView(data() + payload_offset_, payload_size_);
+ }
// Buffer.
- rtc::CopyOnWriteBuffer Buffer() const;
- size_t capacity() const;
- size_t size() const;
- const uint8_t* data() const;
- size_t FreeCapacity() const;
- size_t MaxPayloadSize() const;
+ rtc::CopyOnWriteBuffer Buffer() const { return buffer_; }
+ size_t capacity() const { return buffer_.capacity(); }
+ size_t size() const {
+ return payload_offset_ + payload_size_ + padding_size_;
+ }
+ const uint8_t* data() const { return buffer_.cdata(); }
+ size_t FreeCapacity() const { return capacity() - size(); }
+ size_t MaxPayloadSize() const { return capacity() - headers_size(); }
// Reset fields and buffer.
void Clear();
@@ -87,7 +91,7 @@
// Writes csrc list. Assumes:
// a) There is enough room left in buffer.
// b) Extension headers, payload or padding data has not already been added.
- void SetCsrcs(const std::vector<uint32_t>& csrcs);
+ void SetCsrcs(rtc::ArrayView<const uint32_t> csrcs);
// Header extensions.
template <typename Extension>
@@ -102,21 +106,6 @@
template <typename Extension>
bool ReserveExtension();
- // Following 4 helpers identify rtp header extension by |id| negotiated with
- // remote peer and written in an rtp packet.
- bool HasRawExtension(int id) const;
-
- // Returns place where extension with |id| is stored.
- // Returns empty arrayview if extension is not present.
- rtc::ArrayView<const uint8_t> GetRawExtension(int id) const;
-
- // Allocates and store header extension. Returns true on success.
- bool SetRawExtension(int id, rtc::ArrayView<const uint8_t> data);
-
- // Allocates and returns place to store rtp header extension.
- // Returns empty arrayview on failure.
- rtc::ArrayView<uint8_t> AllocateRawExtension(int id, size_t length);
-
// Reserve size_bytes for payload. Returns nullptr on failure.
uint8_t* SetPayloadSize(size_t size_bytes);
// Same as SetPayloadSize but doesn't guarantee to keep current payload.
@@ -138,12 +127,16 @@
// Returns view of the raw extension or empty view on failure.
rtc::ArrayView<const uint8_t> FindExtension(ExtensionType type) const;
+ // Allocates and returns place to store rtp header extension.
+ // Returns empty arrayview on failure.
+ rtc::ArrayView<uint8_t> AllocateRawExtension(int id, size_t length);
+
// Find or allocate an extension |type|. Returns view of size |length|
// to write raw extension to or an empty view on failure.
rtc::ArrayView<uint8_t> AllocateExtension(ExtensionType type, size_t length);
- uint8_t* WriteAt(size_t offset);
- void WriteAt(size_t offset, uint8_t byte);
+ uint8_t* WriteAt(size_t offset) { return buffer_.data() + offset; }
+ void WriteAt(size_t offset, uint8_t byte) { buffer_.data()[offset] = byte; }
// Header.
bool marker_;
diff --git a/modules/rtp_rtcp/source/rtp_packet_history.h b/modules/rtp_rtcp/source/rtp_packet_history.h
index 03527ff..433da0e 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history.h
+++ b/modules/rtp_rtcp/source/rtp_packet_history.h
@@ -19,7 +19,6 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/thread_annotations.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
index 026c187..ab5aeb0 100644
--- a/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc
@@ -17,7 +17,6 @@
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "system_wrappers/include/clock.h"
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
namespace {
diff --git a/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
index 60d23d8..e19f191 100644
--- a/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -196,50 +196,27 @@
EXPECT_FALSE(packet.SetExtension<RtpMid>(kLongMid));
}
-TEST(RtpPacketTest, CreateWithExtensionsWithoutManager) {
- RtpPacketToSend packet(nullptr);
- packet.SetPayloadType(kPayloadType);
- packet.SetSequenceNumber(kSeqNum);
- packet.SetTimestamp(kTimestamp);
- packet.SetSsrc(kSsrc);
-
- auto raw = packet.AllocateRawExtension(kTransmissionOffsetExtensionId,
- TransmissionOffset::kValueSizeBytes);
- EXPECT_EQ(raw.size(), TransmissionOffset::kValueSizeBytes);
- TransmissionOffset::Write(raw, kTimeOffset);
-
- raw = packet.AllocateRawExtension(kAudioLevelExtensionId,
- AudioLevel::kValueSizeBytes);
- EXPECT_EQ(raw.size(), AudioLevel::kValueSizeBytes);
- AudioLevel::Write(raw, kVoiceActive, kAudioLevel);
-
- EXPECT_THAT(kPacketWithTOAndAL,
- ElementsAreArray(packet.data(), packet.size()));
-}
-
TEST(RtpPacketTest, CreateWithMaxSizeHeaderExtension) {
- const size_t kMaxExtensionSize = 16;
- const int kId = 1;
- const uint8_t kValue[16] = "123456789abcdef";
+ const std::string kValue = "123456789abcdef";
+ RtpPacket::ExtensionManager extensions;
+ extensions.Register<RtpMid>(1);
+ extensions.Register<RtpStreamId>(2);
- // Write packet with a custom extension.
- RtpPacketToSend packet(nullptr);
- packet.SetRawExtension(kId, kValue);
- // Using different size for same id is not allowed.
- EXPECT_TRUE(packet.AllocateRawExtension(kId, kMaxExtensionSize - 1).empty());
+ RtpPacket packet(&extensions);
+ EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
packet.SetPayloadSize(42);
// Rewriting allocated extension is allowed.
- EXPECT_EQ(packet.AllocateRawExtension(kId, kMaxExtensionSize).size(),
- kMaxExtensionSize);
+ EXPECT_TRUE(packet.SetExtension<RtpMid>(kValue));
// Adding another extension after payload is set is not allowed.
- EXPECT_TRUE(packet.AllocateRawExtension(kId + 1, kMaxExtensionSize).empty());
+ EXPECT_FALSE(packet.SetExtension<RtpStreamId>(kValue));
- // Read packet with the custom extension.
- RtpPacketReceived parsed;
+ // Read packet with the extension.
+ RtpPacketReceived parsed(&extensions);
EXPECT_TRUE(parsed.Parse(packet.Buffer()));
- auto read_raw = parsed.GetRawExtension(kId);
- EXPECT_THAT(read_raw, ElementsAreArray(kValue, kMaxExtensionSize));
+ std::string read;
+ EXPECT_TRUE(parsed.GetExtension<RtpMid>(&read));
+ EXPECT_EQ(read, kValue);
}
TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
@@ -426,23 +403,6 @@
EXPECT_EQ(0u, packet.padding_size());
}
-TEST(RtpPacketTest, ParseWithoutExtensionManager) {
- RtpPacketReceived packet;
- EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
-
- EXPECT_FALSE(packet.HasRawExtension(kAudioLevelExtensionId));
- EXPECT_TRUE(packet.GetRawExtension(kAudioLevelExtensionId).empty());
-
- EXPECT_TRUE(packet.HasRawExtension(kTransmissionOffsetExtensionId));
-
- int32_t time_offset = 0;
- auto raw_extension = packet.GetRawExtension(kTransmissionOffsetExtensionId);
- EXPECT_EQ(raw_extension.size(), TransmissionOffset::kValueSizeBytes);
- EXPECT_TRUE(TransmissionOffset::Parse(raw_extension, &time_offset));
-
- EXPECT_EQ(time_offset, kTimeOffset);
-}
-
TEST(RtpPacketTest, ParseDynamicSizeExtension) {
// clang-format off
const uint8_t kPacket1[] = {
@@ -493,23 +453,6 @@
EXPECT_EQ(mid, kMid);
}
-TEST(RtpPacketTest, RawExtensionFunctionsAcceptZeroIdAndReturnFalse) {
- RtpPacketReceived::ExtensionManager extensions;
- RtpPacketReceived packet(&extensions);
- // Use ExtensionManager to set kInvalidId to 0 to demonstrate natural way for
- // using zero value as a parameter to Packet::*RawExtension functions.
- const int kInvalidId = extensions.GetId(TransmissionOffset::kId);
- ASSERT_EQ(kInvalidId, 0);
-
- ASSERT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
-
- EXPECT_FALSE(packet.HasRawExtension(kInvalidId));
- EXPECT_THAT(packet.GetRawExtension(kInvalidId), IsEmpty());
- const uint8_t kExtension[] = {'e', 'x', 't'};
- EXPECT_FALSE(packet.SetRawExtension(kInvalidId, kExtension));
- EXPECT_THAT(packet.AllocateRawExtension(kInvalidId, 3), IsEmpty());
-}
-
TEST(RtpPacketTest, CreateAndParseTimingFrameExtension) {
// Create a packet with video frame timing extension populated.
RtpPacketToSend::ExtensionManager send_extensions;
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry.cc b/modules/rtp_rtcp/source/rtp_payload_registry.cc
index f69940a..4bbb03a 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry.cc
+++ b/modules/rtp_rtcp/source/rtp_payload_registry.cc
@@ -47,20 +47,9 @@
PayloadUnion(AudioPayload{audio_format, 0})};
}
-RtpVideoCodecTypes ConvertToRtpVideoCodecType(VideoCodecType type) {
- switch (type) {
- case kVideoCodecVP8:
- case kVideoCodecVP9:
- case kVideoCodecH264:
- return type;
- default:
- return kVideoCodecGeneric;
- }
-}
-
RtpUtility::Payload CreatePayloadType(const VideoCodec& video_codec) {
VideoPayload p;
- p.videoCodecType = ConvertToRtpVideoCodecType(video_codec.codecType);
+ p.videoCodecType = video_codec.codecType;
if (video_codec.codecType == kVideoCodecH264)
p.h264_profile = video_codec.H264().profile;
return {CodecTypeToPayloadString(video_codec.codecType), PayloadUnion(p)};
@@ -91,7 +80,7 @@
} // namespace
-RTPPayloadRegistry::RTPPayloadRegistry() : last_received_payload_type_(-1) {}
+RTPPayloadRegistry::RTPPayloadRegistry() = default;
RTPPayloadRegistry::~RTPPayloadRegistry() = default;
@@ -112,10 +101,6 @@
payload_type_map_.emplace(rtp_payload_type,
CreatePayloadType(audio_format));
}
-
- // Clear the value of last received payload type since it might mean
- // something else now.
- last_received_payload_type_ = -1;
}
int32_t RTPPayloadRegistry::RegisterReceivePayload(
@@ -153,9 +138,7 @@
RTC_DCHECK(insert_status.second); // Insertion succeeded.
*created_new_payload = true;
- // Successful set of payload type, clear the value of last received payload
- // type since it might mean something else.
- last_received_payload_type_ = -1;
+ // Successful set of payload type.
return 0;
}
@@ -186,9 +169,7 @@
video_codec.plType, CreatePayloadType(video_codec));
RTC_DCHECK(insert_status.second); // Insertion succeeded.
- // Successful set of payload type, clear the value of last received payload
- // type since it might mean something else.
- last_received_payload_type_ = -1;
+ // Successful set of payload type.
return 0;
}
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc b/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
index e7362c7..9ae6aef 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_payload_registry_unittest.cc
@@ -149,21 +149,6 @@
<< "Not compatible; both payloads should be kept.";
}
-TEST(RtpPayloadRegistryTest,
- LastReceivedCodecTypesAreResetWhenRegisteringNewPayloadTypes) {
- RTPPayloadRegistry rtp_payload_registry;
- rtp_payload_registry.set_last_received_payload_type(17);
- EXPECT_EQ(17, rtp_payload_registry.last_received_payload_type());
-
- bool ignored;
- constexpr int payload_type = 34;
- const SdpAudioFormat audio_format("name", 44000, 1);
- EXPECT_EQ(0, rtp_payload_registry.RegisterReceivePayload(
- payload_type, audio_format, &ignored));
-
- EXPECT_EQ(-1, rtp_payload_registry.last_received_payload_type());
-}
-
class ParameterizedRtpPayloadRegistryTest
: public ::testing::TestWithParam<int> {};
diff --git a/modules/rtp_rtcp/source/rtp_receiver_audio.cc b/modules/rtp_rtcp/source/rtp_receiver_audio.cc
index ac57138..030c79f 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_audio.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_audio.cc
@@ -25,47 +25,10 @@
}
RTPReceiverAudio::RTPReceiverAudio(RtpData* data_callback)
- : RTPReceiverStrategy(data_callback),
- TelephoneEventHandler(),
- telephone_event_forward_to_decoder_(false),
- telephone_event_payload_type_(-1),
- cng_nb_payload_type_(-1),
- cng_wb_payload_type_(-1),
- cng_swb_payload_type_(-1),
- cng_fb_payload_type_(-1) {}
+ : RTPReceiverStrategy(data_callback) {}
RTPReceiverAudio::~RTPReceiverAudio() = default;
-// Outband TelephoneEvent(DTMF) detection
-void RTPReceiverAudio::SetTelephoneEventForwardToDecoder(
- bool forward_to_decoder) {
- rtc::CritScope lock(&crit_sect_);
- telephone_event_forward_to_decoder_ = forward_to_decoder;
-}
-
-// Is forwarding of outband telephone events turned on/off?
-bool RTPReceiverAudio::TelephoneEventForwardToDecoder() const {
- rtc::CritScope lock(&crit_sect_);
- return telephone_event_forward_to_decoder_;
-}
-
-bool RTPReceiverAudio::TelephoneEventPayloadType(int8_t payload_type) const {
- rtc::CritScope lock(&crit_sect_);
- return telephone_event_payload_type_ == payload_type;
-}
-
-TelephoneEventHandler* RTPReceiverAudio::GetTelephoneEventHandler() {
- return this;
-}
-
-bool RTPReceiverAudio::CNGPayloadType(int8_t payload_type) {
- rtc::CritScope lock(&crit_sect_);
- return payload_type == cng_nb_payload_type_ ||
- payload_type == cng_wb_payload_type_ ||
- payload_type == cng_swb_payload_type_ ||
- payload_type == cng_fb_payload_type_;
-}
-
// - Sample based or frame based codecs based on RFC 3551
// -
// - NOTE! There is one error in the RFC, stating G.722 uses 8 bits/samples.
@@ -98,32 +61,6 @@
// - MPA frame N/A var. var.
// -
// - G7221 frame N/A
-int32_t RTPReceiverAudio::OnNewPayloadTypeCreated(
- int payload_type,
- const SdpAudioFormat& audio_format) {
- rtc::CritScope lock(&crit_sect_);
-
- if (RtpUtility::StringCompare(audio_format.name.c_str(), "telephone-event",
- 15)) {
- telephone_event_payload_type_ = payload_type;
- }
- if (RtpUtility::StringCompare(audio_format.name.c_str(), "cn", 2)) {
- // We support comfort noise at four different frequencies.
- if (audio_format.clockrate_hz == 8000) {
- cng_nb_payload_type_ = payload_type;
- } else if (audio_format.clockrate_hz == 16000) {
- cng_wb_payload_type_ = payload_type;
- } else if (audio_format.clockrate_hz == 32000) {
- cng_swb_payload_type_ = payload_type;
- } else if (audio_format.clockrate_hz == 48000) {
- cng_fb_payload_type_ = payload_type;
- } else {
- assert(false);
- return -1;
- }
- }
- return 0;
-}
int32_t RTPReceiverAudio::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
const PayloadUnion& specific_payload,
@@ -138,24 +75,6 @@
specific_payload.audio_payload());
}
-RTPAliveType RTPReceiverAudio::ProcessDeadOrAlive(
- uint16_t last_payload_length) const {
- // Our CNG is 9 bytes; if it's a likely CNG the receiver needs to check
- // kRtpNoRtp against NetEq speech_type kOutputPLCtoCNG.
- if (last_payload_length < 10) { // our CNG is 9 bytes
- return kRtpNoRtp;
- } else {
- return kRtpDead;
- }
-}
-
-void RTPReceiverAudio::CheckPayloadChanged(int8_t payload_type,
- PayloadUnion* /* specific_payload */,
- bool* should_discard_changes) {
- *should_discard_changes =
- TelephoneEventPayloadType(payload_type) || CNGPayloadType(payload_type);
-}
-
// We are not allowed to have any critsects when calling data_callback.
int32_t RTPReceiverAudio::ParseAudioCodecSpecific(
WebRtcRTPHeader* rtp_header,
@@ -170,71 +89,6 @@
return data_callback_->OnReceivedPayloadData(nullptr, 0, rtp_header);
}
- bool telephone_event_packet =
- TelephoneEventPayloadType(rtp_header->header.payloadType);
- if (telephone_event_packet) {
- rtc::CritScope lock(&crit_sect_);
-
- // RFC 4733 2.3
- // 0 1 2 3
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | event |E|R| volume | duration |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- //
- if (payload_data_length % 4 != 0) {
- return -1;
- }
- size_t number_of_events = payload_data_length / 4;
-
- // sanity
- if (number_of_events >= MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS) {
- number_of_events = MAX_NUMBER_OF_PARALLEL_TELEPHONE_EVENTS;
- }
- for (size_t n = 0; n < number_of_events; ++n) {
- RTC_DCHECK_GE(payload_data_length, (4 * n) + 2);
- bool end = (payload_data[(4 * n) + 1] & 0x80) ? true : false;
-
- std::set<uint8_t>::iterator event =
- telephone_event_reported_.find(payload_data[4 * n]);
-
- if (event != telephone_event_reported_.end()) {
- // we have already seen this event
- if (end) {
- telephone_event_reported_.erase(payload_data[4 * n]);
- }
- } else {
- if (end) {
- // don't add if it's a end of a tone
- } else {
- telephone_event_reported_.insert(payload_data[4 * n]);
- }
- }
- }
-
- // RFC 4733 2.5.1.3 & 2.5.2.3 Long-Duration Events
- // should not be a problem since we don't care about the duration
-
- // RFC 4733 See 2.5.1.5. & 2.5.2.4. Multiple Events in a Packet
- }
-
- {
- rtc::CritScope lock(&crit_sect_);
-
- // check if it's a DTMF event, hence something we can playout
- if (telephone_event_packet) {
- if (!telephone_event_forward_to_decoder_) {
- // don't forward event to decoder
- return 0;
- }
- std::set<uint8_t>::iterator first = telephone_event_reported_.begin();
- if (first != telephone_event_reported_.end() && *first > 15) {
- // don't forward non DTMF events
- return 0;
- }
- }
- }
-
return data_callback_->OnReceivedPayloadData(payload_data,
payload_data_length, rtp_header);
}
diff --git a/modules/rtp_rtcp/source/rtp_receiver_audio.h b/modules/rtp_rtcp/source/rtp_receiver_audio.h
index d88acfd..5d97a1f 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_audio.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_audio.h
@@ -18,64 +18,27 @@
#include "modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "modules/rtp_rtcp/source/rtp_utility.h"
#include "rtc_base/onetimeevent.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
// Handles audio RTP packets. This class is thread-safe.
-class RTPReceiverAudio : public RTPReceiverStrategy,
- public TelephoneEventHandler {
+class RTPReceiverAudio : public RTPReceiverStrategy {
public:
explicit RTPReceiverAudio(RtpData* data_callback);
~RTPReceiverAudio() override;
- // The following three methods implement the TelephoneEventHandler interface.
- // Forward DTMFs to decoder for playout.
- void SetTelephoneEventForwardToDecoder(bool forward_to_decoder) override;
-
- // Is forwarding of outband telephone events turned on/off?
- bool TelephoneEventForwardToDecoder() const override;
-
- // Is TelephoneEvent configured with |payload_type|.
- bool TelephoneEventPayloadType(const int8_t payload_type) const override;
-
- TelephoneEventHandler* GetTelephoneEventHandler() override;
-
- // Returns true if CNG is configured with |payload_type|.
- bool CNGPayloadType(const int8_t payload_type);
-
int32_t ParseRtpPacket(WebRtcRTPHeader* rtp_header,
const PayloadUnion& specific_payload,
const uint8_t* packet,
size_t payload_length,
int64_t timestamp_ms) override;
- RTPAliveType ProcessDeadOrAlive(uint16_t last_payload_length) const override;
-
- int32_t OnNewPayloadTypeCreated(int payload_type,
- const SdpAudioFormat& audio_format) override;
-
- // We need to look out for special payload types here and sometimes reset
- // statistics. In addition we sometimes need to tweak the frequency.
- void CheckPayloadChanged(int8_t payload_type,
- PayloadUnion* specific_payload,
- bool* should_discard_changes) override;
-
private:
int32_t ParseAudioCodecSpecific(WebRtcRTPHeader* rtp_header,
const uint8_t* payload_data,
size_t payload_length,
const AudioPayload& audio_specific);
- bool telephone_event_forward_to_decoder_;
- int8_t telephone_event_payload_type_;
- std::set<uint8_t> telephone_event_reported_;
-
- int8_t cng_nb_payload_type_;
- int8_t cng_wb_payload_type_;
- int8_t cng_swb_payload_type_;
- int8_t cng_fb_payload_type_;
-
ThreadUnsafeOneTimeEvent first_packet_received_;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.cc b/modules/rtp_rtcp/source/rtp_receiver_impl.cc
index ac18688..ea63e5e 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_impl.cc
@@ -85,12 +85,8 @@
rtp_payload_registry_(rtp_payload_registry),
rtp_media_receiver_(rtp_media_receiver),
ssrc_(0),
- num_csrcs_(0),
- current_remote_csrc_(),
last_received_timestamp_(0),
- last_received_frame_time_ms_(-1) {
- memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_));
-}
+ last_received_frame_time_ms_(-1) {}
RtpReceiverImpl::~RtpReceiverImpl() {}
@@ -105,14 +101,6 @@
bool created_new_payload = false;
int32_t result = rtp_payload_registry_->RegisterReceivePayload(
payload_type, audio_format, &created_new_payload);
- if (created_new_payload) {
- if (rtp_media_receiver_->OnNewPayloadTypeCreated(payload_type,
- audio_format) != 0) {
- RTC_LOG(LS_ERROR) << "Failed to register payload: " << audio_format.name
- << "/" << payload_type;
- return -1;
- }
- }
return result;
}
@@ -131,18 +119,6 @@
return ssrc_;
}
-// Get remote CSRC.
-int32_t RtpReceiverImpl::CSRCs(uint32_t array_of_csrcs[kRtpCsrcSize]) const {
- rtc::CritScope lock(&critical_section_rtp_receiver_);
-
- assert(num_csrcs_ <= kRtpCsrcSize);
-
- if (num_csrcs_ > 0) {
- memcpy(array_of_csrcs, current_remote_csrc_, sizeof(uint32_t) * num_csrcs_);
- }
- return num_csrcs_;
-}
-
bool RtpReceiverImpl::IncomingRtpPacket(const RTPHeader& rtp_header,
const uint8_t* payload,
size_t payload_length,
@@ -150,18 +126,21 @@
// Trigger our callbacks.
CheckSSRCChanged(rtp_header);
- if (CheckPayloadChanged(rtp_header, &payload_specific) == -1) {
- if (payload_length == 0) {
- // OK, keep-alive packet.
- return true;
- }
- RTC_LOG(LS_WARNING) << "Receiving invalid payload type.";
- return false;
+ if (payload_length == 0) {
+ // OK, keep-alive packet.
+ return true;
+ }
+ int64_t now_ms = clock_->TimeInMilliseconds();
+
+ {
+ rtc::CritScope lock(&critical_section_rtp_receiver_);
+
+ csrcs_.Update(
+ now_ms, rtc::MakeArrayView(rtp_header.arrOfCSRCs, rtp_header.numCSRCs));
}
WebRtcRTPHeader webrtc_rtp_header{};
webrtc_rtp_header.header = rtp_header;
- CheckCSRC(webrtc_rtp_header);
auto audio_level =
rtp_header.extension.hasAudioLevel
@@ -170,8 +149,7 @@
UpdateSources(audio_level);
int32_t ret_val = rtp_media_receiver_->ParseRtpPacket(
- &webrtc_rtp_header, payload_specific, payload, payload_length,
- clock_->TimeInMilliseconds());
+ &webrtc_rtp_header, payload_specific, payload, payload_length, now_ms);
if (ret_val < 0) {
return false;
@@ -195,24 +173,15 @@
return true;
}
-TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
- return rtp_media_receiver_->GetTelephoneEventHandler();
-}
-
std::vector<RtpSource> RtpReceiverImpl::GetSources() const {
rtc::CritScope lock(&critical_section_rtp_receiver_);
int64_t now_ms = clock_->TimeInMilliseconds();
- std::vector<RtpSource> sources;
-
RTC_DCHECK(std::is_sorted(ssrc_sources_.begin(), ssrc_sources_.end(),
[](const RtpSource& lhs, const RtpSource& rhs) {
return lhs.timestamp_ms() < rhs.timestamp_ms();
}));
- RTC_DCHECK(std::is_sorted(csrc_sources_.begin(), csrc_sources_.end(),
- [](const RtpSource& lhs, const RtpSource& rhs) {
- return lhs.timestamp_ms() < rhs.timestamp_ms();
- }));
+ std::vector<RtpSource> sources = csrcs_.GetSources(now_ms);
std::set<uint32_t> selected_ssrcs;
for (auto rit = ssrc_sources_.rbegin(); rit != ssrc_sources_.rend(); ++rit) {
@@ -223,13 +192,6 @@
sources.push_back(*rit);
}
}
-
- for (auto rit = csrc_sources_.rbegin(); rit != csrc_sources_.rend(); ++rit) {
- if ((now_ms - rit->timestamp_ms()) > kGetSourcesTimeoutMs) {
- break;
- }
- sources.push_back(*rit);
- }
return sources;
}
@@ -252,85 +214,11 @@
ssrc_ = rtp_header.ssrc;
}
-// Implementation note: must not hold critsect when called.
-// TODO(phoglund): Move as much as possible of this code path into the media
-// specific receivers. Basically this method goes through a lot of trouble to
-// compute something which is only used by the media specific parts later. If
-// this code path moves we can get rid of some of the rtp_receiver ->
-// media_specific interface (such as CheckPayloadChange, possibly get/set
-// last known payload).
-int32_t RtpReceiverImpl::CheckPayloadChanged(const RTPHeader& rtp_header,
- PayloadUnion* specific_payload) {
- int8_t payload_type = rtp_header.payloadType;
-
- {
- rtc::CritScope lock(&critical_section_rtp_receiver_);
-
- int8_t last_received_payload_type =
- rtp_payload_registry_->last_received_payload_type();
- // TODO(holmer): Remove this code when RED parsing has been broken out from
- // RtpReceiverAudio.
- if (payload_type != last_received_payload_type) {
- bool should_discard_changes = false;
-
- rtp_media_receiver_->CheckPayloadChanged(payload_type, specific_payload,
- &should_discard_changes);
-
- if (should_discard_changes) {
- return 0;
- }
-
- const auto payload =
- rtp_payload_registry_->PayloadTypeToPayload(payload_type);
- if (!payload) {
- // Not a registered payload type.
- return -1;
- }
- rtp_payload_registry_->set_last_received_payload_type(payload_type);
- }
- } // End critsect.
-
- return 0;
-}
-
-// Implementation note: must not hold critsect when called.
-void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) {
- const uint8_t num_csrcs = rtp_header.header.numCSRCs;
- if (num_csrcs > kRtpCsrcSize) {
- // Ignore.
- return;
- }
- {
- rtc::CritScope lock(&critical_section_rtp_receiver_);
-
- // Copy new.
- memcpy(current_remote_csrc_, rtp_header.header.arrOfCSRCs,
- num_csrcs * sizeof(uint32_t));
-
- num_csrcs_ = num_csrcs;
- } // End critsect.
-}
-
void RtpReceiverImpl::UpdateSources(
const absl::optional<uint8_t>& ssrc_audio_level) {
rtc::CritScope lock(&critical_section_rtp_receiver_);
int64_t now_ms = clock_->TimeInMilliseconds();
- for (size_t i = 0; i < num_csrcs_; ++i) {
- auto map_it = iterator_by_csrc_.find(current_remote_csrc_[i]);
- if (map_it == iterator_by_csrc_.end()) {
- // If it is a new CSRC, append a new object to the end of the list.
- csrc_sources_.emplace_back(now_ms, current_remote_csrc_[i],
- RtpSourceType::CSRC);
- } else {
- // If it is an existing CSRC, move the object to the end of the list.
- map_it->second->update_timestamp_ms(now_ms);
- csrc_sources_.splice(csrc_sources_.end(), csrc_sources_, map_it->second);
- }
- // Update the unordered_map.
- iterator_by_csrc_[current_remote_csrc_[i]] = std::prev(csrc_sources_.end());
- }
-
// If this is the first packet or the SSRC is changed, insert a new
// contributing source that uses the SSRC.
if (ssrc_sources_.empty() || ssrc_sources_.rbegin()->source_id() != ssrc_) {
@@ -345,15 +233,6 @@
}
void RtpReceiverImpl::RemoveOutdatedSources(int64_t now_ms) {
- std::list<RtpSource>::iterator it;
- for (it = csrc_sources_.begin(); it != csrc_sources_.end(); ++it) {
- if ((now_ms - it->timestamp_ms()) <= kGetSourcesTimeoutMs) {
- break;
- }
- iterator_by_csrc_.erase(it->source_id());
- }
- csrc_sources_.erase(csrc_sources_.begin(), it);
-
std::vector<RtpSource>::iterator vec_it;
for (vec_it = ssrc_sources_.begin(); vec_it != ssrc_sources_.end();
++vec_it) {
diff --git a/modules/rtp_rtcp/source/rtp_receiver_impl.h b/modules/rtp_rtcp/source/rtp_receiver_impl.h
index ec218d3..66265f5 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_impl.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_impl.h
@@ -11,7 +11,6 @@
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
#define MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
-#include <list>
#include <memory>
#include <unordered_map>
#include <vector>
@@ -19,9 +18,9 @@
#include "absl/types/optional.h"
#include "modules/rtp_rtcp/include/rtp_receiver.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "modules/rtp_rtcp/source/contributing_sources.h"
#include "modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "rtc_base/criticalsection.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -52,25 +51,10 @@
uint32_t SSRC() const override;
- int32_t CSRCs(uint32_t array_of_csrc[kRtpCsrcSize]) const override;
-
- TelephoneEventHandler* GetTelephoneEventHandler() override;
-
std::vector<RtpSource> GetSources() const override;
- const std::vector<RtpSource>& ssrc_sources_for_testing() const {
- return ssrc_sources_;
- }
-
- const std::list<RtpSource>& csrc_sources_for_testing() const {
- return csrc_sources_;
- }
-
private:
void CheckSSRCChanged(const RTPHeader& rtp_header);
- void CheckCSRC(const WebRtcRTPHeader& rtp_header);
- int32_t CheckPayloadChanged(const RTPHeader& rtp_header,
- PayloadUnion* payload);
void UpdateSources(const absl::optional<uint8_t>& ssrc_audio_level);
void RemoveOutdatedSources(int64_t now_ms);
@@ -84,9 +68,8 @@
// SSRCs.
uint32_t ssrc_ RTC_GUARDED_BY(critical_section_rtp_receiver_);
- uint8_t num_csrcs_ RTC_GUARDED_BY(critical_section_rtp_receiver_);
- uint32_t current_remote_csrc_[kRtpCsrcSize] RTC_GUARDED_BY(
- critical_section_rtp_receiver_);
+
+ ContributingSources csrcs_ RTC_GUARDED_BY(critical_section_rtp_receiver_);
// Sequence number and timestamps for the latest in-order packet.
absl::optional<uint16_t> last_received_sequence_number_
@@ -96,10 +79,7 @@
int64_t last_received_frame_time_ms_
RTC_GUARDED_BY(critical_section_rtp_receiver_);
- std::unordered_map<uint32_t, std::list<RtpSource>::iterator>
- iterator_by_csrc_;
// The RtpSource objects are sorted chronologically.
- std::list<RtpSource> csrc_sources_;
std::vector<RtpSource> ssrc_sources_;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_strategy.cc b/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
index bcce3e3..647ecea 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_strategy.cc
@@ -19,11 +19,4 @@
RTPReceiverStrategy::~RTPReceiverStrategy() = default;
-void RTPReceiverStrategy::CheckPayloadChanged(int8_t payload_type,
- PayloadUnion* specific_payload,
- bool* should_discard_changes) {
- // Default: Keep changes.
- *should_discard_changes = false;
-}
-
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_strategy.h b/modules/rtp_rtcp/source/rtp_receiver_strategy.h
index 8b13f18..987af7c 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_strategy.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_strategy.h
@@ -15,14 +15,11 @@
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_utility.h"
#include "rtc_base/criticalsection.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
struct CodecInst;
-class TelephoneEventHandler;
-
// This strategy deals with media-specific RTP packet processing.
// This class is not thread-safe and must be protected by its caller.
class RTPReceiverStrategy {
@@ -43,24 +40,6 @@
size_t payload_length,
int64_t timestamp_ms) = 0;
- virtual TelephoneEventHandler* GetTelephoneEventHandler() = 0;
-
- // Computes the current dead-or-alive state.
- virtual RTPAliveType ProcessDeadOrAlive(
- uint16_t last_payload_length) const = 0;
-
- // Notifies the strategy that we have created a new non-RED audio payload type
- // in the payload registry.
- virtual int32_t OnNewPayloadTypeCreated(
- int payload_type,
- const SdpAudioFormat& audio_format) = 0;
-
- // Checks if the payload type has changed, and returns whether we should
- // reset statistics and/or discard this packet.
- virtual void CheckPayloadChanged(int8_t payload_type,
- PayloadUnion* specific_payload,
- bool* should_discard_changes);
-
protected:
// The data callback is where we should send received payload data.
// See ParseRtpPacket. This class does not claim ownership of the callback.
diff --git a/modules/rtp_rtcp/source/rtp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtp_receiver_unittest.cc
index e8dccf4..1400288 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_unittest.cc
@@ -16,7 +16,6 @@
#include "modules/rtp_rtcp/include/rtp_receiver.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
-#include "modules/rtp_rtcp/source/rtp_receiver_impl.h"
#include "test/gmock.h"
#include "test/gtest.h"
@@ -235,20 +234,11 @@
header.arrOfCSRCs[0] = kCsrc1;
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(
header, kTestPayload, sizeof(kTestPayload), payload_specific));
- auto* rtp_receiver_impl = static_cast<RtpReceiverImpl*>(rtp_receiver_.get());
- auto ssrc_sources = rtp_receiver_impl->ssrc_sources_for_testing();
- ASSERT_EQ(1u, ssrc_sources.size());
- EXPECT_EQ(kSsrc1, ssrc_sources.begin()->source_id());
- EXPECT_EQ(RtpSourceType::SSRC, ssrc_sources.begin()->source_type());
- EXPECT_EQ(fake_clock_.TimeInMilliseconds(),
- ssrc_sources.begin()->timestamp_ms());
-
- auto csrc_sources = rtp_receiver_impl->csrc_sources_for_testing();
- ASSERT_EQ(1u, csrc_sources.size());
- EXPECT_EQ(kCsrc1, csrc_sources.begin()->source_id());
- EXPECT_EQ(RtpSourceType::CSRC, csrc_sources.begin()->source_type());
- EXPECT_EQ(fake_clock_.TimeInMilliseconds(),
- csrc_sources.begin()->timestamp_ms());
+ now_ms = fake_clock_.TimeInMilliseconds();
+ sources = rtp_receiver_->GetSources();
+ EXPECT_THAT(sources, UnorderedElementsAre(
+ RtpSource(now_ms, kSsrc1, RtpSourceType::SSRC),
+ RtpSource(now_ms, kCsrc1, RtpSourceType::CSRC)));
}
// The audio level from the RTPHeader extension should be stored in the
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.cc b/modules/rtp_rtcp/source/rtp_receiver_video.cc
index 5e6bf3e..1101bec 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -36,13 +36,6 @@
RTPReceiverVideo::~RTPReceiverVideo() {}
-int32_t RTPReceiverVideo::OnNewPayloadTypeCreated(
- int payload_type,
- const SdpAudioFormat& audio_format) {
- RTC_NOTREACHED();
- return 0;
-}
-
int32_t RTPReceiverVideo::ParseRtpPacket(WebRtcRTPHeader* rtp_header,
const PayloadUnion& specific_payload,
const uint8_t* payload,
@@ -108,13 +101,4 @@
: -1;
}
-TelephoneEventHandler* RTPReceiverVideo::GetTelephoneEventHandler() {
- return nullptr;
-}
-
-RTPAliveType RTPReceiverVideo::ProcessDeadOrAlive(
- uint16_t last_payload_length) const {
- return kRtpDead;
-}
-
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.h b/modules/rtp_rtcp/source/rtp_receiver_video.h
index d9404d1..46b97f5 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.h
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.h
@@ -15,7 +15,6 @@
#include "modules/rtp_rtcp/source/rtp_receiver_strategy.h"
#include "modules/rtp_rtcp/source/rtp_utility.h"
#include "rtc_base/onetimeevent.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -31,13 +30,6 @@
size_t packet_length,
int64_t timestamp) override;
- TelephoneEventHandler* GetTelephoneEventHandler() override;
-
- RTPAliveType ProcessDeadOrAlive(uint16_t last_payload_length) const override;
-
- int32_t OnNewPayloadTypeCreated(int payload_type,
- const SdpAudioFormat& audio_format) override;
-
void SetPacketOverHead(uint16_t packet_over_head);
private:
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_config.h b/modules/rtp_rtcp/source/rtp_rtcp_config.h
index a24bcdf..6863c4c 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_config.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_config.h
@@ -13,31 +13,11 @@
// Configuration file for RTP utilities (RTPSender, RTPReceiver ...)
namespace webrtc {
-enum { NACK_BYTECOUNT_SIZE = 60 }; // size of our NACK history
-// A sanity for the NACK list parsing at the send-side.
-enum { kSendSideNackListSizeSanity = 20000 };
enum { kDefaultMaxReorderingThreshold = 50 }; // In sequence numbers.
enum { kRtcpMaxNackFields = 253 };
enum { RTCP_SEND_BEFORE_KEY_FRAME_MS = 100 };
enum { RTCP_MAX_REPORT_BLOCKS = 31 }; // RFC 3550 page 37
-enum {
- kRtcpAppCode_DATA_SIZE = 32 * 4
-}; // multiple of 4, this is not a limitation of the size
-enum { RTCP_NUMBER_OF_SR = 60 };
-
-enum { MAX_NUMBER_OF_TEMPORAL_ID = 8 }; // RFC
-enum { MAX_NUMBER_OF_DEPENDENCY_QUALITY_ID = 128 }; // RFC
-enum { MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS = 255 };
-
-enum { BW_HISTORY_SIZE = 35 };
-
-#define MIN_AUDIO_BW_MANAGEMENT_BITRATE 6
-#define MIN_VIDEO_BW_MANAGEMENT_BITRATE 30
-
-enum { RTP_MAX_BURST_SLEEP_TIME = 500 };
-enum { RTP_AUDIO_LEVEL_UNIQUE_ID = 0xbede };
-enum { RTP_MAX_PACKETS_PER_FRAME = 512 }; // must be multiple of 32
} // namespace webrtc
#endif // MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
index 5071eee..2de6175 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl_unittest.cc
@@ -327,7 +327,7 @@
header.sequenceNumber = 123;
header.ssrc = kSenderSsrc;
header.headerLength = 12;
- receiver_.receive_statistics_->IncomingPacket(header, 100, false);
+ receiver_.receive_statistics_->IncomingPacket(header, 100);
// Send Frame before sending an SR.
SendFrame(&sender_, kBaseLayerTid);
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index e0347f0..ba04b5c 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -160,7 +160,9 @@
overhead_observer_(overhead_observer),
populate_network2_timestamp_(populate_network2_timestamp),
send_side_bwe_with_overhead_(
- webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")) {
+ webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")),
+ unlimited_retransmission_experiment_(
+ field_trial::IsEnabled("WebRTC-UnlimitedScreenshareRetransmission")) {
// This random initialization is not intended to be cryptographic strong.
timestamp_offset_ = random_.Rand<uint32_t>();
// Random start, 16 bits. Can't be 0.
@@ -412,6 +414,11 @@
*transport_frame_id_out = rtp_timestamp;
if (!sending_media_)
return true;
+
+ // Cache video content type.
+ if (!audio_configured_ && rtp_header) {
+ video_content_type_ = rtp_header->content_type;
+ }
}
VideoCodecType video_type = kVideoCodecGeneric;
if (CheckPayloadType(payload_type, &video_type) != 0) {
@@ -643,10 +650,21 @@
const int32_t packet_size = static_cast<int32_t>(stored_packet->payload_size);
+ // Skip retransmission rate check if sending screenshare and the experiment
+ // is on.
+ bool skip_retransmission_rate_limit;
+ {
+ rtc::CritScope lock(&send_critsect_);
+ skip_retransmission_rate_limit =
+ unlimited_retransmission_experiment_ && video_content_type_ &&
+ videocontenttypehelpers::IsScreenshare(*video_content_type_);
+ }
+
RTC_DCHECK(retransmission_rate_limiter_);
// Check if we're overusing retransmission bitrate.
// TODO(sprang): Add histograms for nack success or failure reasons.
- if (!retransmission_rate_limiter_->TryUseRate(packet_size)) {
+ if (!skip_retransmission_rate_limit &&
+ !retransmission_rate_limiter_->TryUseRate(packet_size)) {
return -1;
}
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index 5ff4a0f..7f66d24 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -20,6 +20,7 @@
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/call/transport.h"
+#include "api/video/video_content_type.h"
#include "common_types.h" // NOLINT(build/include)
#include "modules/rtp_rtcp/include/flexfec_sender.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
@@ -338,6 +339,11 @@
const bool send_side_bwe_with_overhead_;
+ const bool unlimited_retransmission_experiment_;
+
+ absl::optional<VideoContentType> video_content_type_
+ RTC_GUARDED_BY(send_critsect_);
+
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RTPSender);
};
diff --git a/modules/rtp_rtcp/source/rtp_sender_audio.h b/modules/rtp_rtcp/source/rtp_sender_audio.h
index 16648cd..63dfc2b 100644
--- a/modules/rtp_rtcp/source/rtp_sender_audio.h
+++ b/modules/rtp_rtcp/source/rtp_sender_audio.h
@@ -19,7 +19,6 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/onetimeevent.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 1d0ddaf..d143c87 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -34,7 +34,6 @@
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_transport.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -245,9 +244,10 @@
EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType, 90000,
0, 1500));
+ RTPVideoHeader video_header;
EXPECT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
- sizeof(kPayloadData), nullptr, nullptr, nullptr,
+ sizeof(kPayloadData), nullptr, &video_header, nullptr,
kDefaultExpectedRetransmissionTimeMs));
}
};
@@ -969,9 +969,10 @@
uint8_t payload[] = {47, 11, 32, 93, 89};
// Send keyframe
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload();
uint8_t generic_header = sent_payload[0];
@@ -986,7 +987,7 @@
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
sent_payload = transport_.last_sent_packet().payload();
generic_header = sent_payload[0];
@@ -1102,7 +1103,6 @@
EXPECT_EQ(0, rtp_sender_->RegisterPayload(payload_name, kPayloadType, 90000,
0, 1500));
RTPVideoHeader video_header;
- memset(&video_header, 0, sizeof(RTPVideoHeader));
video_header.video_timing.flags = VideoSendTiming::kTriggeredByTimer;
EXPECT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, kPayloadType, kTimestamp, kCaptureTimeMs, kPayloadData,
@@ -1301,9 +1301,10 @@
EXPECT_CALL(mock_paced_sender_, InsertPacket(_, _, _, _, _, _))
.Times(::testing::AtLeast(2));
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
EXPECT_EQ(1U, callback.num_calls_);
EXPECT_EQ(ssrc, callback.ssrc_);
@@ -1312,7 +1313,7 @@
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
EXPECT_EQ(2U, callback.num_calls_);
EXPECT_EQ(ssrc, callback.ssrc_);
@@ -1375,10 +1376,11 @@
rtp_sender_->ProcessBitrate();
// Send a few frames.
+ RTPVideoHeader video_header;
for (uint32_t i = 0; i < kNumPackets; ++i) {
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
}
@@ -1459,9 +1461,10 @@
rtp_sender_->RegisterRtpStatisticsCallback(&callback);
// Send a frame.
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
StreamDataCounters expected;
expected.transmitted.payload_bytes = 6;
expected.transmitted.header_bytes = 12;
@@ -1503,7 +1506,7 @@
rtp_sender_->SetFecParameters(fec_params, fec_params);
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameDelta, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
expected.transmitted.payload_bytes = 40;
expected.transmitted.header_bytes = 60;
expected.transmitted.packets = 5;
@@ -1520,9 +1523,10 @@
0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload();
EXPECT_THAT(sent_payload, ElementsAreArray(payload));
@@ -1539,9 +1543,10 @@
0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kAudioFrameCN, payload_type, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
auto sent_payload = transport_.last_sent_packet().payload();
EXPECT_THAT(sent_payload, ElementsAreArray(payload));
@@ -1578,22 +1583,23 @@
// During start, it takes the starting timestamp as last sent timestamp.
// The duration is calculated as the difference of current and last sent
// timestamp. So for first call it will skip since the duration is zero.
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kEmptyFrame, kPayloadType, capture_time_ms, 0, nullptr, 0, nullptr,
- nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// DTMF Sample Length is (Frequency/1000) * Duration.
// So in this case, it is (8000/1000) * 500 = 4000.
// Sending it as two packets.
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kEmptyFrame, kPayloadType, capture_time_ms + 2000, 0, nullptr, 0, nullptr,
- nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// Marker Bit should be set to 1 for first packet.
EXPECT_TRUE(transport_.last_sent_packet().Marker());
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kEmptyFrame, kPayloadType, capture_time_ms + 4000, 0, nullptr, 0, nullptr,
- nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// Marker Bit should be set to 0 for rest of the packets.
EXPECT_FALSE(transport_.last_sent_packet().Marker());
}
@@ -1610,9 +1616,10 @@
0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
+ RTPVideoHeader video_header;
ASSERT_TRUE(rtp_sender_->SendOutgoingData(
kVideoFrameKey, kPayloadType, 1234, 4321, payload, sizeof(payload),
- nullptr, nullptr, nullptr, kDefaultExpectedRetransmissionTimeMs));
+ nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs));
// Will send 2 full-size padding packets.
rtp_sender_->TimeToSendPadding(1, PacedPacketInfo());
@@ -1810,8 +1817,9 @@
TEST_P(RtpSenderVideoTest, RetransmissionTypesH264) {
RTPVideoHeader header;
+ header.video_type_header.emplace<RTPVideoHeaderH264>().packetization_mode =
+ H264PacketizationMode::NonInterleaved;
header.codec = kVideoCodecH264;
- header.h264().packetization_mode = H264PacketizationMode::NonInterleaved;
EXPECT_EQ(kDontRetransmit,
rtp_sender_video_->GetStorageType(
@@ -1892,8 +1900,9 @@
RTPVideoHeader header;
header.codec = kVideoCodecVP9;
+ auto& vp9_header = header.video_type_header.emplace<RTPVideoHeaderVP9>();
for (int tid = 1; tid <= kMaxTemporalStreams; ++tid) {
- header.vp9().temporal_idx = tid;
+ vp9_header.temporal_idx = tid;
EXPECT_EQ(kDontRetransmit, rtp_sender_video_->GetStorageType(
header, kRetransmitOff,
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index a7f3df0..bf8150d 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -280,6 +280,7 @@
int64_t expected_retransmission_time_ms) {
if (payload_size == 0)
return false;
+ RTC_CHECK(video_header);
// Create header that will be reused in all packets.
std::unique_ptr<RtpPacketToSend> rtp_header = rtp_sender_->AllocatePacket();
@@ -303,24 +304,22 @@
// packet in each group of packets which make up another type of frame
// (e.g. a P-Frame) only if the current value is different from the previous
// value sent.
- if (video_header) {
- // Set rotation when key frame or when changed (to follow standard).
- // Or when different from 0 (to follow current receiver implementation).
- VideoRotation current_rotation = video_header->rotation;
- if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ ||
- current_rotation != kVideoRotation_0)
- last_packet->SetExtension<VideoOrientation>(current_rotation);
- last_rotation_ = current_rotation;
- // Report content type only for key frames.
- if (frame_type == kVideoFrameKey &&
- video_header->content_type != VideoContentType::UNSPECIFIED) {
- last_packet->SetExtension<VideoContentTypeExtension>(
- video_header->content_type);
- }
- if (video_header->video_timing.flags != VideoSendTiming::kInvalid) {
- last_packet->SetExtension<VideoTimingExtension>(
- video_header->video_timing);
- }
+ // Set rotation when key frame or when changed (to follow standard).
+ // Or when different from 0 (to follow current receiver implementation).
+ VideoRotation current_rotation = video_header->rotation;
+ if (frame_type == kVideoFrameKey || current_rotation != last_rotation_ ||
+ current_rotation != kVideoRotation_0)
+ last_packet->SetExtension<VideoOrientation>(current_rotation);
+ last_rotation_ = current_rotation;
+ // Report content type only for key frames.
+ if (frame_type == kVideoFrameKey &&
+ video_header->content_type != VideoContentType::UNSPECIFIED) {
+ last_packet->SetExtension<VideoContentTypeExtension>(
+ video_header->content_type);
+ }
+ if (video_header->video_timing.flags != VideoSendTiming::kInvalid) {
+ last_packet->SetExtension<VideoTimingExtension>(
+ video_header->video_timing);
}
// FEC settings.
@@ -347,16 +346,17 @@
size_t last_packet_reduction_len =
last_packet->headers_size() - rtp_header->headers_size();
- std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create(
- video_type, max_data_payload_length, last_packet_reduction_len,
- video_header, frame_type));
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = max_data_payload_length;
+ limits.last_packet_reduction_len = last_packet_reduction_len;
+ std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create(
+ video_type, rtc::MakeArrayView(payload_data, payload_size), limits,
+ *video_header, frame_type, fragmentation);
- const uint8_t temporal_id =
- video_header ? GetTemporalId(*video_header) : kNoTemporalIdx;
+ const uint8_t temporal_id = GetTemporalId(*video_header);
StorageType storage = GetStorageType(temporal_id, retransmission_settings,
expected_retransmission_time_ms);
- size_t num_packets =
- packetizer->SetPayloadData(payload_data, payload_size, fragmentation);
+ size_t num_packets = packetizer->NumPackets();
if (num_packets == 0)
return false;
@@ -471,7 +471,8 @@
case kVideoCodecVP8:
return header.vp8().temporalIdx;
case kVideoCodecVP9:
- return header.vp9().temporal_idx;
+ return absl::get<RTPVideoHeaderVP9>(header.video_type_header)
+ .temporal_idx;
default:
return kNoTemporalIdx;
}
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index 08724c7..ce7be16 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -27,7 +27,6 @@
#include "rtc_base/rate_statistics.h"
#include "rtc_base/sequenced_task_checker.h"
#include "rtc_base/thread_annotations.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
class RtpPacketizer;
diff --git a/modules/rtp_rtcp/source/rtp_utility.h b/modules/rtp_rtcp/source/rtp_utility.h
index 51732df..762f964 100644
--- a/modules/rtp_rtcp/source/rtp_utility.h
+++ b/modules/rtp_rtcp/source/rtp_utility.h
@@ -19,7 +19,6 @@
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_config.h"
#include "rtc_base/deprecation.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/rtp_video_header.cc b/modules/rtp_rtcp/source/rtp_video_header.cc
index 020a52e..a3ee8ba 100644
--- a/modules/rtp_rtcp/source/rtp_video_header.cc
+++ b/modules/rtp_rtcp/source/rtp_video_header.cc
@@ -12,16 +12,13 @@
namespace webrtc {
-RTPVideoHeader::RTPVideoHeader()
- : width(),
- height(),
- rotation(),
- playout_delay(),
- content_type(),
- video_timing(),
- is_first_packet_in_frame(),
- simulcastIdx(),
- codec() {}
+RTPVideoHeader::RTPVideoHeader() : playout_delay(), video_timing() {}
RTPVideoHeader::RTPVideoHeader(const RTPVideoHeader& other) = default;
+RTPVideoHeader::~RTPVideoHeader() = default;
+
+RTPVideoHeader::GenericDescriptorInfo::GenericDescriptorInfo() = default;
+RTPVideoHeader::GenericDescriptorInfo::GenericDescriptorInfo(
+ const GenericDescriptorInfo& other) = default;
+RTPVideoHeader::GenericDescriptorInfo::~GenericDescriptorInfo() = default;
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/rtp_video_header.h b/modules/rtp_rtcp/source/rtp_video_header.h
index 49e2d29..520f4d4 100644
--- a/modules/rtp_rtcp/source/rtp_video_header.h
+++ b/modules/rtp_rtcp/source/rtp_video_header.h
@@ -10,6 +10,7 @@
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_HEADER_H_
#define MODULES_RTP_RTCP_SOURCE_RTP_VIDEO_HEADER_H_
+#include "absl/container/inlined_vector.h"
#include "absl/types/variant.h"
#include "api/video/video_content_type.h"
#include "api/video/video_rotation.h"
@@ -24,9 +25,23 @@
absl::variant<RTPVideoHeaderVP8, RTPVideoHeaderVP9, RTPVideoHeaderH264>;
struct RTPVideoHeader {
+ struct GenericDescriptorInfo {
+ GenericDescriptorInfo();
+ GenericDescriptorInfo(const GenericDescriptorInfo& other);
+ ~GenericDescriptorInfo();
+
+ int64_t frame_id = 0;
+ int spatial_index = 0;
+ int temporal_index = 0;
+ absl::InlinedVector<int64_t, 5> dependencies;
+ absl::InlinedVector<int, 5> higher_spatial_layers;
+ };
+
RTPVideoHeader();
RTPVideoHeader(const RTPVideoHeader& other);
+ ~RTPVideoHeader();
+
// TODO(philipel): Remove when downstream projects have been updated.
RTPVideoHeaderVP8& vp8() {
if (!absl::holds_alternative<RTPVideoHeaderVP8>(video_type_header))
@@ -41,44 +56,19 @@
return absl::get<RTPVideoHeaderVP8>(video_type_header);
}
- // TODO(philipel): Remove when downstream projects have been updated.
- RTPVideoHeaderVP9& vp9() {
- if (!absl::holds_alternative<RTPVideoHeaderVP9>(video_type_header))
- video_type_header.emplace<RTPVideoHeaderVP9>();
- return absl::get<RTPVideoHeaderVP9>(video_type_header);
- }
- // TODO(philipel): Remove when downstream projects have been updated.
- const RTPVideoHeaderVP9& vp9() const {
- if (!absl::holds_alternative<RTPVideoHeaderVP9>(video_type_header))
- video_type_header.emplace<RTPVideoHeaderVP9>();
+ absl::optional<GenericDescriptorInfo> generic;
- return absl::get<RTPVideoHeaderVP9>(video_type_header);
- }
- // TODO(philipel): Remove when downstream projects have been updated.
- RTPVideoHeaderH264& h264() {
- if (!absl::holds_alternative<RTPVideoHeaderH264>(video_type_header))
- video_type_header.emplace<RTPVideoHeaderH264>();
+ uint16_t width = 0;
+ uint16_t height = 0;
+ VideoRotation rotation = VideoRotation::kVideoRotation_0;
+ VideoContentType content_type = VideoContentType::UNSPECIFIED;
+ bool is_first_packet_in_frame = false;
+ uint8_t simulcastIdx = 0;
+ VideoCodecType codec = VideoCodecType::kVideoCodecGeneric;
- return absl::get<RTPVideoHeaderH264>(video_type_header);
- }
- // TODO(philipel): Remove when downstream projects have been updated.
- const RTPVideoHeaderH264& h264() const {
- if (!absl::holds_alternative<RTPVideoHeaderH264>(video_type_header))
- video_type_header.emplace<RTPVideoHeaderH264>();
-
- return absl::get<RTPVideoHeaderH264>(video_type_header);
- }
-
- uint16_t width;
- uint16_t height;
- VideoRotation rotation;
PlayoutDelay playout_delay;
- VideoContentType content_type;
VideoSendTiming video_timing;
- bool is_first_packet_in_frame;
- uint8_t simulcastIdx;
- VideoCodecType codec;
// TODO(philipel): remove mutable when downstream projects have been updated.
mutable RTPVideoTypeHeader video_type_header;
};
diff --git a/modules/rtp_rtcp/source/tmmbr_help.h b/modules/rtp_rtcp/source/tmmbr_help.h
index 46ce845..91aeaf4 100644
--- a/modules/rtp_rtcp/source/tmmbr_help.h
+++ b/modules/rtp_rtcp/source/tmmbr_help.h
@@ -13,7 +13,6 @@
#include <vector>
#include "modules/rtp_rtcp/source/rtcp_packet/tmmb_item.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/rtp_rtcp/source/ulpfec_receiver_impl.h b/modules/rtp_rtcp/source/ulpfec_receiver_impl.h
index 7dbc7dd..96367dc 100644
--- a/modules/rtp_rtcp/source/ulpfec_receiver_impl.h
+++ b/modules/rtp_rtcp/source/ulpfec_receiver_impl.h
@@ -18,7 +18,6 @@
#include "modules/rtp_rtcp/include/ulpfec_receiver.h"
#include "modules/rtp_rtcp/source/forward_error_correction.h"
#include "rtc_base/criticalsection.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/modules/third_party/fft/BUILD.gn b/modules/third_party/fft/BUILD.gn
new file mode 100644
index 0000000..ad51341
--- /dev/null
+++ b/modules/third_party/fft/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("fft") {
+ sources = [
+ "fft.c",
+ "fft.h",
+ ]
+}
diff --git a/modules/third_party/fft/LICENSE b/modules/third_party/fft/LICENSE
new file mode 100644
index 0000000..c0a7805
--- /dev/null
+++ b/modules/third_party/fft/LICENSE
@@ -0,0 +1,25 @@
+/*
+ * Copyright(c)1995,97 Mark Olesen <olesen@me.QueensU.CA>
+ * Queen's Univ at Kingston (Canada)
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose without fee is hereby granted, provided that this
+ * entire notice is included in all copies of any software which is
+ * or includes a copy or modification of this software and in all
+ * copies of the supporting documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR QUEEN'S
+ * UNIVERSITY AT KINGSTON MAKES ANY REPRESENTATION OR WARRANTY OF ANY
+ * KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * All of which is to say that you can do what you like with this
+ * source code provided you don't try to sell it as your own and you
+ * include an unaltered copy of this message (including the
+ * copyright).
+ *
+ * It is also implicitly understood that bug fixes and improvements
+ * should make their way back to the general Internet community so
+ * that everyone benefits.
+ */
diff --git a/modules/third_party/fft/README.chromium b/modules/third_party/fft/README.chromium
new file mode 100644
index 0000000..94d20d4
--- /dev/null
+++ b/modules/third_party/fft/README.chromium
@@ -0,0 +1,12 @@
+Name: fft
+Short Name: fft
+URL:
+Version: 0
+Date: 2018-07-26
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+Multivariate complex Fourier transform, computed in place
+using mixed-radix Fast Fourier Transform algorithm.
diff --git a/modules/audio_coding/codecs/isac/main/source/fft.c b/modules/third_party/fft/fft.c
similarity index 99%
rename from modules/audio_coding/codecs/isac/main/source/fft.c
rename to modules/third_party/fft/fft.c
index a3cbd5e..7260462 100644
--- a/modules/audio_coding/codecs/isac/main/source/fft.c
+++ b/modules/third_party/fft/fft.c
@@ -127,7 +127,7 @@
#include <stdlib.h>
#include <math.h>
-#include "modules/audio_coding/codecs/isac/main/source/fft.h"
+#include "modules/third_party/fft/fft.h"
/* double precision routine */
static int
@@ -211,7 +211,7 @@
{
max_factors = (int)nSpan;
}
- if ((int)nSpan > max_perm)
+ if ((int)nSpan > max_perm)
{
max_perm = (int)nSpan;
}
@@ -415,7 +415,7 @@
}
/* test that mfactors is in range */
- if (mfactor > NFACTOR)
+ if (mfactor > FFT_NFACTOR)
{
return -1;
}
diff --git a/modules/audio_coding/codecs/isac/main/source/fft.h b/modules/third_party/fft/fft.h
similarity index 73%
rename from modules/audio_coding/codecs/isac/main/source/fft.h
rename to modules/third_party/fft/fft.h
index 34e5f94..f8f8b6f 100644
--- a/modules/audio_coding/codecs/isac/main/source/fft.h
+++ b/modules/third_party/fft/fft.h
@@ -2,7 +2,7 @@
* Copyright (c) 2011 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
+ * 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.
@@ -27,10 +27,23 @@
* See the comments in the code for correct usage!
*/
-#ifndef MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_
-#define MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_
+#ifndef MODULES_THIRD_PARTY_FFT_FFT_H_
+#define MODULES_THIRD_PARTY_FFT_FFT_H_
-#include "modules/audio_coding/codecs/isac/main/source/structs.h"
+#define FFT_MAXFFTSIZE 2048
+#define FFT_NFACTOR 11
+
+typedef struct {
+ unsigned int SpaceAlloced;
+ unsigned int MaxPermAlloced;
+ double Tmp0[FFT_MAXFFTSIZE];
+ double Tmp1[FFT_MAXFFTSIZE];
+ double Tmp2[FFT_MAXFFTSIZE];
+ double Tmp3[FFT_MAXFFTSIZE];
+ int Perm[FFT_MAXFFTSIZE];
+ int factor[FFT_NFACTOR];
+
+} FFTstr;
/* double precision routine */
@@ -42,4 +55,4 @@
double scaling,
FFTstr* fftstate);
-#endif /* MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_FFT_H_ */
+#endif /* MODULES_THIRD_PARTY_FFT_FFT_H_ */
diff --git a/modules/third_party/fft/module.mk b/modules/third_party/fft/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/modules/third_party/fft/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/modules/third_party/g711/BUILD.gn b/modules/third_party/g711/BUILD.gn
new file mode 100644
index 0000000..ca1ccf3
--- /dev/null
+++ b/modules/third_party/g711/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("g711_3p") {
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "g711.c",
+ "g711.h",
+ ]
+}
diff --git a/modules/third_party/g711/LICENSE b/modules/third_party/g711/LICENSE
new file mode 100644
index 0000000..3cdf910
--- /dev/null
+++ b/modules/third_party/g711/LICENSE
@@ -0,0 +1,14 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g711.h - In line A-law and u-law conversion routines
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2001 Steve Underwood
+ *
+ * Despite my general liking of the GPL, I place this code in the
+ * public domain for the benefit of all mankind - even the slimy
+ * ones who might try to proprietize my work and use it to my
+ * detriment.
+ */
diff --git a/modules/third_party/g711/README.chromium b/modules/third_party/g711/README.chromium
new file mode 100644
index 0000000..1baa263
--- /dev/null
+++ b/modules/third_party/g711/README.chromium
@@ -0,0 +1,11 @@
+Name: In line A-law and u-law conversion routines
+Short Name: g711
+URL:
+Version: 0
+Date: 2018-06-25
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+In line A-law and u-law conversion routines
diff --git a/modules/audio_coding/codecs/g711/g711.c b/modules/third_party/g711/g711.c
similarity index 98%
rename from modules/audio_coding/codecs/g711/g711.c
rename to modules/third_party/g711/g711.c
index 46a21f4..b7ae6bb 100644
--- a/modules/audio_coding/codecs/g711/g711.c
+++ b/modules/third_party/g711/g711.c
@@ -20,7 +20,7 @@
* -Added option to run encoder bitexact with ITU-T reference implementation
*/
-#include "modules/audio_coding/codecs/g711/g711.h"
+#include "modules/third_party/g711/g711.h"
/* Copied from the CCITT G.711 specification */
static const uint8_t ulaw_to_alaw_table[256] = {
diff --git a/modules/audio_coding/codecs/g711/g711.h b/modules/third_party/g711/g711.h
similarity index 98%
rename from modules/audio_coding/codecs/g711/g711.h
rename to modules/third_party/g711/g711.h
index ac43377..4eef42c 100644
--- a/modules/audio_coding/codecs/g711/g711.h
+++ b/modules/third_party/g711/g711.h
@@ -43,8 +43,8 @@
specification by other means.
*/
-#if !defined(_G711_H_)
-#define _G711_H_
+#ifndef MODULES_THIRD_PARTY_G711_G711_H_
+#define MODULES_THIRD_PARTY_G711_G711_H_
#ifdef __cplusplus
extern "C" {
@@ -347,4 +347,4 @@
}
#endif
-#endif
+#endif /* MODULES_THIRD_PARTY_G711_G711_H_ */
diff --git a/modules/third_party/g722/BUILD.gn b/modules/third_party/g722/BUILD.gn
new file mode 100644
index 0000000..a1bfe89
--- /dev/null
+++ b/modules/third_party/g722/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("g722_3p") {
+ poisonous = [ "audio_codecs" ]
+ sources = [
+ "g722_decode.c",
+ "g722_enc_dec.h",
+ "g722_encode.c",
+ ]
+}
diff --git a/modules/third_party/g722/LICENSE b/modules/third_party/g722/LICENSE
new file mode 100644
index 0000000..ea6308f
--- /dev/null
+++ b/modules/third_party/g722/LICENSE
@@ -0,0 +1,20 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g722_decode.c - The ITU G.722 codec, decode part.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2005 Steve Underwood
+ *
+ * Despite my general liking of the GPL, I place my own contributions
+ * to this code in the public domain for the benefit of all mankind -
+ * even the slimy ones who might try to proprietize my work and use it
+ * to my detriment.
+ *
+ * Based in part on a single channel G.722 codec which is:
+ *
+ * Copyright (c) CMU 1993
+ * Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ */
diff --git a/modules/third_party/g722/README.chromium b/modules/third_party/g722/README.chromium
new file mode 100644
index 0000000..c427ed8
--- /dev/null
+++ b/modules/third_party/g722/README.chromium
@@ -0,0 +1,11 @@
+Name: The ITU G.722 codec, encode and decode part.
+Short Name: g722
+URL:
+Version: 0
+Date: 2018-06-25
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+The ITU G.722 codec, encode and decode part.
diff --git a/modules/audio_coding/codecs/g722/g722_decode.c b/modules/third_party/g722/g722_decode.c
similarity index 99%
rename from modules/audio_coding/codecs/g722/g722_decode.c
rename to modules/third_party/g722/g722_decode.c
index d638f50..012aeb5 100644
--- a/modules/audio_coding/codecs/g722/g722_decode.c
+++ b/modules/third_party/g722/g722_decode.c
@@ -34,7 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "modules/audio_coding/codecs/g722/g722_enc_dec.h"
+#include "modules/third_party/g722/g722_enc_dec.h"
#if !defined(FALSE)
#define FALSE 0
diff --git a/modules/audio_coding/codecs/g722/g722_enc_dec.h b/modules/third_party/g722/g722_enc_dec.h
similarity index 96%
rename from modules/audio_coding/codecs/g722/g722_enc_dec.h
rename to modules/third_party/g722/g722_enc_dec.h
index cc3aa98..898fa27 100644
--- a/modules/audio_coding/codecs/g722/g722_enc_dec.h
+++ b/modules/third_party/g722/g722_enc_dec.h
@@ -27,8 +27,8 @@
/*! \file */
-#if !defined(_G722_ENC_DEC_H_)
-#define _G722_ENC_DEC_H_
+#ifndef MODULES_THIRD_PARTY_G722_G722_H_
+#define MODULES_THIRD_PARTY_G722_G722_H_
#include <stdint.h>
@@ -150,4 +150,4 @@
}
#endif
-#endif
+#endif /* MODULES_THIRD_PARTY_G722_G722_H_ */
diff --git a/modules/audio_coding/codecs/g722/g722_encode.c b/modules/third_party/g722/g722_encode.c
similarity index 99%
rename from modules/audio_coding/codecs/g722/g722_encode.c
rename to modules/third_party/g722/g722_encode.c
index cd19252..10a5bcf 100644
--- a/modules/audio_coding/codecs/g722/g722_encode.c
+++ b/modules/third_party/g722/g722_encode.c
@@ -34,7 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "modules/audio_coding/codecs/g722/g722_enc_dec.h"
+#include "modules/third_party/g722/g722_enc_dec.h"
#if !defined(FALSE)
#define FALSE 0
diff --git a/modules/third_party/module.mk b/modules/third_party/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/modules/third_party/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/modules/third_party/portaudio/BUILD.gn b/modules/third_party/portaudio/BUILD.gn
new file mode 100644
index 0000000..1f701db
--- /dev/null
+++ b/modules/third_party/portaudio/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("mac_portaudio") {
+ visibility = [ "../../audio_device:*" ]
+ sources = [
+ "pa_memorybarrier.h",
+ "pa_ringbuffer.c",
+ "pa_ringbuffer.h",
+ ]
+}
diff --git a/modules/third_party/portaudio/LICENSE b/modules/third_party/portaudio/LICENSE
new file mode 100644
index 0000000..6ccaca2
--- /dev/null
+++ b/modules/third_party/portaudio/LICENSE
@@ -0,0 +1,91 @@
+/*
+ * $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $
+ * Portable Audio I/O Library
+ * Memory barrier utilities
+ *
+ * Author: Bjorn Roche, XO Audio, LLC
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however,
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
+ * license above.
+ */
+
+/*
+ * $Id: pa_ringbuffer.c 1421 2009-11-18 16:09:05Z bjornroche $
+ * Portable Audio I/O Library
+ * Ring Buffer utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ * modified for SMP safety on Mac OS X by Bjorn Roche
+ * modified for SMP safety on Linux by Leland Lucius
+ * also, allowed for const where possible
+ * modified for multiple-byte-sized data elements by Sven Fischer
+ *
+ * Note that this is safe only for a single-thread reader and a
+ * single-thread writer.
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however,
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
+ * license above.
+ */
+
diff --git a/modules/third_party/portaudio/README.chromium b/modules/third_party/portaudio/README.chromium
new file mode 100644
index 0000000..7a15b2e
--- /dev/null
+++ b/modules/third_party/portaudio/README.chromium
@@ -0,0 +1,12 @@
+Name: Portaudio library for mac
+Short Name: portaudio
+URL: https://app.assembla.com/spaces/portaudio/git/source/master/src/common
+Version: 0
+Date: 2018-02-01
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+Part of portaudio library to operate with memory barriers and ring buffer.
+
diff --git a/modules/third_party/portaudio/pa_memorybarrier.h b/modules/third_party/portaudio/pa_memorybarrier.h
new file mode 100644
index 0000000..c1040d1
--- /dev/null
+++ b/modules/third_party/portaudio/pa_memorybarrier.h
@@ -0,0 +1,132 @@
+/*
+ * $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $
+ * Portable Audio I/O Library
+ * Memory barrier utilities
+ *
+ * Author: Bjorn Roche, XO Audio, LLC
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however,
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
+ * license above.
+ */
+
+/**
+ @file pa_memorybarrier.h
+ @ingroup common_src
+*/
+
+/****************
+ * Some memory barrier primitives based on the system.
+ * right now only OS X, FreeBSD, and Linux are supported. In addition to
+ *providing memory barriers, these functions should ensure that data cached in
+ *registers is written out to cache where it can be snooped by other CPUs. (ie,
+ *the volatile keyword should not be required)
+ *
+ * the primitives that must be defined are:
+ *
+ * PaUtil_FullMemoryBarrier()
+ * PaUtil_ReadMemoryBarrier()
+ * PaUtil_WriteMemoryBarrier()
+ *
+ ****************/
+
+#ifndef MODULES_THIRD_PARTY_PORTAUDIO_PA_MEMORYBARRIER_H_
+#define MODULES_THIRD_PARTY_PORTAUDIO_PA_MEMORYBARRIER_H_
+
+#if defined(__APPLE__)
+#include <libkern/OSAtomic.h>
+/* Here are the memory barrier functions. Mac OS X only provides
+ full memory barriers, so the three types of barriers are the same,
+ however, these barriers are superior to compiler-based ones. */
+#define PaUtil_FullMemoryBarrier() OSMemoryBarrier()
+#define PaUtil_ReadMemoryBarrier() OSMemoryBarrier()
+#define PaUtil_WriteMemoryBarrier() OSMemoryBarrier()
+#elif defined(__GNUC__)
+/* GCC >= 4.1 has built-in intrinsics. We'll use those */
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
+#define PaUtil_FullMemoryBarrier() __sync_synchronize()
+#define PaUtil_ReadMemoryBarrier() __sync_synchronize()
+#define PaUtil_WriteMemoryBarrier() __sync_synchronize()
+/* as a fallback, GCC understands volatile asm and "memory" to mean it
+ * should not reorder memory read/writes */
+/* Note that it is not clear that any compiler actually defines __PPC__,
+ * it can probably removed safely. */
+#elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__)
+#define PaUtil_FullMemoryBarrier() asm volatile("sync" ::: "memory")
+#define PaUtil_ReadMemoryBarrier() asm volatile("sync" ::: "memory")
+#define PaUtil_WriteMemoryBarrier() asm volatile("sync" ::: "memory")
+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \
+ defined(__i686__) || defined(__x86_64__)
+#define PaUtil_FullMemoryBarrier() asm volatile("mfence" ::: "memory")
+#define PaUtil_ReadMemoryBarrier() asm volatile("lfence" ::: "memory")
+#define PaUtil_WriteMemoryBarrier() asm volatile("sfence" ::: "memory")
+#else
+#ifdef ALLOW_SMP_DANGERS
+#warning Memory barriers not defined on this system or system unknown
+#warning For SMP safety, you should fix this.
+#define PaUtil_FullMemoryBarrier()
+#define PaUtil_ReadMemoryBarrier()
+#define PaUtil_WriteMemoryBarrier()
+#else
+# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
+#endif
+#endif
+#elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE)
+#include <intrin.h>
+#pragma intrinsic(_ReadWriteBarrier)
+#pragma intrinsic(_ReadBarrier)
+#pragma intrinsic(_WriteBarrier)
+#define PaUtil_FullMemoryBarrier() _ReadWriteBarrier()
+#define PaUtil_ReadMemoryBarrier() _ReadBarrier()
+#define PaUtil_WriteMemoryBarrier() _WriteBarrier()
+#elif defined(_WIN32_WCE)
+#define PaUtil_FullMemoryBarrier()
+#define PaUtil_ReadMemoryBarrier()
+#define PaUtil_WriteMemoryBarrier()
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+#define PaUtil_FullMemoryBarrier() _asm { lock add [esp], 0}
+#define PaUtil_ReadMemoryBarrier() _asm { lock add [esp], 0}
+#define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0}
+#else
+#ifdef ALLOW_SMP_DANGERS
+#warning Memory barriers not defined on this system or system unknown
+#warning For SMP safety, you should fix this.
+#define PaUtil_FullMemoryBarrier()
+#define PaUtil_ReadMemoryBarrier()
+#define PaUtil_WriteMemoryBarrier()
+#else
+# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
+#endif
+#endif
+
+#endif /* MODULES_THIRD_PARTY_PORTAUDIO_PA_MEMORYBARRIER_H_ */
diff --git a/modules/third_party/portaudio/pa_ringbuffer.c b/modules/third_party/portaudio/pa_ringbuffer.c
new file mode 100644
index 0000000..fc1053c
--- /dev/null
+++ b/modules/third_party/portaudio/pa_ringbuffer.c
@@ -0,0 +1,237 @@
+/*
+ * $Id: pa_ringbuffer.c 1421 2009-11-18 16:09:05Z bjornroche $
+ * Portable Audio I/O Library
+ * Ring Buffer utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ * modified for SMP safety on Mac OS X by Bjorn Roche
+ * modified for SMP safety on Linux by Leland Lucius
+ * also, allowed for const where possible
+ * modified for multiple-byte-sized data elements by Sven Fischer
+ *
+ * Note that this is safe only for a single-thread reader and a
+ * single-thread writer.
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however,
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
+ * license above.
+ */
+
+/**
+ @file
+ @ingroup common_src
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "modules/third_party/portaudio/pa_memorybarrier.h"
+#include "modules/third_party/portaudio/pa_ringbuffer.h"
+
+/***************************************************************************
+ * Initialize FIFO.
+ * elementCount must be power of 2, returns -1 if not.
+ */
+PaRingBufferSize PaUtil_InitializeRingBuffer(PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementSizeBytes,
+ PaRingBufferSize elementCount,
+ void* dataPtr) {
+ if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */
+ rbuf->bufferSize = elementCount;
+ rbuf->buffer = (char *)dataPtr;
+ PaUtil_FlushRingBuffer( rbuf );
+ rbuf->bigMask = (elementCount*2)-1;
+ rbuf->smallMask = (elementCount)-1;
+ rbuf->elementSizeBytes = elementSizeBytes;
+ return 0;
+}
+
+/***************************************************************************
+** Return number of elements available for reading. */
+PaRingBufferSize PaUtil_GetRingBufferReadAvailable( PaUtilRingBuffer *rbuf )
+{
+ PaUtil_ReadMemoryBarrier();
+ return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
+}
+/***************************************************************************
+** Return number of elements available for writing. */
+PaRingBufferSize PaUtil_GetRingBufferWriteAvailable( PaUtilRingBuffer *rbuf )
+{
+ /* Since we are calling PaUtil_GetRingBufferReadAvailable, we don't need an aditional MB */
+ return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf));
+}
+
+/***************************************************************************
+** Clear buffer. Should only be called when buffer is NOT being read. */
+void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf )
+{
+ rbuf->writeIndex = rbuf->readIndex = 0;
+}
+
+/***************************************************************************
+** Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or elementCount, whichever is smaller.
+*/
+PaRingBufferSize PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount,
+ void** dataPtr1,
+ PaRingBufferSize* sizePtr1,
+ void** dataPtr2,
+ PaRingBufferSize* sizePtr2) {
+ PaRingBufferSize index;
+ PaRingBufferSize available = PaUtil_GetRingBufferWriteAvailable( rbuf );
+ if( elementCount > available ) elementCount = available;
+ /* Check to see if write is not contiguous. */
+ index = rbuf->writeIndex & rbuf->smallMask;
+ if( (index + elementCount) > rbuf->bufferSize )
+ {
+ /* Write data in two blocks that wrap the buffer. */
+ PaRingBufferSize firstHalf = rbuf->bufferSize - index;
+ *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = elementCount - firstHalf;
+ }
+ else
+ {
+ *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
+ *sizePtr1 = elementCount;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return elementCount;
+}
+
+
+/***************************************************************************
+*/
+PaRingBufferSize PaUtil_AdvanceRingBufferWriteIndex(
+ PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount) {
+ /* we need to ensure that previous writes are seen before we update the write index */
+ PaUtil_WriteMemoryBarrier();
+ return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask;
+}
+
+/***************************************************************************
+** Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or elementCount, whichever is smaller.
+*/
+PaRingBufferSize PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount,
+ void** dataPtr1,
+ PaRingBufferSize* sizePtr1,
+ void** dataPtr2,
+ PaRingBufferSize* sizePtr2) {
+ PaRingBufferSize index;
+ PaRingBufferSize available = PaUtil_GetRingBufferReadAvailable( rbuf );
+ if( elementCount > available ) elementCount = available;
+ /* Check to see if read is not contiguous. */
+ index = rbuf->readIndex & rbuf->smallMask;
+ if( (index + elementCount) > rbuf->bufferSize )
+ {
+ /* Write data in two blocks that wrap the buffer. */
+ PaRingBufferSize firstHalf = rbuf->bufferSize - index;
+ *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
+ *sizePtr1 = firstHalf;
+ *dataPtr2 = &rbuf->buffer[0];
+ *sizePtr2 = elementCount - firstHalf;
+ }
+ else
+ {
+ *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes];
+ *sizePtr1 = elementCount;
+ *dataPtr2 = NULL;
+ *sizePtr2 = 0;
+ }
+ return elementCount;
+}
+/***************************************************************************
+*/
+PaRingBufferSize PaUtil_AdvanceRingBufferReadIndex(
+ PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount) {
+ /* we need to ensure that previous writes are always seen before updating the index. */
+ PaUtil_WriteMemoryBarrier();
+ return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask;
+}
+
+/***************************************************************************
+** Return elements written. */
+PaRingBufferSize PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf,
+ const void* data,
+ PaRingBufferSize elementCount) {
+ PaRingBufferSize size1, size2, numWritten;
+ void *data1, *data2;
+ numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
+ if( size2 > 0 )
+ {
+
+ memcpy( data1, data, size1*rbuf->elementSizeBytes );
+ data = ((char *)data) + size1*rbuf->elementSizeBytes;
+ memcpy( data2, data, size2*rbuf->elementSizeBytes );
+ }
+ else
+ {
+ memcpy( data1, data, size1*rbuf->elementSizeBytes );
+ }
+ PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten );
+ return numWritten;
+}
+
+/***************************************************************************
+** Return elements read. */
+PaRingBufferSize PaUtil_ReadRingBuffer(PaUtilRingBuffer* rbuf,
+ void* data,
+ PaRingBufferSize elementCount) {
+ PaRingBufferSize size1, size2, numRead;
+ void *data1, *data2;
+ numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 );
+ if( size2 > 0 )
+ {
+ memcpy( data, data1, size1*rbuf->elementSizeBytes );
+ data = ((char *)data) + size1*rbuf->elementSizeBytes;
+ memcpy( data, data2, size2*rbuf->elementSizeBytes );
+ }
+ else
+ {
+ memcpy( data, data1, size1*rbuf->elementSizeBytes );
+ }
+ PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead );
+ return numRead;
+}
diff --git a/modules/third_party/portaudio/pa_ringbuffer.h b/modules/third_party/portaudio/pa_ringbuffer.h
new file mode 100644
index 0000000..3ad8216
--- /dev/null
+++ b/modules/third_party/portaudio/pa_ringbuffer.h
@@ -0,0 +1,251 @@
+#ifndef MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_
+#define MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_
+/*
+ * $Id: pa_ringbuffer.h 1421 2009-11-18 16:09:05Z bjornroche $
+ * Portable Audio I/O Library
+ * Ring Buffer utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ * modified for SMP safety on OS X by Bjorn Roche.
+ * also allowed for const where possible.
+ * modified for multiple-byte-sized data elements by Sven Fischer
+ *
+ * Note that this is safe only for a single-thread reader
+ * and a single-thread writer.
+ *
+ * This program is distributed with the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The text above constitutes the entire PortAudio license; however,
+ * the PortAudio community also makes the following non-binding requests:
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
+ * license above.
+ */
+
+/** @file
+ @ingroup common_src
+ @brief Single-reader single-writer lock-free ring buffer
+
+ PaUtilRingBuffer is a ring buffer used to transport samples between
+ different execution contexts (threads, OS callbacks, interrupt handlers)
+ without requiring the use of any locks. This only works when there is
+ a single reader and a single writer (ie. one thread or callback writes
+ to the ring buffer, another thread or callback reads from it).
+
+ The PaUtilRingBuffer structure manages a ring buffer containing N
+ elements, where N must be a power of two. An element may be any size
+ (specified in bytes).
+
+ The memory area used to store the buffer elements must be allocated by
+ the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
+ the use of the ring buffer.
+*/
+
+#if defined(__APPLE__)
+#include <sys/types.h>
+typedef int32_t PaRingBufferSize;
+#elif defined(__GNUC__)
+typedef long PaRingBufferSize;
+#elif (_MSC_VER >= 1400)
+typedef long PaRingBufferSize;
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+typedef long PaRingBufferSize;
+#else
+typedef long PaRingBufferSize;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct PaUtilRingBuffer {
+ PaRingBufferSize
+ bufferSize; /**< Number of elements in FIFO. Power of 2. Set by
+ PaUtil_InitRingBuffer. */
+ PaRingBufferSize writeIndex; /**< Index of next writable element. Set by
+ PaUtil_AdvanceRingBufferWriteIndex. */
+ PaRingBufferSize readIndex; /**< Index of next readable element. Set by
+ PaUtil_AdvanceRingBufferReadIndex. */
+ PaRingBufferSize bigMask; /**< Used for wrapping indices with extra bit to
+ distinguish full/empty. */
+ PaRingBufferSize smallMask; /**< Used for fitting indices to buffer. */
+ PaRingBufferSize elementSizeBytes; /**< Number of bytes per element. */
+ char* buffer; /**< Pointer to the buffer containing the actual data. */
+} PaUtilRingBuffer;
+
+/** Initialize Ring Buffer.
+
+ @param rbuf The ring buffer.
+
+ @param elementSizeBytes The size of a single data element in bytes.
+
+ @param elementCount The number of elements in the buffer (must be power of 2).
+
+ @param dataPtr A pointer to a previously allocated area where the data
+ will be maintained. It must be elementCount*elementSizeBytes long.
+
+ @return -1 if elementCount is not a power of 2, otherwise 0.
+*/
+PaRingBufferSize PaUtil_InitializeRingBuffer(PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementSizeBytes,
+ PaRingBufferSize elementCount,
+ void* dataPtr);
+
+/** Clear buffer. Should only be called when buffer is NOT being read.
+
+ @param rbuf The ring buffer.
+*/
+void PaUtil_FlushRingBuffer(PaUtilRingBuffer* rbuf);
+
+/** Retrieve the number of elements available in the ring buffer for writing.
+
+ @param rbuf The ring buffer.
+
+ @return The number of elements available for writing.
+*/
+PaRingBufferSize PaUtil_GetRingBufferWriteAvailable(PaUtilRingBuffer* rbuf);
+
+/** Retrieve the number of elements available in the ring buffer for reading.
+
+ @param rbuf The ring buffer.
+
+ @return The number of elements available for reading.
+*/
+PaRingBufferSize PaUtil_GetRingBufferReadAvailable(PaUtilRingBuffer* rbuf);
+
+/** Write data to the ring buffer.
+
+ @param rbuf The ring buffer.
+
+ @param data The address of new data to write to the buffer.
+
+ @param elementCount The number of elements to be written.
+
+ @return The number of elements written.
+*/
+PaRingBufferSize PaUtil_WriteRingBuffer(PaUtilRingBuffer* rbuf,
+ const void* data,
+ PaRingBufferSize elementCount);
+
+/** Read data from the ring buffer.
+
+ @param rbuf The ring buffer.
+
+ @param data The address where the data should be stored.
+
+ @param elementCount The number of elements to be read.
+
+ @return The number of elements read.
+*/
+PaRingBufferSize PaUtil_ReadRingBuffer(PaUtilRingBuffer* rbuf,
+ void* data,
+ PaRingBufferSize elementCount);
+
+/** Get address of region(s) to which we can write data.
+
+ @param rbuf The ring buffer.
+
+ @param elementCount The number of elements desired.
+
+ @param dataPtr1 The address where the first (or only) region pointer will be
+ stored.
+
+ @param sizePtr1 The address where the first (or only) region length will be
+ stored.
+
+ @param dataPtr2 The address where the second region pointer will be stored if
+ the first region is too small to satisfy elementCount.
+
+ @param sizePtr2 The address where the second region length will be stored if
+ the first region is too small to satisfy elementCount.
+
+ @return The room available to be written or elementCount, whichever is smaller.
+*/
+PaRingBufferSize PaUtil_GetRingBufferWriteRegions(PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount,
+ void** dataPtr1,
+ PaRingBufferSize* sizePtr1,
+ void** dataPtr2,
+ PaRingBufferSize* sizePtr2);
+
+/** Advance the write index to the next location to be written.
+
+ @param rbuf The ring buffer.
+
+ @param elementCount The number of elements to advance.
+
+ @return The new position.
+*/
+PaRingBufferSize PaUtil_AdvanceRingBufferWriteIndex(
+ PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount);
+
+/** Get address of region(s) from which we can write data.
+
+ @param rbuf The ring buffer.
+
+ @param elementCount The number of elements desired.
+
+ @param dataPtr1 The address where the first (or only) region pointer will be
+ stored.
+
+ @param sizePtr1 The address where the first (or only) region length will be
+ stored.
+
+ @param dataPtr2 The address where the second region pointer will be stored if
+ the first region is too small to satisfy elementCount.
+
+ @param sizePtr2 The address where the second region length will be stored if
+ the first region is too small to satisfy elementCount.
+
+ @return The number of elements available for reading.
+*/
+PaRingBufferSize PaUtil_GetRingBufferReadRegions(PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount,
+ void** dataPtr1,
+ PaRingBufferSize* sizePtr1,
+ void** dataPtr2,
+ PaRingBufferSize* sizePtr2);
+
+/** Advance the read index to the next location to be read.
+
+ @param rbuf The ring buffer.
+
+ @param elementCount The number of elements to advance.
+
+ @return The new position.
+*/
+PaRingBufferSize PaUtil_AdvanceRingBufferReadIndex(
+ PaUtilRingBuffer* rbuf,
+ PaRingBufferSize elementCount);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* MODULES_THIRD_PARTY_PORTAUDIO_PA_RINGBUFFER_H_ */
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 982d5c4..2ef79fa 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -15,18 +15,6 @@
import("//build/config/android/rules.gni")
}
-group("base") {
- public_deps = [
- ":rtc_base",
- ":rtc_base_approved",
- ":rtc_task_queue",
- ":weak_ptr",
- ]
- if (is_android) {
- public_deps += [ ":base_java" ]
- }
-}
-
config("rtc_base_chromium_config") {
defines = [ "NO_MAIN_THREAD_WRAPPING" ]
}
@@ -66,7 +54,8 @@
"protobuf_utils.h",
]
if (rtc_enable_protobuf) {
- public_deps = [
+ public_configs = [ "//third_party/protobuf:protobuf_config" ]
+ deps = [
"//third_party/protobuf:protobuf_lite",
]
}
@@ -102,6 +91,8 @@
}
rtc_source_set("macromagic") {
+ # TODO(bugs.webrtc.org/9606): This should not be public.
+ visibility = [ "*" ]
sources = [
"arraysize.h",
"constructormagic.h",
@@ -109,6 +100,9 @@
"stringize_macros.h",
"thread_annotations.h",
]
+ deps = [
+ "system:arch",
+ ]
}
rtc_source_set("platform_thread_types") {
@@ -119,16 +113,14 @@
}
rtc_source_set("ptr_util") {
+ visibility = [ "*" ]
sources = [
- "ptr_util.h",
"scoped_ref_ptr.h",
]
- deps = [
- "//third_party/abseil-cpp/absl/memory",
- ]
}
rtc_source_set("refcount") {
+ visibility = [ "*" ]
sources = [
"refcount.h",
"refcountedobject.h",
@@ -150,7 +142,7 @@
":checks",
":macromagic",
":platform_thread_types",
- "..:typedefs",
+ "system:unused",
]
}
@@ -174,7 +166,6 @@
":rtc_event",
":thread_checker",
":timeutils",
- "..:typedefs",
]
}
@@ -200,6 +191,7 @@
}
rtc_source_set("logging") {
+ visibility = [ "*" ]
deps = [
":criticalsection",
":macromagic",
@@ -239,7 +231,6 @@
":criticalsection",
":macromagic",
":platform_thread_types",
- "..:typedefs",
]
}
@@ -250,13 +241,14 @@
}
rtc_source_set("checks") {
+ # TODO(bugs.webrtc.org/9607): This should not be public.
+ visibility = [ "*" ]
sources = [
"checks.cc",
"checks.h",
]
deps = [
":safe_compare",
- "..:typedefs",
"system:inline",
]
}
@@ -309,6 +301,7 @@
}
rtc_source_set("timeutils") {
+ visibility = [ "*" ]
sources = [
"timeutils.cc",
"timeutils.h",
@@ -321,6 +314,8 @@
rtc_source_set("stringutils") {
sources = [
+ "string_to_number.cc",
+ "string_to_number.h",
"stringencode.cc",
"stringencode.h",
"strings/string_builder.cc",
@@ -330,8 +325,10 @@
]
deps = [
":checks",
+ ":macromagic",
":safe_minmax",
"../api:array_view",
+ "//third_party/abseil-cpp/absl/types:optional",
]
}
@@ -371,7 +368,6 @@
data_deps = []
deps = [
":atomicops",
- ":base64",
":checks",
":criticalsection",
":logging",
@@ -388,8 +384,9 @@
":thread_checker",
":timeutils",
":type_traits",
- "../:typedefs",
"system:arch",
+ "system:unused",
+ "third_party/base64",
]
sources = [
@@ -416,6 +413,7 @@
"ignore_wundef.h",
"location.cc",
"location.h",
+ "message_buffer_reader.h",
"numerics/histogram_percentile_counter.cc",
"numerics/histogram_percentile_counter.h",
"numerics/mod_ops.h",
@@ -435,8 +433,6 @@
"rate_statistics.h",
"ratetracker.cc",
"ratetracker.h",
- "string_to_number.cc",
- "string_to_number.h",
"swap_queue.h",
"template_util.h",
"timestampaligner.cc",
@@ -449,6 +445,7 @@
deps += [
"..:webrtc_common",
"../api:array_view",
+ "//third_party/abseil-cpp/absl/memory:memory",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -492,14 +489,6 @@
}
}
-rtc_source_set("base64") {
- visibility = [ "*" ]
- sources = [
- "base64.cc",
- "base64.h",
- ]
-}
-
rtc_source_set("rtc_task_queue") {
visibility = [ "*" ]
deps = []
@@ -555,6 +544,7 @@
":rtc_task_queue_api",
":safe_conversions",
":timeutils",
+ "system:unused",
]
if (rtc_build_libevent) {
deps += [ "//base/third_party/libevent" ]
@@ -723,11 +713,12 @@
libs = []
defines = []
deps = [
- ":base64",
":checks",
":stringutils",
"..:webrtc_common",
"../api:array_view",
+ "third_party/base64",
+ "third_party/sigslot",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -815,8 +806,6 @@
"rtccertificategenerator.h",
"signalthread.cc",
"signalthread.h",
- "sigslot.cc",
- "sigslot.h",
"sigslotrepeater.h",
"socket.cc",
"socket.h",
@@ -885,10 +874,6 @@
configs += [ ":external_ssl_library" ]
}
- if (rtc_builtin_ssl_root_certificates) {
- defines += [ "WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES" ]
- }
-
if (is_android) {
sources += [
"ifaddrs-android.cc",
@@ -976,10 +961,6 @@
]
}
-config("rtc_base_tests_utils_exported_config") {
- defines = [ "GTEST_RELATIVE_PATH" ]
-}
-
rtc_source_set("rtc_base_tests_utils") {
testonly = true
sources = [
@@ -1023,7 +1004,6 @@
"virtualsocketserver.cc",
"virtualsocketserver.h",
]
- public_configs = [ ":rtc_base_tests_utils_exported_config" ]
deps = [
":checks",
":rtc_base",
@@ -1032,6 +1012,7 @@
"../test:field_trial",
"../test:test_support",
"system:fallthrough",
+ "third_party/sigslot",
"//third_party/abseil-cpp/absl/memory",
]
public_deps = [
@@ -1055,12 +1036,23 @@
}
if (rtc_include_tests) {
+ rtc_source_set("sigslot_unittest") {
+ testonly = true
+ sources = [
+ "sigslot_unittest.cc",
+ ]
+ deps = [
+ ":rtc_base",
+ ":rtc_base_tests_utils",
+ "third_party/sigslot",
+ ]
+ }
+
rtc_source_set("rtc_base_tests_main") {
testonly = true
sources = [
"unittest_main.cc",
]
- public_configs = [ ":rtc_base_tests_utils_exported_config" ]
deps = [
":rtc_base",
":rtc_base_approved",
@@ -1160,7 +1152,6 @@
sources += [ "win/windows_version_unittest.cc" ]
}
deps = [
- ":base64",
":checks",
":rate_limiter",
":rtc_base",
@@ -1177,6 +1168,7 @@
"../test:fileutils",
"../test:test_support",
"memory:unittests",
+ "third_party/base64",
"//third_party/abseil-cpp/absl/memory",
]
}
@@ -1268,12 +1260,10 @@
"network_unittest.cc",
"optionsfile_unittest.cc",
"proxy_unittest.cc",
- "ptr_util_unittest.cc",
"rollingaccumulator_unittest.cc",
"rtccertificate_unittest.cc",
"rtccertificategenerator_unittest.cc",
"signalthread_unittest.cc",
- "sigslot_unittest.cc",
"sigslottester_unittest.cc",
"stream_unittest.cc",
"testclient_unittest.cc",
@@ -1303,6 +1293,7 @@
"../api:array_view",
"../test:fileutils",
"../test:test_support",
+ "third_party/sigslot",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -1317,9 +1308,6 @@
} else {
configs += [ ":external_ssl_library" ]
}
- if (rtc_builtin_ssl_root_certificates) {
- defines += [ "WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES" ]
- }
}
}
diff --git a/rtc_base/OWNERS b/rtc_base/OWNERS
index 6355075..69ce253 100644
--- a/rtc_base/OWNERS
+++ b/rtc_base/OWNERS
@@ -4,7 +4,9 @@
mflodman@webrtc.org
perkj@webrtc.org
pthatcher@webrtc.org
+qingsi@webrtc.org
sergeyu@chromium.org
+steveanton@webrtc.org
tommi@webrtc.org
# These are for the common case of adding or renaming files. If you're doing
diff --git a/rtc_base/asyncinvoker-inl.h b/rtc_base/asyncinvoker-inl.h
index 3ae2430..0dadc0f 100644
--- a/rtc_base/asyncinvoker-inl.h
+++ b/rtc_base/asyncinvoker-inl.h
@@ -17,7 +17,7 @@
#include "rtc_base/messagehandler.h"
#include "rtc_base/refcountedobject.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
diff --git a/rtc_base/asyncinvoker.h b/rtc_base/asyncinvoker.h
index 74e8689..474ec7c 100644
--- a/rtc_base/asyncinvoker.h
+++ b/rtc_base/asyncinvoker.h
@@ -21,7 +21,7 @@
#include "rtc_base/event.h"
#include "rtc_base/refcountedobject.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
namespace rtc {
diff --git a/rtc_base/asyncpacketsocket.h b/rtc_base/asyncpacketsocket.h
index 820fe94..bb0b3bc 100644
--- a/rtc_base/asyncpacketsocket.h
+++ b/rtc_base/asyncpacketsocket.h
@@ -13,8 +13,8 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/dscp.h"
-#include "rtc_base/sigslot.h"
#include "rtc_base/socket.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/timeutils.h"
namespace rtc {
diff --git a/rtc_base/asyncresolverinterface.h b/rtc_base/asyncresolverinterface.h
index 96b5ec1..5b2303f 100644
--- a/rtc_base/asyncresolverinterface.h
+++ b/rtc_base/asyncresolverinterface.h
@@ -11,8 +11,8 @@
#ifndef RTC_BASE_ASYNCRESOLVERINTERFACE_H_
#define RTC_BASE_ASYNCRESOLVERINTERFACE_H_
-#include "rtc_base/sigslot.h"
#include "rtc_base/socketaddress.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
diff --git a/rtc_base/asyncsocket.h b/rtc_base/asyncsocket.h
index bf9c282..0abdc27 100644
--- a/rtc_base/asyncsocket.h
+++ b/rtc_base/asyncsocket.h
@@ -11,8 +11,8 @@
#ifndef RTC_BASE_ASYNCSOCKET_H_
#define RTC_BASE_ASYNCSOCKET_H_
-#include "rtc_base/sigslot.h"
#include "rtc_base/socket.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
diff --git a/rtc_base/base64_unittest.cc b/rtc_base/base64_unittest.cc
index f73b396..4b857f1 100644
--- a/rtc_base/base64_unittest.cc
+++ b/rtc_base/base64_unittest.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "rtc_base/base64.h"
+#include "rtc_base/third_party/base64/base64.h"
#include "rtc_base/gunit.h"
#include "rtc_base/logging.h"
#include "rtc_base/stringutils.h"
diff --git a/rtc_base/buffer.h b/rtc_base/buffer.h
index 64974d3..22f8937 100644
--- a/rtc_base/buffer.h
+++ b/rtc_base/buffer.h
@@ -87,7 +87,7 @@
BufferT(size_t size, size_t capacity)
: size_(size),
capacity_(std::max(size, capacity)),
- data_(new T[capacity_]) {
+ data_(capacity_ > 0 ? new T[capacity_] : nullptr) {
RTC_DCHECK(IsConsistent());
}
diff --git a/rtc_base/bytebuffer.h b/rtc_base/bytebuffer.h
index 9036bcd..9e08f02 100644
--- a/rtc_base/bytebuffer.h
+++ b/rtc_base/bytebuffer.h
@@ -185,7 +185,7 @@
// after this call.
bool Consume(size_t size);
- private:
+ protected:
void Construct(const char* bytes, size_t size);
const char* bytes_;
@@ -193,6 +193,7 @@
size_t start_;
size_t end_;
+ private:
RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
};
diff --git a/rtc_base/copyonwritebuffer.cc b/rtc_base/copyonwritebuffer.cc
index 8874ea9..6c48d52 100644
--- a/rtc_base/copyonwritebuffer.cc
+++ b/rtc_base/copyonwritebuffer.cc
@@ -22,6 +22,9 @@
CopyOnWriteBuffer::CopyOnWriteBuffer(CopyOnWriteBuffer&& buf)
: buffer_(std::move(buf.buffer_)) {}
+CopyOnWriteBuffer::CopyOnWriteBuffer(const std::string& s)
+ : CopyOnWriteBuffer(s.data(), s.length()) {}
+
CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size)
: buffer_(size > 0 ? new RefCountedObject<Buffer>(size) : nullptr) {
RTC_DCHECK(IsConsistent());
diff --git a/rtc_base/copyonwritebuffer.h b/rtc_base/copyonwritebuffer.h
index 467baad..0514e2f 100644
--- a/rtc_base/copyonwritebuffer.h
+++ b/rtc_base/copyonwritebuffer.h
@@ -31,6 +31,9 @@
// Move contents from an existing buffer.
CopyOnWriteBuffer(CopyOnWriteBuffer&& buf);
+ // Construct a buffer from a string, convenient for unittests.
+ CopyOnWriteBuffer(const std::string& s);
+
// Construct a buffer with the specified number of uninitialized bytes.
explicit CopyOnWriteBuffer(size_t size);
CopyOnWriteBuffer(size_t size, size_t capacity);
diff --git a/rtc_base/criticalsection.cc b/rtc_base/criticalsection.cc
index c786a40..d8a5b48 100644
--- a/rtc_base/criticalsection.cc
+++ b/rtc_base/criticalsection.cc
@@ -13,6 +13,7 @@
#include "rtc_base/atomicops.h"
#include "rtc_base/checks.h"
#include "rtc_base/platform_thread_types.h"
+#include "rtc_base/system/unused.h"
// TODO(tommi): Split this file up to per-platform implementation files.
diff --git a/rtc_base/criticalsection.h b/rtc_base/criticalsection.h
index ce6fca1..f25e7d0 100644
--- a/rtc_base/criticalsection.h
+++ b/rtc_base/criticalsection.h
@@ -15,7 +15,6 @@
#include "rtc_base/constructormagic.h"
#include "rtc_base/platform_thread_types.h"
#include "rtc_base/thread_annotations.h"
-#include "typedefs.h" // NOLINT(build/include)
#if defined(WEBRTC_WIN)
// clang-format off
diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn
index a95e258..c0e1049 100644
--- a/rtc_base/experiments/BUILD.gn
+++ b/rtc_base/experiments/BUILD.gn
@@ -63,6 +63,17 @@
]
}
+rtc_static_library("rtt_mult_experiment") {
+ sources = [
+ "rtt_mult_experiment.cc",
+ "rtt_mult_experiment.h",
+ ]
+ deps = [
+ "../:rtc_base_approved",
+ "../../system_wrappers:field_trial_api",
+ ]
+}
+
if (rtc_include_tests) {
rtc_source_set("experiments_unittests") {
testonly = true
@@ -72,11 +83,13 @@
"field_trial_parser_unittest.cc",
"field_trial_units_unittest.cc",
"quality_scaling_experiment_unittest.cc",
+ "rtt_mult_experiment_unittest.cc",
]
deps = [
":congestion_controller_experiment",
":field_trial_parser",
":quality_scaling_experiment",
+ ":rtt_mult_experiment",
"../:rtc_base_tests_main",
"../:rtc_base_tests_utils",
"../../system_wrappers:field_trial_api",
diff --git a/rtc_base/experiments/rtt_mult_experiment.cc b/rtc_base/experiments/rtt_mult_experiment.cc
new file mode 100644
index 0000000..f8f7f2a
--- /dev/null
+++ b/rtc_base/experiments/rtt_mult_experiment.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 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 "rtc_base/experiments/rtt_mult_experiment.h"
+
+#include <algorithm>
+#include <string>
+
+#include "rtc_base/logging.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+
+namespace {
+const char kRttMultExperiment[] = "WebRTC-RttMult";
+const float max_rtt_mult_setting = 1.0;
+const float min_rtt_mult_setting = 0.0;
+} // namespace
+
+bool RttMultExperiment::RttMultEnabled() {
+ return field_trial::IsEnabled(kRttMultExperiment);
+}
+
+float RttMultExperiment::GetRttMultValue() {
+ const std::string group =
+ webrtc::field_trial::FindFullName(kRttMultExperiment);
+ if (group.empty()) {
+ RTC_LOG(LS_WARNING) << "Could not find rtt_mult_experiment.";
+ return 0.0;
+ }
+
+ float rtt_mult_setting;
+ if (sscanf(group.c_str(), "Enabled-%f", &rtt_mult_setting) != 1) {
+ RTC_LOG(LS_WARNING) << "Invalid number of parameters provided.";
+ return 0.0;
+ }
+ // Bounds check rtt_mult_setting value.
+ rtt_mult_setting = std::min(rtt_mult_setting, max_rtt_mult_setting);
+ rtt_mult_setting = std::max(rtt_mult_setting, min_rtt_mult_setting);
+ return rtt_mult_setting;
+}
+
+} // namespace webrtc
diff --git a/rtc_base/experiments/rtt_mult_experiment.h b/rtc_base/experiments/rtt_mult_experiment.h
new file mode 100644
index 0000000..d431af6
--- /dev/null
+++ b/rtc_base/experiments/rtt_mult_experiment.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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 RTC_BASE_EXPERIMENTS_RTT_MULT_EXPERIMENT_H_
+#define RTC_BASE_EXPERIMENTS_RTT_MULT_EXPERIMENT_H_
+
+namespace webrtc {
+
+class RttMultExperiment {
+ public:
+ // Returns true if the experiment is enabled.
+ static bool RttMultEnabled();
+
+ // Returns rtt_mult value from field trial.
+ static float GetRttMultValue();
+};
+
+} // namespace webrtc
+
+#endif // RTC_BASE_EXPERIMENTS_RTT_MULT_EXPERIMENT_H_
diff --git a/rtc_base/experiments/rtt_mult_experiment_unittest.cc b/rtc_base/experiments/rtt_mult_experiment_unittest.cc
new file mode 100644
index 0000000..0cd86d1
--- /dev/null
+++ b/rtc_base/experiments/rtt_mult_experiment_unittest.cc
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2018 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 "rtc_base/experiments/rtt_mult_experiment.h"
+#include "rtc_base/gunit.h"
+#include "test/field_trial.h"
+
+namespace webrtc {
+
+TEST(RttMultExperimentTest, RttMultDisabledByDefault) {
+ EXPECT_FALSE(RttMultExperiment::RttMultEnabled());
+}
+
+TEST(RttMultExperimentTest, RttMultEnabledByFieldTrial) {
+ webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-0.25/");
+ EXPECT_TRUE(RttMultExperiment::RttMultEnabled());
+}
+
+TEST(RttMultExperimentTest, RttMultTestValue) {
+ webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-0.25/");
+ EXPECT_EQ(0.25, RttMultExperiment::GetRttMultValue());
+}
+
+TEST(RttMultExperimentTest, RttMultTestMalformedEnabled) {
+ webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enable-0.25/");
+ EXPECT_FALSE(RttMultExperiment::RttMultEnabled());
+}
+
+TEST(RttMultExperimentTest, RttMultTestValueOutOfBoundsPositive) {
+ webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-1.5/");
+ EXPECT_EQ(1.0, RttMultExperiment::GetRttMultValue());
+}
+
+TEST(RttMultExperimentTest, RttMultTestValueOutOfBoundsNegative) {
+ webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled--0.5/");
+ EXPECT_EQ(0.0, RttMultExperiment::GetRttMultValue());
+}
+
+TEST(RttMultExperimentTest, RttMultTestMalformedValue) {
+ webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-0.2a5/");
+ EXPECT_NE(0.25, RttMultExperiment::GetRttMultValue());
+}
+
+} // namespace webrtc
diff --git a/rtc_base/format_macros.h b/rtc_base/format_macros.h
index 48127e1..7252f2e 100644
--- a/rtc_base/format_macros.h
+++ b/rtc_base/format_macros.h
@@ -37,6 +37,8 @@
#include <inttypes.h>
+#include "rtc_base/system/arch.h"
+
#if !defined(PRIuS)
#define PRIuS "zu"
#endif
diff --git a/rtc_base/gunit.h b/rtc_base/gunit.h
index 145b466..910fbf3 100644
--- a/rtc_base/gunit.h
+++ b/rtc_base/gunit.h
@@ -14,11 +14,7 @@
#include "rtc_base/fakeclock.h"
#include "rtc_base/logging.h"
#include "rtc_base/thread.h"
-#if defined(GTEST_RELATIVE_PATH)
#include "test/gtest.h"
-#else
-#include "testing/base/public/gunit.h"
-#endif
// Wait until "ex" is true, or "timeout" expires.
#define WAIT(ex, timeout) \
diff --git a/rtc_base/gunit_prod.h b/rtc_base/gunit_prod.h
index bf4f9a1..dae2084 100644
--- a/rtc_base/gunit_prod.h
+++ b/rtc_base/gunit_prod.h
@@ -15,10 +15,8 @@
// Android doesn't use gtest at all, so anything that relies on gtest should
// check this define first.
#define NO_GTEST
-#elif defined(GTEST_RELATIVE_PATH)
-#include "gtest/gtest_prod.h"
#else
-#include "testing/base/gunit_prod.h"
+#include "gtest/gtest_prod.h"
#endif
#endif // RTC_BASE_GUNIT_PROD_H_
diff --git a/rtc_base/helpers.cc b/rtc_base/helpers.cc
index 0260665..b9372b9 100644
--- a/rtc_base/helpers.cc
+++ b/rtc_base/helpers.cc
@@ -15,9 +15,9 @@
#include <openssl/rand.h>
-#include "rtc_base/base64.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
+#include "rtc_base/third_party/base64/base64.h"
#include "rtc_base/timeutils.h"
// Protect against max macro inclusion.
diff --git a/rtc_base/httpbase.cc b/rtc_base/httpbase.cc
index 3e2f376..8f2869d 100644
--- a/rtc_base/httpbase.cc
+++ b/rtc_base/httpbase.cc
@@ -224,149 +224,11 @@
}
//////////////////////////////////////////////////////////////////////
-// HttpBase::DocumentStream
-//////////////////////////////////////////////////////////////////////
-
-class BlockingMemoryStream : public ExternalMemoryStream {
- public:
- BlockingMemoryStream(char* buffer, size_t size)
- : ExternalMemoryStream(buffer, size) {}
-
- StreamResult DoReserve(size_t size, int* error) override {
- return (buffer_length_ >= size) ? SR_SUCCESS : SR_BLOCK;
- }
-};
-
-class HttpBase::DocumentStream : public StreamInterface {
- public:
- DocumentStream(HttpBase* base) : base_(base), error_(HE_DEFAULT) {}
-
- StreamState GetState() const override {
- if (nullptr == base_)
- return SS_CLOSED;
- if (HM_RECV == base_->mode_)
- return SS_OPEN;
- return SS_OPENING;
- }
-
- StreamResult Read(void* buffer,
- size_t buffer_len,
- size_t* read,
- int* error) override {
- if (!base_) {
- if (error)
- *error = error_;
- return (HE_NONE == error_) ? SR_EOS : SR_ERROR;
- }
-
- if (HM_RECV != base_->mode_) {
- return SR_BLOCK;
- }
-
- // DoReceiveLoop writes http document data to the StreamInterface* document
- // member of HttpData. In this case, we want this data to be written
- // directly to our buffer. To accomplish this, we wrap our buffer with a
- // StreamInterface, and replace the existing document with our wrapper.
- // When the method returns, we restore the old document. Ideally, we would
- // pass our StreamInterface* to DoReceiveLoop, but due to the callbacks
- // of HttpParser, we would still need to store the pointer temporarily.
- std::unique_ptr<StreamInterface> stream(
- new BlockingMemoryStream(reinterpret_cast<char*>(buffer), buffer_len));
-
- // Replace the existing document with our wrapped buffer.
- base_->data_->document.swap(stream);
-
- // Pump the I/O loop. DoReceiveLoop is guaranteed not to attempt to
- // complete the I/O process, which means that our wrapper is not in danger
- // of being deleted. To ensure this, DoReceiveLoop returns true when it
- // wants complete to be called. We make sure to uninstall our wrapper
- // before calling complete().
- HttpError http_error;
- bool complete = base_->DoReceiveLoop(&http_error);
-
- // Reinstall the original output document.
- base_->data_->document.swap(stream);
-
- // If we reach the end of the receive stream, we disconnect our stream
- // adapter from the HttpBase, and further calls to read will either return
- // EOS or ERROR, appropriately. Finally, we call complete().
- StreamResult result = SR_BLOCK;
- if (complete) {
- HttpBase* base = Disconnect(http_error);
- if (error)
- *error = error_;
- result = (HE_NONE == error_) ? SR_EOS : SR_ERROR;
- base->complete(http_error);
- }
-
- // Even if we are complete, if some data was read we must return SUCCESS.
- // Future Reads will return EOS or ERROR based on the error_ variable.
- size_t position;
- stream->GetPosition(&position);
- if (position > 0) {
- if (read)
- *read = position;
- result = SR_SUCCESS;
- }
- return result;
- }
-
- StreamResult Write(const void* data,
- size_t data_len,
- size_t* written,
- int* error) override {
- if (error)
- *error = -1;
- return SR_ERROR;
- }
-
- void Close() override {
- if (base_) {
- HttpBase* base = Disconnect(HE_NONE);
- if (HM_RECV == base->mode_ && base->http_stream_) {
- // Read I/O could have been stalled on the user of this DocumentStream,
- // so restart the I/O process now that we've removed ourselves.
- base->http_stream_->PostEvent(SE_READ, 0);
- }
- }
- }
-
- bool GetAvailable(size_t* size) const override {
- if (!base_ || HM_RECV != base_->mode_)
- return false;
- size_t data_size = base_->GetDataRemaining();
- if (SIZE_UNKNOWN == data_size)
- return false;
- if (size)
- *size = data_size;
- return true;
- }
-
- HttpBase* Disconnect(HttpError error) {
- RTC_DCHECK(nullptr != base_);
- RTC_DCHECK(nullptr != base_->doc_stream_);
- HttpBase* base = base_;
- base_->doc_stream_ = nullptr;
- base_ = nullptr;
- error_ = error;
- return base;
- }
-
- private:
- HttpBase* base_;
- HttpError error_;
-};
-
-//////////////////////////////////////////////////////////////////////
// HttpBase
//////////////////////////////////////////////////////////////////////
HttpBase::HttpBase()
- : mode_(HM_NONE),
- data_(nullptr),
- notify_(nullptr),
- http_stream_(nullptr),
- doc_stream_(nullptr) {}
+ : mode_(HM_NONE), data_(nullptr), notify_(nullptr), http_stream_(nullptr) {}
HttpBase::~HttpBase() {
RTC_DCHECK(HM_NONE == mode_);
@@ -451,11 +313,7 @@
ignore_data_ = chunk_data_ = false;
reset();
- if (doc_stream_) {
- doc_stream_->SignalEvent(doc_stream_, SE_OPEN | SE_READ, 0);
- } else {
- read_and_process_data();
- }
+ read_and_process_data();
}
void HttpBase::abort(HttpError err) {
@@ -467,13 +325,6 @@
}
}
-StreamInterface* HttpBase::GetDocumentStream() {
- if (doc_stream_)
- return nullptr;
- doc_stream_ = new DocumentStream(this);
- return doc_stream_;
-}
-
HttpError HttpBase::HandleStreamClose(int error) {
if (http_stream_ != nullptr) {
http_stream_->Close();
@@ -730,13 +581,6 @@
data_->document->SignalEvent.disconnect(this);
}
data_ = nullptr;
- if ((HM_RECV == mode) && doc_stream_) {
- RTC_DCHECK(HE_NONE !=
- err); // We should have Disconnected doc_stream_ already.
- DocumentStream* ds = doc_stream_;
- ds->Disconnect(err);
- ds->SignalEvent(ds, SE_CLOSE, err);
- }
if (notify_) {
notify_->onHttpComplete(mode, err);
}
@@ -761,11 +605,7 @@
}
if ((events & SE_READ) && (mode_ == HM_RECV)) {
- if (doc_stream_) {
- doc_stream_->SignalEvent(doc_stream_, SE_READ, 0);
- } else {
- read_and_process_data();
- }
+ read_and_process_data();
return;
}
@@ -825,7 +665,6 @@
HttpParser::ProcessResult HttpBase::ProcessHeaderComplete(bool chunked,
size_t& data_size,
HttpError* error) {
- StreamInterface* old_docstream = doc_stream_;
if (notify_) {
*error = notify_->onHttpHeaderComplete(chunked, data_size);
// The request must not be aborted as a result of this callback.
@@ -837,10 +676,6 @@
if (HE_NONE != *error) {
return PR_COMPLETE;
}
- if (old_docstream != doc_stream_) {
- // Break out of Process loop, since our I/O model just changed.
- return PR_BLOCK;
- }
return PR_CONTINUE;
}
diff --git a/rtc_base/httpbase.h b/rtc_base/httpbase.h
index 25a11ab..b0e2425 100644
--- a/rtc_base/httpbase.h
+++ b/rtc_base/httpbase.h
@@ -119,11 +119,6 @@
void set_ignore_data(bool ignore) { ignore_data_ = ignore; }
bool ignore_data() const { return ignore_data_; }
- // Obtaining this stream puts HttpBase into stream mode until the stream
- // is closed. HttpBase can only expose one open stream interface at a time.
- // Further calls will return null.
- StreamInterface* GetDocumentStream();
-
protected:
// Do cleanup when the http stream closes (error may be 0 for a clean
// shutdown), and return the error code to signal.
@@ -180,7 +175,6 @@
HttpData* data_;
IHttpNotify* notify_;
StreamInterface* http_stream_;
- DocumentStream* doc_stream_;
char buffer_[kBufferSize];
size_t len_;
diff --git a/rtc_base/httpbase_unittest.cc b/rtc_base/httpbase_unittest.cc
index 260fb9b..35321da 100644
--- a/rtc_base/httpbase_unittest.cc
+++ b/rtc_base/httpbase_unittest.cc
@@ -34,16 +34,6 @@
"Proxy-Authorization: 42\r\n"
"\r\n";
-const char* const kHttpResponsePrefix =
- "HTTP/1.1 200\r\n"
- "Connection: Keep-Alive\r\n"
- "Content-Type: text/plain\r\n"
- "Proxy-Authorization: 42\r\n"
- "Transfer-Encoding: chunked\r\n"
- "\r\n"
- "8\r\n"
- "Goodbye!\r\n";
-
class HttpBaseTest : public testing::Test, public IHttpNotify {
public:
enum EventType { E_HEADER_COMPLETE, E_COMPLETE, E_CLOSED };
@@ -54,7 +44,7 @@
HttpMode mode;
HttpError err;
};
- HttpBaseTest() : mem(nullptr), obtain_stream(false), http_stream(nullptr) {}
+ HttpBaseTest() : mem(nullptr), http_stream(nullptr) {}
void TearDown() override {
delete http_stream;
@@ -66,9 +56,6 @@
RTC_LOG_F(LS_VERBOSE) << "chunked: " << chunked << " size: " << data_size;
Event e = {E_HEADER_COMPLETE, chunked, data_size, HM_NONE, HE_NONE};
events.push_back(e);
- if (obtain_stream) {
- ObtainDocumentStream();
- }
return HE_NONE;
}
void onHttpComplete(HttpMode mode, HttpError err) override {
@@ -88,7 +75,6 @@
void VerifyDocumentContents(const char* expected_data,
size_t expected_length = SIZE_UNKNOWN);
- void ObtainDocumentStream();
void VerifyDocumentStreamIsOpening();
void VerifyDocumentStreamOpenEvent();
void ReadDocumentStreamData(const char* expected_data);
@@ -108,8 +94,7 @@
webrtc::testing::StreamSource src;
std::vector<Event> events;
- // Document stream, and stream events
- bool obtain_stream;
+ // Stream events
StreamInterface* http_stream;
webrtc::testing::StreamSink sink;
};
@@ -184,15 +169,6 @@
RTC_LOG_F(LS_VERBOSE) << "Exit";
}
-void HttpBaseTest::ObtainDocumentStream() {
- RTC_LOG_F(LS_VERBOSE) << "Enter";
- EXPECT_FALSE(http_stream);
- http_stream = base.GetDocumentStream();
- ASSERT_TRUE(nullptr != http_stream);
- sink.Monitor(http_stream);
- RTC_LOG_F(LS_VERBOSE) << "Exit";
-}
-
void HttpBaseTest::VerifyDocumentStreamIsOpening() {
RTC_LOG_F(LS_VERBOSE) << "Enter";
ASSERT_TRUE(nullptr != http_stream);
@@ -379,145 +355,4 @@
VerifyDocumentContents("Goodbye!");
}
-TEST_F(HttpBaseTest, SupportsReceiveViaStreamPull) {
- // Switch to pull mode
- ObtainDocumentStream();
- VerifyDocumentStreamIsOpening();
-
- // Queue response document
- SetupSource(kHttpResponse);
- VerifyDocumentStreamIsOpening();
-
- // Begin receive
- base.recv(&data);
-
- // Pull document data
- VerifyDocumentStreamOpenEvent();
- ReadDocumentStreamData("Goodbye!");
- VerifyDocumentStreamIsEOS();
-
- // Document completed successfully
- VerifyHeaderComplete(2, false);
- VerifyTransferComplete(HM_RECV, HE_NONE);
- VerifyDocumentContents("");
-}
-
-TEST_F(HttpBaseTest, DISABLED_AllowsCloseStreamBeforeDocumentIsComplete) {
- // TODO: Remove extra logging once test failure is understood
- LoggingSeverity old_sev = rtc::LogMessage::GetLogToDebug();
- rtc::LogMessage::LogToDebug(LS_VERBOSE);
-
- // Switch to pull mode
- ObtainDocumentStream();
- VerifyDocumentStreamIsOpening();
-
- // Queue response document
- SetupSource(kHttpResponse);
- VerifyDocumentStreamIsOpening();
-
- // Begin receive
- base.recv(&data);
-
- // Pull some of the data
- VerifyDocumentStreamOpenEvent();
- ReadDocumentStreamData("Goodb");
-
- // We've seen the header by now
- VerifyHeaderComplete(1, false);
-
- // Close the pull stream, this will transition back to push I/O.
- http_stream->Close();
- Thread::Current()->ProcessMessages(0);
-
- // Remainder of document completed successfully
- VerifyTransferComplete(HM_RECV, HE_NONE);
- VerifyDocumentContents("ye!");
-
- rtc::LogMessage::LogToDebug(old_sev);
-}
-
-TEST_F(HttpBaseTest, AllowsGetDocumentStreamInResponseToHttpHeader) {
- // Queue response document
- SetupSource(kHttpResponse);
-
- // Switch to pull mode in response to header arrival
- obtain_stream = true;
-
- // Begin receive
- base.recv(&data);
-
- // We've already seen the header, but not data has arrived
- VerifyHeaderComplete(1, false);
- VerifyDocumentContents("");
-
- // Pull the document data
- ReadDocumentStreamData("Goodbye!");
- VerifyDocumentStreamIsEOS();
-
- // Document completed successfully
- VerifyTransferComplete(HM_RECV, HE_NONE);
- VerifyDocumentContents("");
-}
-
-TEST_F(HttpBaseTest, AllowsGetDocumentStreamWithEmptyDocumentBody) {
- // Queue empty response document
- SetupSource(kHttpEmptyResponse);
-
- // Switch to pull mode in response to header arrival
- obtain_stream = true;
-
- // Begin receive
- base.recv(&data);
-
- // We've already seen the header, but not data has arrived
- VerifyHeaderComplete(1, true);
- VerifyDocumentContents("");
-
- // The document is still open, until we attempt to read
- ASSERT_TRUE(nullptr != http_stream);
- EXPECT_EQ(SS_OPEN, http_stream->GetState());
-
- // Attempt to read data, and discover EOS
- VerifyDocumentStreamIsEOS();
-
- // Document completed successfully
- VerifyTransferComplete(HM_RECV, HE_NONE);
- VerifyDocumentContents("");
-}
-
-TEST_F(HttpBaseTest, SignalsDocumentStreamCloseOnUnexpectedClose) {
- // Switch to pull mode
- ObtainDocumentStream();
- VerifyDocumentStreamIsOpening();
-
- // Queue response document
- SetupSource(kHttpResponsePrefix);
- VerifyDocumentStreamIsOpening();
-
- // Begin receive
- base.recv(&data);
-
- // Pull document data
- VerifyDocumentStreamOpenEvent();
- ReadDocumentStreamData("Goodbye!");
-
- // Simulate unexpected close
- src.SetState(SS_CLOSED);
-
- // Observe error event on document stream
- EXPECT_EQ(webrtc::testing::SSE_ERROR, sink.Events(http_stream));
-
- // Future reads give an error
- int error = 0;
- char buffer[5] = {0};
- EXPECT_EQ(SR_ERROR,
- http_stream->Read(buffer, sizeof(buffer), nullptr, &error));
- EXPECT_EQ(HE_DISCONNECTED, error);
-
- // Document completed with error
- VerifyHeaderComplete(2, false);
- VerifyTransferComplete(HM_RECV, HE_DISCONNECTED);
- VerifyDocumentContents("");
-}
-
} // namespace rtc
diff --git a/rtc_base/httpcommon.cc b/rtc_base/httpcommon.cc
index 5ac1e42..4ecb393 100644
--- a/rtc_base/httpcommon.cc
+++ b/rtc_base/httpcommon.cc
@@ -21,13 +21,13 @@
#include <algorithm>
#include "rtc_base/arraysize.h"
-#include "rtc_base/base64.h"
#include "rtc_base/checks.h"
#include "rtc_base/cryptstring.h"
#include "rtc_base/httpcommon-inl.h"
#include "rtc_base/httpcommon.h"
#include "rtc_base/messagedigest.h"
#include "rtc_base/socketaddress.h"
+#include "rtc_base/third_party/base64/base64.h"
#include "rtc_base/zero_memory.h"
namespace rtc {
@@ -169,10 +169,6 @@
static const char* kHttpVersions[HVER_LAST + 1] = {"1.0", "1.1", "Unknown"};
ENUM(HttpVersion, kHttpVersions);
-static const char* kHttpVerbs[HV_LAST + 1] = {"GET", "POST", "PUT",
- "DELETE", "CONNECT", "HEAD"};
-ENUM(HttpVerb, kHttpVerbs);
-
static const char* kHttpHeaders[HH_LAST + 1] = {
"Age",
"Cache-Control",
@@ -213,14 +209,6 @@
return Enum<HttpVersion>::Parse(version, str);
}
-const char* ToString(HttpVerb verb) {
- return Enum<HttpVerb>::Name(verb);
-}
-
-bool FromString(HttpVerb& verb, const std::string& str) {
- return Enum<HttpVerb>::Parse(verb, str);
-}
-
const char* ToString(HttpHeader header) {
return Enum<HttpHeader>::Name(header);
}
@@ -229,25 +217,6 @@
return Enum<HttpHeader>::Parse(header, str);
}
-bool HttpCodeHasBody(uint32_t code) {
- return !HttpCodeIsInformational(code) && (code != HC_NO_CONTENT) &&
- (code != HC_NOT_MODIFIED);
-}
-
-bool HttpCodeIsCacheable(uint32_t code) {
- switch (code) {
- case HC_OK:
- case HC_NON_AUTHORITATIVE:
- case HC_PARTIAL_CONTENT:
- case HC_MULTIPLE_CHOICES:
- case HC_MOVED_PERMANENTLY:
- case HC_GONE:
- return true;
- default:
- return false;
- }
-}
-
bool HttpHeaderIsEndToEnd(HttpHeader header) {
switch (header) {
case HH_CONNECTION:
@@ -494,10 +463,6 @@
}
}
-void HttpData::copy(const HttpData& src) {
- headers_ = src.headers_;
-}
-
void HttpData::changeHeader(const std::string& name,
const std::string& value,
HeaderCombine combine) {
@@ -572,21 +537,14 @@
//
void HttpRequestData::clear(bool release_document) {
- verb = HV_GET;
path.clear();
HttpData::clear(release_document);
}
-void HttpRequestData::copy(const HttpRequestData& src) {
- verb = src.verb;
- path = src.path;
- HttpData::copy(src);
-}
-
size_t HttpRequestData::formatLeader(char* buffer, size_t size) const {
RTC_DCHECK(path.find(' ') == std::string::npos);
- return sprintfn(buffer, size, "%s %.*s HTTP/%s", ToString(verb), path.size(),
- path.data(), ToString(version));
+ return sprintfn(buffer, size, "GET %.*s HTTP/%s", path.size(), path.data(),
+ ToString(version));
}
HttpError HttpRequestData::parseLeader(const char* line, size_t len) {
@@ -608,8 +566,7 @@
} else {
return HE_PROTOCOL;
}
- std::string sverb(line, vend);
- if (!FromString(verb, sverb.c_str())) {
+ if (vend != 3 || memcmp(line, "GET", 3)) {
return HE_PROTOCOL; // !?! HC_METHOD_NOT_SUPPORTED?
}
path.assign(line + dstart, line + dend);
@@ -617,8 +574,6 @@
}
bool HttpRequestData::getAbsoluteUri(std::string* uri) const {
- if (HV_CONNECT == verb)
- return false;
Url<char> url(path);
if (url.valid()) {
uri->assign(path);
@@ -635,8 +590,6 @@
bool HttpRequestData::getRelativeUri(std::string* host,
std::string* path) const {
- if (HV_CONNECT == verb)
- return false;
Url<char> url(this->path);
if (url.valid()) {
host->assign(url.address());
@@ -659,34 +612,12 @@
HttpData::clear(release_document);
}
-void HttpResponseData::copy(const HttpResponseData& src) {
- scode = src.scode;
- message = src.message;
- HttpData::copy(src);
-}
-
void HttpResponseData::set_success(uint32_t scode) {
this->scode = scode;
message.clear();
setHeader(HH_CONTENT_LENGTH, "0", false);
}
-void HttpResponseData::set_success(const std::string& content_type,
- StreamInterface* document,
- uint32_t scode) {
- this->scode = scode;
- message.erase(message.begin(), message.end());
- setContent(content_type, document);
-}
-
-void HttpResponseData::set_redirect(const std::string& location,
- uint32_t scode) {
- this->scode = scode;
- message.clear();
- setHeader(HH_LOCATION, location);
- setHeader(HH_CONTENT_LENGTH, "0", false);
-}
-
void HttpResponseData::set_error(uint32_t scode) {
this->scode = scode;
message.clear();
diff --git a/rtc_base/httpcommon.h b/rtc_base/httpcommon.h
index 1b8768d..11c01ca 100644
--- a/rtc_base/httpcommon.h
+++ b/rtc_base/httpcommon.h
@@ -31,41 +31,11 @@
enum HttpCode {
HC_OK = 200,
- HC_NON_AUTHORITATIVE = 203,
- HC_NO_CONTENT = 204,
- HC_PARTIAL_CONTENT = 206,
-
- HC_MULTIPLE_CHOICES = 300,
- HC_MOVED_PERMANENTLY = 301,
- HC_FOUND = 302,
- HC_SEE_OTHER = 303,
- HC_NOT_MODIFIED = 304,
- HC_MOVED_TEMPORARILY = 307,
-
- HC_BAD_REQUEST = 400,
- HC_UNAUTHORIZED = 401,
- HC_FORBIDDEN = 403,
- HC_NOT_FOUND = 404,
- HC_PROXY_AUTHENTICATION_REQUIRED = 407,
- HC_GONE = 410,
-
HC_INTERNAL_SERVER_ERROR = 500,
- HC_NOT_IMPLEMENTED = 501,
- HC_SERVICE_UNAVAILABLE = 503,
};
enum HttpVersion { HVER_1_0, HVER_1_1, HVER_UNKNOWN, HVER_LAST = HVER_UNKNOWN };
-enum HttpVerb {
- HV_GET,
- HV_POST,
- HV_PUT,
- HV_DELETE,
- HV_CONNECT,
- HV_HEAD,
- HV_LAST = HV_HEAD
-};
-
enum HttpError {
HE_NONE,
HE_PROTOCOL, // Received non-valid HTTP data
@@ -121,37 +91,12 @@
// Utility Functions
//////////////////////////////////////////////////////////////////////
-inline HttpError mkerr(HttpError err, HttpError def_err = HE_DEFAULT) {
- return (err != HE_NONE) ? err : def_err;
-}
-
const char* ToString(HttpVersion version);
bool FromString(HttpVersion& version, const std::string& str);
-const char* ToString(HttpVerb verb);
-bool FromString(HttpVerb& verb, const std::string& str);
-
const char* ToString(HttpHeader header);
bool FromString(HttpHeader& header, const std::string& str);
-inline bool HttpCodeIsInformational(uint32_t code) {
- return ((code / 100) == 1);
-}
-inline bool HttpCodeIsSuccessful(uint32_t code) {
- return ((code / 100) == 2);
-}
-inline bool HttpCodeIsRedirection(uint32_t code) {
- return ((code / 100) == 3);
-}
-inline bool HttpCodeIsClientError(uint32_t code) {
- return ((code / 100) == 4);
-}
-inline bool HttpCodeIsServerError(uint32_t code) {
- return ((code / 100) == 5);
-}
-
-bool HttpCodeHasBody(uint32_t code);
-bool HttpCodeIsCacheable(uint32_t code);
bool HttpHeaderIsEndToEnd(HttpHeader header);
bool HttpHeaderIsCollapsible(HttpHeader header);
@@ -382,20 +327,17 @@
protected:
virtual ~HttpData();
void clear(bool release_document);
- void copy(const HttpData& src);
private:
HeaderMap headers_;
};
struct HttpRequestData : public HttpData {
- HttpVerb verb;
std::string path;
- HttpRequestData() : verb(HV_GET) {}
+ HttpRequestData() {}
void clear(bool release_document);
- void copy(const HttpRequestData& src);
size_t formatLeader(char* buffer, size_t size) const override;
HttpError parseLeader(const char* line, size_t len) override;
@@ -410,15 +352,9 @@
HttpResponseData() : scode(HC_INTERNAL_SERVER_ERROR) {}
void clear(bool release_document);
- void copy(const HttpResponseData& src);
// Convenience methods
void set_success(uint32_t scode = HC_OK);
- void set_success(const std::string& content_type,
- StreamInterface* document,
- uint32_t scode = HC_OK);
- void set_redirect(const std::string& location,
- uint32_t scode = HC_MOVED_TEMPORARILY);
void set_error(uint32_t scode);
size_t formatLeader(char* buffer, size_t size) const override;
diff --git a/rtc_base/memory/BUILD.gn b/rtc_base/memory/BUILD.gn
index e24b8ce..05fd7ab 100644
--- a/rtc_base/memory/BUILD.gn
+++ b/rtc_base/memory/BUILD.gn
@@ -27,9 +27,7 @@
"aligned_malloc.cc",
"aligned_malloc.h",
]
- deps = [
- "../..:typedefs",
- ]
+ deps = []
}
rtc_source_set("unittests") {
@@ -41,7 +39,6 @@
deps = [
":aligned_array",
":aligned_malloc",
- "../..:typedefs",
"../../test:test_support",
]
}
diff --git a/rtc_base/memory/aligned_malloc.cc b/rtc_base/memory/aligned_malloc.cc
index 4e1e85c..2943a64 100644
--- a/rtc_base/memory/aligned_malloc.cc
+++ b/rtc_base/memory/aligned_malloc.cc
@@ -19,8 +19,6 @@
#include <stdint.h>
#endif
-#include "typedefs.h" // NOLINT(build/include)
-
// Reference on memory alignment:
// http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me
namespace webrtc {
diff --git a/rtc_base/memory/aligned_malloc_unittest.cc b/rtc_base/memory/aligned_malloc_unittest.cc
index 742a772..572af5a 100644
--- a/rtc_base/memory/aligned_malloc_unittest.cc
+++ b/rtc_base/memory/aligned_malloc_unittest.cc
@@ -19,7 +19,6 @@
#endif
#include "test/gtest.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/rtc_base/message_buffer_reader.h b/rtc_base/message_buffer_reader.h
new file mode 100644
index 0000000..baba89e
--- /dev/null
+++ b/rtc_base/message_buffer_reader.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2018 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 RTC_BASE_MESSAGE_BUFFER_READER_H_
+#define RTC_BASE_MESSAGE_BUFFER_READER_H_
+
+#include "rtc_base/bytebuffer.h"
+
+namespace webrtc {
+
+// A simple subclass of the ByteBufferReader that exposes the starting address
+// of the message and its length, so that we can recall previously parsed data.
+class MessageBufferReader : public rtc::ByteBufferReader {
+ public:
+ MessageBufferReader(const char* bytes, size_t len)
+ : rtc::ByteBufferReader(bytes, len) {}
+ ~MessageBufferReader() = default;
+
+ // Starting address of the message.
+ const char* MessageData() const { return bytes_; }
+ // Total length of the message. Note that this is different from Length(),
+ // which is the length of the remaining message from the current offset.
+ size_t MessageLength() const { return size_; }
+ // Current offset in the message.
+ size_t CurrentOffset() const { return start_; }
+};
+
+} // namespace webrtc
+
+#endif // RTC_BASE_MESSAGE_BUFFER_READER_H_
diff --git a/rtc_base/messagequeue.h b/rtc_base/messagequeue.h
index c156d15..fe64c9c 100644
--- a/rtc_base/messagequeue.h
+++ b/rtc_base/messagequeue.h
@@ -25,8 +25,8 @@
#include "rtc_base/location.h"
#include "rtc_base/messagehandler.h"
#include "rtc_base/scoped_ref_ptr.h"
-#include "rtc_base/sigslot.h"
#include "rtc_base/socketserver.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/timeutils.h"
diff --git a/rtc_base/module.mk b/rtc_base/module.mk
index 0f8f8ca..2a1b9f3 100644
--- a/rtc_base/module.mk
+++ b/rtc_base/module.mk
@@ -5,7 +5,7 @@
include common.mk
rtc_base_approved_generic_CXX_OBJECTS = \
- rtc_base/base64.o \
+ rtc_base/third_party/base64/base64.o \
rtc_base/bitbuffer.o \
rtc_base/bitrateallocationstrategy.o \
rtc_base/bufferqueue.o \
diff --git a/rtc_base/nethelpers.h b/rtc_base/nethelpers.h
index de14a06..f9d188f 100644
--- a/rtc_base/nethelpers.h
+++ b/rtc_base/nethelpers.h
@@ -22,8 +22,8 @@
#include "rtc_base/asyncresolverinterface.h"
#include "rtc_base/signalthread.h"
-#include "rtc_base/sigslot.h"
#include "rtc_base/socketaddress.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index 0f42d6f..34da828 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -95,6 +95,7 @@
std::string AdapterTypeToString(AdapterType type) {
switch (type) {
case ADAPTER_TYPE_ANY:
+ return "Wildcard";
case ADAPTER_TYPE_UNKNOWN:
return "Unknown";
case ADAPTER_TYPE_ETHERNET:
diff --git a/rtc_base/network.h b/rtc_base/network.h
index 03a0978..ad932d0 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -22,7 +22,7 @@
#include "rtc_base/ipaddress.h"
#include "rtc_base/messagehandler.h"
#include "rtc_base/networkmonitor.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#if defined(WEBRTC_POSIX)
struct ifaddrs;
diff --git a/rtc_base/networkmonitor.h b/rtc_base/networkmonitor.h
index a174473..a84a30a 100644
--- a/rtc_base/networkmonitor.h
+++ b/rtc_base/networkmonitor.h
@@ -13,7 +13,7 @@
#include "rtc_base/logging.h"
#include "rtc_base/network_constants.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
namespace rtc {
diff --git a/rtc_base/networkroute.h b/rtc_base/networkroute.h
index 5800ef8..31c0831 100644
--- a/rtc_base/networkroute.h
+++ b/rtc_base/networkroute.h
@@ -20,30 +20,13 @@
namespace rtc {
struct NetworkRoute {
- bool connected;
- uint16_t local_network_id;
- uint16_t remote_network_id;
- int last_sent_packet_id; // Last packet id sent on the PREVIOUS route.
- int packet_overhead; // The overhead in bytes from IP layer and above.
-
- NetworkRoute()
- : connected(false),
- local_network_id(0),
- remote_network_id(0),
- last_sent_packet_id(-1),
- packet_overhead(0) {}
-
- // The route is connected if the local and remote network ids are provided.
- // TODO(zhihuang): Remove this and let the caller set the fields explicitly.
- NetworkRoute(bool connected,
- uint16_t local_net_id,
- uint16_t remote_net_id,
- int last_packet_id)
- : connected(connected),
- local_network_id(local_net_id),
- remote_network_id(remote_net_id),
- last_sent_packet_id(last_packet_id),
- packet_overhead(0) {}
+ bool connected = false;
+ uint16_t local_network_id = 0;
+ uint16_t remote_network_id = 0;
+ // Last packet id sent on the PREVIOUS route.
+ int last_sent_packet_id = -1;
+ // The overhead in bytes from IP layer and above.
+ int packet_overhead = 0;
// |last_sent_packet_id| and |packet_overhead| do not affect the NetworkRoute
// comparison.
diff --git a/rtc_base/onetimeevent.h b/rtc_base/onetimeevent.h
index 8c55e26..f649f15 100644
--- a/rtc_base/onetimeevent.h
+++ b/rtc_base/onetimeevent.h
@@ -12,7 +12,6 @@
#define RTC_BASE_ONETIMEEVENT_H_
#include "rtc_base/criticalsection.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
// Provides a simple way to perform an operation (such as logging) one
diff --git a/rtc_base/openssladapter.cc b/rtc_base/openssladapter.cc
index 05de6d0..50284a6 100644
--- a/rtc_base/openssladapter.cc
+++ b/rtc_base/openssladapter.cc
@@ -907,14 +907,14 @@
return nullptr;
}
-#ifdef WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
if (!openssl::LoadBuiltinSSLRootCertificates(ctx)) {
RTC_LOG(LS_ERROR) << "SSL_CTX creation failed: Failed to load any trusted "
"ssl root certificates.";
SSL_CTX_free(ctx);
return nullptr;
}
-#endif // WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
#if !defined(NDEBUG)
SSL_CTX_set_info_callback(ctx, SSLInfoCallback);
diff --git a/rtc_base/opensslcertificate.cc b/rtc_base/opensslcertificate.cc
index 15fc303..ed67a89 100644
--- a/rtc_base/opensslcertificate.cc
+++ b/rtc_base/opensslcertificate.cc
@@ -36,9 +36,9 @@
#include "rtc_base/openssldigest.h"
#include "rtc_base/opensslidentity.h"
#include "rtc_base/opensslutility.h"
-#ifdef WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
#include "rtc_base/sslroots.h"
-#endif
+#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
namespace rtc {
diff --git a/rtc_base/opensslutility.cc b/rtc_base/opensslutility.cc
index 2b4ffb6..46f4547 100644
--- a/rtc_base/opensslutility.cc
+++ b/rtc_base/opensslutility.cc
@@ -23,6 +23,7 @@
#include <openssl/bio.h>
#include <openssl/crypto.h>
+#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@@ -32,9 +33,9 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/openssl.h"
#include "rtc_base/opensslcertificate.h"
-#ifdef WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
#include "rtc_base/sslroots.h"
-#endif // WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
namespace rtc {
namespace openssl {
@@ -109,7 +110,7 @@
}
}
-#ifdef WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
bool LoadBuiltinSSLRootCertificates(SSL_CTX* ctx) {
int count_of_added_certs = 0;
for (size_t i = 0; i < arraysize(kSSLCertCertificateList); i++) {
@@ -129,7 +130,7 @@
}
return count_of_added_certs > 0;
}
-#endif // WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
} // namespace openssl
} // namespace rtc
diff --git a/rtc_base/opensslutility.h b/rtc_base/opensslutility.h
index f579f50..7cb38b5 100644
--- a/rtc_base/opensslutility.h
+++ b/rtc_base/opensslutility.h
@@ -28,12 +28,12 @@
// prefix can be provided for context.
void LogSSLErrors(const std::string& prefix);
-#ifdef WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#ifndef WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
// Attempt to add the certificates from the loader into the SSL_CTX. False is
// returned only if there are no certificates returned from the loader or none
// of them can be added to the TrustStore for the provided context.
bool LoadBuiltinSSLRootCertificates(SSL_CTX* ssl_ctx);
-#endif // WEBRTC_BUILT_IN_SSL_ROOT_CERTIFICATES
+#endif // WEBRTC_EXCLUDE_BUILT_IN_SSL_ROOT_CERTS
} // namespace openssl
} // namespace rtc
diff --git a/rtc_base/optionsfile.cc b/rtc_base/optionsfile.cc
index 8d2d2e0..535859b 100644
--- a/rtc_base/optionsfile.cc
+++ b/rtc_base/optionsfile.cc
@@ -165,7 +165,8 @@
if (!IsLegalName(option)) {
return false;
}
- return ToString(value, &options_[option]);
+ options_[option] = ToString(value);
+ return true;
}
bool OptionsFile::RemoveValue(const std::string& option) {
diff --git a/rtc_base/ptr_util.h b/rtc_base/ptr_util.h
deleted file mode 100644
index 56d8da3..0000000
--- a/rtc_base/ptr_util.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 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.
- */
-
-// This file contains rtc::MakeUnique and rtc::WrapUnique, which are backwards
-// compatibility aliases for absl::make_unique and absl::WrapUnique,
-// respectively. This file will go away soon; use the Abseil types directly in
-// new code.
-
-#ifndef RTC_BASE_PTR_UTIL_H_
-#define RTC_BASE_PTR_UTIL_H_
-
-#include "absl/memory/memory.h"
-
-namespace rtc {
-
-template <typename T, typename... Args>
-auto MakeUnique(Args&&... args)
- -> decltype(absl::make_unique<T, Args...>(std::forward<Args>(args)...)) {
- return absl::make_unique<T, Args...>(std::forward<Args>(args)...);
-}
-
-template <typename T>
-auto MakeUnique(size_t n) -> decltype(absl::make_unique<T>(n)) {
- return absl::make_unique<T>(n);
-}
-
-using absl::WrapUnique;
-
-} // namespace rtc
-
-#endif // RTC_BASE_PTR_UTIL_H_
diff --git a/rtc_base/ptr_util_unittest.cc b/rtc_base/ptr_util_unittest.cc
deleted file mode 100644
index 6497fda..0000000
--- a/rtc_base/ptr_util_unittest.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 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 "rtc_base/ptr_util.h"
-
-#include <stddef.h>
-#include <string>
-
-#include "rtc_base/gunit.h"
-
-namespace rtc {
-
-namespace {
-
-class DeleteCounter {
- public:
- DeleteCounter() { ++count_; }
- ~DeleteCounter() { --count_; }
-
- static size_t count() { return count_; }
-
- private:
- static size_t count_;
-};
-
-size_t DeleteCounter::count_ = 0;
-
-} // namespace
-
-TEST(PtrUtilTest, WrapUnique) {
- EXPECT_EQ(0u, DeleteCounter::count());
- DeleteCounter* counter = new DeleteCounter;
- EXPECT_EQ(1u, DeleteCounter::count());
- std::unique_ptr<DeleteCounter> owned_counter = WrapUnique(counter);
- EXPECT_EQ(1u, DeleteCounter::count());
- owned_counter.reset();
- EXPECT_EQ(0u, DeleteCounter::count());
-}
-
-TEST(PtrUtilTest, MakeUniqueScalar) {
- auto s = MakeUnique<std::string>();
- EXPECT_EQ("", *s);
-
- auto s2 = MakeUnique<std::string>("test");
- EXPECT_EQ("test", *s2);
-}
-
-TEST(PtrUtilTest, MakeUniqueScalarWithMoveOnlyType) {
- using MoveOnly = std::unique_ptr<std::string>;
- auto p = MakeUnique<MoveOnly>(MakeUnique<std::string>("test"));
- EXPECT_EQ("test", **p);
-}
-
-TEST(PtrUtilTest, MakeUniqueArray) {
- EXPECT_EQ(0u, DeleteCounter::count());
- auto a = MakeUnique<DeleteCounter[]>(5);
- EXPECT_EQ(5u, DeleteCounter::count());
- a.reset();
- EXPECT_EQ(0u, DeleteCounter::count());
-}
-
-} // namespace rtc
diff --git a/rtc_base/random.h b/rtc_base/random.h
index 7c103cc..2faa985 100644
--- a/rtc_base/random.h
+++ b/rtc_base/random.h
@@ -15,7 +15,6 @@
#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/rtc_base/rate_statistics.cc b/rtc_base/rate_statistics.cc
index 9b1ff8f..bb506aa 100644
--- a/rtc_base/rate_statistics.cc
+++ b/rtc_base/rate_statistics.cc
@@ -12,6 +12,7 @@
#include <algorithm>
+#include "absl/memory/memory.h"
#include "rtc_base/checks.h"
namespace webrtc {
@@ -26,6 +27,21 @@
max_window_size_ms_(window_size_ms),
current_window_size_ms_(max_window_size_ms_) {}
+RateStatistics::RateStatistics(const RateStatistics& other)
+ : accumulated_count_(other.accumulated_count_),
+ num_samples_(other.num_samples_),
+ oldest_time_(other.oldest_time_),
+ oldest_index_(other.oldest_index_),
+ scale_(other.scale_),
+ max_window_size_ms_(other.max_window_size_ms_),
+ current_window_size_ms_(other.current_window_size_ms_) {
+ buckets_ = absl::make_unique<Bucket[]>(other.max_window_size_ms_);
+ std::copy(other.buckets_.get(),
+ other.buckets_.get() + other.max_window_size_ms_, buckets_.get());
+}
+
+RateStatistics::RateStatistics(RateStatistics&& other) = default;
+
RateStatistics::~RateStatistics() {}
void RateStatistics::Reset() {
diff --git a/rtc_base/rate_statistics.h b/rtc_base/rate_statistics.h
index fe5ae82..68035c9 100644
--- a/rtc_base/rate_statistics.h
+++ b/rtc_base/rate_statistics.h
@@ -14,7 +14,6 @@
#include <memory>
#include "absl/types/optional.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
@@ -28,6 +27,11 @@
// scale = coefficient to convert counts/ms to desired unit
// ex: kBpsScale (8000) for bits/s if count represents bytes.
RateStatistics(int64_t max_window_size_ms, float scale);
+
+ RateStatistics(const RateStatistics& other);
+
+ RateStatistics(RateStatistics&& other);
+
~RateStatistics();
// Reset instance to original state.
diff --git a/rtc_base/signalthread.h b/rtc_base/signalthread.h
index 9d140c0..be54d9c 100644
--- a/rtc_base/signalthread.h
+++ b/rtc_base/signalthread.h
@@ -16,7 +16,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/nullsocketserver.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
namespace rtc {
diff --git a/rtc_base/sigslot_unittest.cc b/rtc_base/sigslot_unittest.cc
index 114a59f..2f3de40 100644
--- a/rtc_base/sigslot_unittest.cc
+++ b/rtc_base/sigslot_unittest.cc
@@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/gunit.h"
#include "rtc_base/sigslotrepeater.h"
diff --git a/rtc_base/sigslotrepeater.h b/rtc_base/sigslotrepeater.h
index ca44854..724e624 100644
--- a/rtc_base/sigslotrepeater.h
+++ b/rtc_base/sigslotrepeater.h
@@ -21,7 +21,7 @@
// TODO(deadbeef): Actually use this, after we decide on some style points on
// using signals, so it doesn't get deleted again.
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace sigslot {
diff --git a/rtc_base/sigslottester.h b/rtc_base/sigslottester.h
index 646ba22..73f4365 100644
--- a/rtc_base/sigslottester.h
+++ b/rtc_base/sigslottester.h
@@ -39,7 +39,7 @@
// /* See unit-tests for more examples */
#include "rtc_base/constructormagic.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
diff --git a/rtc_base/sigslottester.h.pump b/rtc_base/sigslottester.h.pump
index 1029a0f..0c7c693 100755
--- a/rtc_base/sigslottester.h.pump
+++ b/rtc_base/sigslottester.h.pump
@@ -36,7 +36,7 @@
// /* See unit-tests for more examples */
#include "rtc_base/constructormagic.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
diff --git a/rtc_base/sigslottester_unittest.cc b/rtc_base/sigslottester_unittest.cc
index c8e87e5..8fde268 100644
--- a/rtc_base/sigslottester_unittest.cc
+++ b/rtc_base/sigslottester_unittest.cc
@@ -13,7 +13,7 @@
#include <string>
#include "rtc_base/gunit.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
diff --git a/rtc_base/sslcertificate.cc b/rtc_base/sslcertificate.cc
index d99da60..9a38fc0 100644
--- a/rtc_base/sslcertificate.cc
+++ b/rtc_base/sslcertificate.cc
@@ -15,11 +15,11 @@
#include <utility>
#include "absl/memory/memory.h"
-#include "rtc_base/base64.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/opensslcertificate.h"
#include "rtc_base/sslfingerprint.h"
+#include "rtc_base/third_party/base64/base64.h"
namespace rtc {
diff --git a/rtc_base/sslidentity.cc b/rtc_base/sslidentity.cc
index 94944f9..f286884 100644
--- a/rtc_base/sslidentity.cc
+++ b/rtc_base/sslidentity.cc
@@ -16,11 +16,11 @@
#include <utility>
#include "absl/memory/memory.h"
-#include "rtc_base/base64.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/opensslidentity.h"
#include "rtc_base/sslfingerprint.h"
+#include "rtc_base/third_party/base64/base64.h"
namespace rtc {
diff --git a/rtc_base/stream.cc b/rtc_base/stream.cc
index b9691c5..3f4d3dc 100644
--- a/rtc_base/stream.cc
+++ b/rtc_base/stream.cc
@@ -553,22 +553,6 @@
}
///////////////////////////////////////////////////////////////////////////////
-
-ExternalMemoryStream::ExternalMemoryStream() {}
-
-ExternalMemoryStream::ExternalMemoryStream(void* data, size_t length) {
- SetData(data, length);
-}
-
-ExternalMemoryStream::~ExternalMemoryStream() {}
-
-void ExternalMemoryStream::SetData(void* data, size_t length) {
- data_length_ = buffer_length_ = length;
- buffer_ = static_cast<char*>(data);
- seek_position_ = 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
// FifoBuffer
///////////////////////////////////////////////////////////////////////////////
diff --git a/rtc_base/stream.h b/rtc_base/stream.h
index ee0f149..ac8193b 100644
--- a/rtc_base/stream.h
+++ b/rtc_base/stream.h
@@ -21,7 +21,7 @@
#include "rtc_base/logging.h"
#include "rtc_base/messagehandler.h"
#include "rtc_base/messagequeue.h"
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
@@ -421,18 +421,6 @@
StreamResult DoReserve(size_t size, int* error) override;
};
-// ExternalMemoryStream adapts an external memory buffer, so writes which would
-// extend past the end of the buffer will return end-of-stream.
-
-class ExternalMemoryStream : public MemoryStreamBase {
- public:
- ExternalMemoryStream();
- ExternalMemoryStream(void* data, size_t length);
- ~ExternalMemoryStream() override;
-
- void SetData(void* data, size_t length);
-};
-
// FifoBuffer allows for efficient, thread-safe buffering of data between
// writer and reader. As the data can wrap around the end of the buffer,
// MemoryStreamBase can't help us here.
diff --git a/rtc_base/string_to_number.cc b/rtc_base/string_to_number.cc
index 06ac9e9..9201242 100644
--- a/rtc_base/string_to_number.cc
+++ b/rtc_base/string_to_number.cc
@@ -48,5 +48,41 @@
return absl::nullopt;
}
+template <typename T>
+T StrToT(const char* str, char** str_end);
+
+template <>
+inline float StrToT(const char* str, char** str_end) {
+ return std::strtof(str, str_end);
+}
+
+template <>
+inline double StrToT(const char* str, char** str_end) {
+ return std::strtod(str, str_end);
+}
+
+template <>
+inline long double StrToT(const char* str, char** str_end) {
+ return std::strtold(str, str_end);
+}
+
+template <typename T>
+absl::optional<T> ParseFloatingPoint(const char* str) {
+ RTC_DCHECK(str);
+ if (*str == '\0')
+ return absl::nullopt;
+ char* end = nullptr;
+ errno = 0;
+ const T value = StrToT<T>(str, &end);
+ if (end && *end == '\0' && errno == 0) {
+ return value;
+ }
+ return absl::nullopt;
+}
+
+template absl::optional<float> ParseFloatingPoint(const char* str);
+template absl::optional<double> ParseFloatingPoint(const char* str);
+template absl::optional<long double> ParseFloatingPoint(const char* str);
+
} // namespace string_to_number_internal
} // namespace rtc
diff --git a/rtc_base/string_to_number.h b/rtc_base/string_to_number.h
index 9b4fa67..7ea9f25 100644
--- a/rtc_base/string_to_number.h
+++ b/rtc_base/string_to_number.h
@@ -48,6 +48,9 @@
absl::optional<signed_type> ParseSigned(const char* str, int base);
absl::optional<unsigned_type> ParseUnsigned(const char* str, int base);
+
+template <typename T>
+absl::optional<T> ParseFloatingPoint(const char* str);
} // namespace string_to_number_internal
template <typename T>
@@ -88,6 +91,17 @@
return absl::nullopt;
}
+template <typename T>
+typename std::enable_if<std::is_floating_point<T>::value,
+ absl::optional<T>>::type
+StringToNumber(const char* str, int base = 10) {
+ static_assert(
+ std::numeric_limits<T>::max() <= std::numeric_limits<long double>::max(),
+ "StringToNumber only supports floating-point numbers as large "
+ "as long double");
+ return string_to_number_internal::ParseFloatingPoint<T>(str);
+}
+
// The std::string overloads only exists if there is a matching const char*
// version.
template <typename T>
diff --git a/rtc_base/stringencode.cc b/rtc_base/stringencode.cc
index 8e7c6d7..b410477 100644
--- a/rtc_base/stringencode.cc
+++ b/rtc_base/stringencode.cc
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/stringutils.h"
@@ -410,4 +411,90 @@
return fields->size();
}
+std::string ToString(const bool b) {
+ return b ? "true" : "false";
+}
+
+std::string ToString(const char* const s) {
+ return std::string(s);
+}
+std::string ToString(const std::string s) {
+ return s;
+}
+
+std::string ToString(const short s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%hd", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const unsigned short s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%hu", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const int s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%d", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const unsigned int s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%u", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const long int s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%ld", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const unsigned long int s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%lu", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const long long int s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%lld", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+std::string ToString(const unsigned long long int s) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%llu", s);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+
+std::string ToString(const double d) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%g", d);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+
+std::string ToString(const void* const p) {
+ char buf[32];
+ const int len = std::snprintf(&buf[0], arraysize(buf), "%p", p);
+ RTC_DCHECK_LE(len, arraysize(buf));
+ return std::string(&buf[0], len);
+}
+
+bool FromString(const std::string& s, bool* b) {
+ if (s == "false") {
+ *b = false;
+ return true;
+ }
+ if (s == "true") {
+ *b = true;
+ return true;
+ }
+ return false;
+}
+
} // namespace rtc
diff --git a/rtc_base/stringencode.h b/rtc_base/stringencode.h
index 7042c4a..830ea77 100644
--- a/rtc_base/stringencode.h
+++ b/rtc_base/stringencode.h
@@ -16,6 +16,7 @@
#include <vector>
#include "rtc_base/checks.h"
+#include "rtc_base/string_to_number.h"
namespace rtc {
@@ -147,32 +148,40 @@
std::string* rest);
// Convert arbitrary values to/from a string.
+// TODO(jonasolsson): Remove these when absl::StrCat becomes available.
+std::string ToString(bool b);
-template <class T>
-static bool ToString(const T& t, std::string* s) {
- RTC_DCHECK(s);
- std::ostringstream oss;
- oss << std::boolalpha << t;
- *s = oss.str();
- return !oss.fail();
-}
+std::string ToString(const char* s);
+std::string ToString(std::string t);
-template <class T>
+std::string ToString(short s);
+std::string ToString(unsigned short s);
+std::string ToString(int s);
+std::string ToString(unsigned int s);
+std::string ToString(long int s);
+std::string ToString(unsigned long int s);
+std::string ToString(long long int s);
+std::string ToString(unsigned long long int s);
+
+std::string ToString(double t);
+
+std::string ToString(const void* p);
+
+template <typename T,
+ typename std::enable_if<std::is_arithmetic<T>::value &&
+ !std::is_same<T, bool>::value,
+ int>::type = 0>
static bool FromString(const std::string& s, T* t) {
RTC_DCHECK(t);
- std::istringstream iss(s);
- iss >> std::boolalpha >> *t;
- return !iss.fail();
+ absl::optional<T> result = StringToNumber<T>(s);
+
+ if (result)
+ *t = *result;
+
+ return result.has_value();
}
-// Inline versions of the string conversion routines.
-
-template <typename T>
-static inline std::string ToString(const T& val) {
- std::string str;
- ToString(val, &str);
- return str;
-}
+bool FromString(const std::string& s, bool* b);
template <typename T>
static inline T FromString(const std::string& str) {
@@ -181,13 +190,6 @@
return val;
}
-template <typename T>
-static inline T FromString(const T& defaultValue, const std::string& str) {
- T val(defaultValue);
- FromString(str, &val);
- return val;
-}
-
//////////////////////////////////////////////////////////////////////
} // namespace rtc
diff --git a/rtc_base/stringencode_unittest.cc b/rtc_base/stringencode_unittest.cc
index ffb90b2..9bdc592 100644
--- a/rtc_base/stringencode_unittest.cc
+++ b/rtc_base/stringencode_unittest.cc
@@ -13,6 +13,8 @@
#include "rtc_base/gunit.h"
#include "rtc_base/stringutils.h"
+#include <sstream> // no-presubmit-check TODO(webrtc:8982)
+
namespace rtc {
class HexEncodeTest : public testing::Test {
@@ -351,53 +353,79 @@
ASSERT_STREQ("", fields.at(0).c_str());
}
-TEST(BoolTest, DecodeValid) {
- bool value;
- EXPECT_TRUE(FromString("true", &value));
- EXPECT_TRUE(value);
- EXPECT_TRUE(FromString("true,", &value));
- EXPECT_TRUE(value);
- EXPECT_TRUE(FromString("true , true", &value));
- EXPECT_TRUE(value);
- EXPECT_TRUE(FromString("true ,\n false", &value));
- EXPECT_TRUE(value);
- EXPECT_TRUE(FromString(" true \n", &value));
- EXPECT_TRUE(value);
+TEST(ToString, SanityCheck) {
+ EXPECT_EQ(ToString(true), "true");
+ EXPECT_EQ(ToString(false), "false");
- EXPECT_TRUE(FromString("false", &value));
- EXPECT_FALSE(value);
- EXPECT_TRUE(FromString(" false ", &value));
- EXPECT_FALSE(value);
- EXPECT_TRUE(FromString(" false, ", &value));
- EXPECT_FALSE(value);
+ const char* c = "message";
+ EXPECT_EQ(ToString(c), c);
+ EXPECT_EQ(ToString(std::string(c)), c);
- EXPECT_TRUE(FromString<bool>("true\n"));
- EXPECT_FALSE(FromString<bool>("false\n"));
+ EXPECT_EQ(ToString(short{-123}), "-123");
+ EXPECT_EQ(ToString((unsigned short)123), "123");
+ EXPECT_EQ(ToString(int{-123}), "-123");
+ EXPECT_EQ(ToString((unsigned int)123), "123");
+ EXPECT_EQ(ToString((long int)-123), "-123");
+ EXPECT_EQ(ToString((unsigned long int)123), "123");
+ EXPECT_EQ(ToString((long long int)-123), "-123");
+ EXPECT_EQ(ToString((unsigned long long int)123), "123");
+
+ int i = 10;
+ int* p = &i;
+ std::ostringstream s; // no-presubmit-check TODO(webrtc:8982)
+ s << p;
+ EXPECT_EQ(s.str(), ToString(p));
+
+ EXPECT_EQ(ToString(0.5), "0.5");
}
-TEST(BoolTest, DecodeInvalid) {
- bool value;
- EXPECT_FALSE(FromString("True", &value));
- EXPECT_FALSE(FromString("TRUE", &value));
- EXPECT_FALSE(FromString("False", &value));
- EXPECT_FALSE(FromString("FALSE", &value));
- EXPECT_FALSE(FromString("0", &value));
- EXPECT_FALSE(FromString("1", &value));
- EXPECT_FALSE(FromString("0,", &value));
- EXPECT_FALSE(FromString("1,", &value));
- EXPECT_FALSE(FromString("1,0", &value));
- EXPECT_FALSE(FromString("1.", &value));
- EXPECT_FALSE(FromString("1.0", &value));
- EXPECT_FALSE(FromString("", &value));
- EXPECT_FALSE(FromString<bool>("false\nfalse"));
+template <typename T>
+void ParsesTo(std::string s, T t) {
+ T value;
+ EXPECT_TRUE(FromString(s, &value));
+ EXPECT_EQ(value, t);
}
-TEST(BoolTest, RoundTrip) {
- bool value;
- EXPECT_TRUE(FromString(ToString(true), &value));
- EXPECT_TRUE(value);
- EXPECT_TRUE(FromString(ToString(false), &value));
- EXPECT_FALSE(value);
+TEST(FromString, DecodeValid) {
+ ParsesTo("true", true);
+ ParsesTo("false", false);
+
+ ParsesTo("105", 105);
+ ParsesTo("0.25", 0.25);
+}
+
+template <typename T>
+void FailsToParse(std::string s) {
+ T value;
+ EXPECT_FALSE(FromString(s, &value)) << "[" << s << "]";
+}
+
+TEST(FromString, DecodeInvalid) {
+ FailsToParse<bool>("True");
+ FailsToParse<bool>("0");
+ FailsToParse<bool>("yes");
+
+ FailsToParse<int>("0.5");
+ FailsToParse<int>("XIV");
+ FailsToParse<double>("");
+ FailsToParse<double>(" ");
+ FailsToParse<int>("1 2");
+}
+
+template <typename T>
+void RoundTrip(T t) {
+ std::string s = ToString(t);
+ T value;
+ EXPECT_TRUE(FromString(s, &value));
+ EXPECT_EQ(value, t);
+}
+
+TEST(FromString, RoundTrip) {
+ RoundTrip<int>(123);
+ RoundTrip(false);
+ RoundTrip(true);
+ RoundTrip(0.5);
+ RoundTrip(-15l);
}
} // namespace rtc
diff --git a/rtc_base/swap_queue.h b/rtc_base/swap_queue.h
index f794ad9..172f2f5 100644
--- a/rtc_base/swap_queue.h
+++ b/rtc_base/swap_queue.h
@@ -18,6 +18,7 @@
#include "rtc_base/checks.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/criticalsection.h"
+#include "rtc_base/system/unused.h"
namespace webrtc {
diff --git a/rtc_base/synchronization/BUILD.gn b/rtc_base/synchronization/BUILD.gn
index 9d9ea6f..447be38 100644
--- a/rtc_base/synchronization/BUILD.gn
+++ b/rtc_base/synchronization/BUILD.gn
@@ -21,7 +21,6 @@
]
deps = [
"..:macromagic",
- "../..:typedefs",
]
if (is_win) {
sources += [
diff --git a/rtc_base/synchronization/rw_lock_posix.h b/rtc_base/synchronization/rw_lock_posix.h
index 9a92bcd..a103fe7 100644
--- a/rtc_base/synchronization/rw_lock_posix.h
+++ b/rtc_base/synchronization/rw_lock_posix.h
@@ -14,7 +14,6 @@
#include <pthread.h>
#include "rtc_base/synchronization/rw_lock_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/rtc_base/system/BUILD.gn b/rtc_base/system/BUILD.gn
index 9d3fa2c..64df84f 100644
--- a/rtc_base/system/BUILD.gn
+++ b/rtc_base/system/BUILD.gn
@@ -38,7 +38,6 @@
deps = [
"..:checks",
"..:criticalsection",
- "../..:typedefs",
"../..:webrtc_common",
]
}
diff --git a/rtc_base/system/file_wrapper.h b/rtc_base/system/file_wrapper.h
index 4672cc4..5411b04 100644
--- a/rtc_base/system/file_wrapper.h
+++ b/rtc_base/system/file_wrapper.h
@@ -16,7 +16,6 @@
#include "common_types.h" // NOLINT(build/include)
#include "rtc_base/criticalsection.h"
-#include "typedefs.h" // NOLINT(build/include)
// Implementation that can read (exclusive) or write from/to a file.
diff --git a/rtc_base/task_queue_libevent.cc b/rtc_base/task_queue_libevent.cc
index 4db4827..8dc9b15 100644
--- a/rtc_base/task_queue_libevent.cc
+++ b/rtc_base/task_queue_libevent.cc
@@ -24,6 +24,7 @@
#include "rtc_base/platform_thread.h"
#include "rtc_base/refcount.h"
#include "rtc_base/refcountedobject.h"
+#include "rtc_base/system/unused.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/task_queue_posix.h"
#include "rtc_base/timeutils.h"
diff --git a/rtc_base/third_party/base64/BUILD.gn b/rtc_base/third_party/base64/BUILD.gn
new file mode 100644
index 0000000..dca47e0
--- /dev/null
+++ b/rtc_base/third_party/base64/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("base64") {
+ visibility = [ "*" ]
+ sources = [
+ "base64.cc",
+ "base64.h",
+ ]
+}
diff --git a/rtc_base/third_party/base64/LICENSE b/rtc_base/third_party/base64/LICENSE
new file mode 100644
index 0000000..4ad21d1
--- /dev/null
+++ b/rtc_base/third_party/base64/LICENSE
@@ -0,0 +1,14 @@
+//*********************************************************************
+//* Base64 - a simple base64 encoder and decoder.
+//*
+//* Copyright (c) 1999, Bob Withers - bwit@pobox.com
+//*
+//* This code may be freely used for any purpose, either personal
+//* or commercial, provided the authors copyright notice remains
+//* intact.
+//*
+//* Enhancements by Stanley Yamane:
+//* o reverse lookup table for the decode function
+//* o reserve string buffer space in advance
+//*
+//*********************************************************************
diff --git a/rtc_base/third_party/base64/README.chromium b/rtc_base/third_party/base64/README.chromium
new file mode 100644
index 0000000..92ba0d3
--- /dev/null
+++ b/rtc_base/third_party/base64/README.chromium
@@ -0,0 +1,11 @@
+Name: A simple base64 encoder and decoder
+Short Name: base64
+URL:
+Version: 0
+Date: 2018-06-20
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+A simple base64 encoder and decoder
diff --git a/rtc_base/base64.cc b/rtc_base/third_party/base64/base64.cc
similarity index 99%
rename from rtc_base/base64.cc
rename to rtc_base/third_party/base64/base64.cc
index 6add993..53ff6b9 100644
--- a/rtc_base/base64.cc
+++ b/rtc_base/third_party/base64/base64.cc
@@ -14,10 +14,10 @@
//*
//*********************************************************************
-#include "rtc_base/base64.h"
+#include "rtc_base/third_party/base64/base64.h"
-#include <string.h>
#include <assert.h>
+#include <string.h>
using std::vector;
diff --git a/rtc_base/base64.h b/rtc_base/third_party/base64/base64.h
similarity index 96%
rename from rtc_base/base64.h
rename to rtc_base/third_party/base64/base64.h
index bfe2fe6..bbc93c8 100644
--- a/rtc_base/base64.h
+++ b/rtc_base/third_party/base64/base64.h
@@ -9,8 +9,8 @@
//* intact.
//*********************************************************************
-#ifndef RTC_BASE_BASE64_H_
-#define RTC_BASE_BASE64_H_
+#ifndef RTC_BASE_THIRD_PARTY_BASE64_BASE64_H_
+#define RTC_BASE_THIRD_PARTY_BASE64_BASE64_H_
#include <string>
#include <vector>
@@ -120,4 +120,4 @@
} // namespace rtc
-#endif // RTC_BASE_BASE64_H_
+#endif /* RTC_BASE_THIRD_PARTY_BASE64_BASE64_H_ */
diff --git a/rtc_base/third_party/base64/module.mk b/rtc_base/third_party/base64/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/rtc_base/third_party/base64/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/rtc_base/third_party/module.mk b/rtc_base/third_party/module.mk
new file mode 100644
index 0000000..37c23f4
--- /dev/null
+++ b/rtc_base/third_party/module.mk
@@ -0,0 +1,5 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+include common.mk
diff --git a/rtc_base/third_party/sigslot/BUILD.gn b/rtc_base/third_party/sigslot/BUILD.gn
new file mode 100644
index 0000000..aea748e
--- /dev/null
+++ b/rtc_base/third_party/sigslot/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the ../../../LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS. All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+import("../../../webrtc.gni")
+
+rtc_source_set("sigslot") {
+ visibility = [ "*" ]
+ sources = [
+ "sigslot.cc",
+ "sigslot.h",
+ ]
+}
diff --git a/rtc_base/third_party/sigslot/LICENSE b/rtc_base/third_party/sigslot/LICENSE
new file mode 100644
index 0000000..d1c66c7
--- /dev/null
+++ b/rtc_base/third_party/sigslot/LICENSE
@@ -0,0 +1,7 @@
+// sigslot.h: Signal/Slot classes
+//
+// Written by Sarah Thompson (sarah@telergy.com) 2002.
+//
+// License: Public domain. You are free to use this code however you like, with
+// the proviso that the author takes on no responsibility or liability for any
+// use.
diff --git a/rtc_base/third_party/sigslot/README.chromium b/rtc_base/third_party/sigslot/README.chromium
new file mode 100644
index 0000000..e0575cf
--- /dev/null
+++ b/rtc_base/third_party/sigslot/README.chromium
@@ -0,0 +1,20 @@
+Name: C++ Signal/Slot Library
+Short Name: sigslot
+URL: http://sigslot.sourceforge.net/
+Version: 0
+Date: 2018-07-09
+License: Custom license
+License File: LICENSE
+Security Critical: yes
+
+Description:
+C++ Signal/Slot Library
+
+This file has been modified such that has_slots and signalx do not have to be
+using the same threading requirements. E.g. it is possible to connect a
+has_slots<single_threaded> and signal0<multi_threaded_local> or
+has_slots<multi_threaded_local> and signal0<single_threaded>.
+If has_slots is single threaded the user must ensure that it is not trying
+to connect or disconnect to signalx concurrently or data race may occur.
+If signalx is single threaded the user must ensure that disconnect, connect
+or signal is not happening concurrently or data race may occur.
diff --git a/rtc_base/sigslot.cc b/rtc_base/third_party/sigslot/sigslot.cc
similarity index 90%
rename from rtc_base/sigslot.cc
rename to rtc_base/third_party/sigslot/sigslot.cc
index 9d792cb..d852a2b 100644
--- a/rtc_base/sigslot.cc
+++ b/rtc_base/third_party/sigslot/sigslot.cc
@@ -6,7 +6,7 @@
// the proviso that the author takes on no responsibility or liability for any
// use.
-#include "rtc_base/sigslot.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
namespace sigslot {
diff --git a/rtc_base/sigslot.h b/rtc_base/third_party/sigslot/sigslot.h
similarity index 98%
rename from rtc_base/sigslot.h
rename to rtc_base/third_party/sigslot/sigslot.h
index 15abdca..c77e4e6 100644
--- a/rtc_base/sigslot.h
+++ b/rtc_base/third_party/sigslot/sigslot.h
@@ -93,8 +93,8 @@
// If signalx is single threaded the user must ensure that disconnect, connect
// or signal is not happening concurrently or data race may occur.
-#ifndef RTC_BASE_SIGSLOT_H_
-#define RTC_BASE_SIGSLOT_H_
+#ifndef RTC_BASE_THIRD_PARTY_SIGSLOT_SIGSLOT_H_
+#define RTC_BASE_THIRD_PARTY_SIGSLOT_SIGSLOT_H_
#include <stdlib.h>
#include <cstring>
@@ -110,7 +110,7 @@
#define _SIGSLOT_SINGLE_THREADED
#elif defined(WEBRTC_WIN)
#define _SIGSLOT_HAS_WIN32_THREADS
-#include "rtc_base/win32.h"
+#include "windows.h"
#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)
#define _SIGSLOT_HAS_POSIX_THREADS
#include <pthread.h>
@@ -641,4 +641,4 @@
} // namespace sigslot
-#endif // RTC_BASE_SIGSLOT_H_
+#endif /* RTC_BASE_THIRD_PARTY_SIGSLOT_SIGSLOT_H_ */
diff --git a/rtc_base/thread_unittest.cc b/rtc_base/thread_unittest.cc
index 74f62eb..d5c53f8 100644
--- a/rtc_base/thread_unittest.cc
+++ b/rtc_base/thread_unittest.cc
@@ -16,8 +16,8 @@
#include "rtc_base/gunit.h"
#include "rtc_base/nullsocketserver.h"
#include "rtc_base/physicalsocketserver.h"
-#include "rtc_base/sigslot.h"
#include "rtc_base/socketaddress.h"
+#include "rtc_base/third_party/sigslot/sigslot.h"
#include "rtc_base/thread.h"
#if defined(WEBRTC_WIN)
diff --git a/rtc_base/time/BUILD.gn b/rtc_base/time/BUILD.gn
index f8f6244..7b298ce 100644
--- a/rtc_base/time/BUILD.gn
+++ b/rtc_base/time/BUILD.gn
@@ -18,7 +18,6 @@
"timestamp_extrapolator.h",
]
deps = [
- "../..:typedefs",
"../synchronization:rw_lock_wrapper",
]
}
diff --git a/rtc_base/time/timestamp_extrapolator.h b/rtc_base/time/timestamp_extrapolator.h
index 6638184..63af57b 100644
--- a/rtc_base/time/timestamp_extrapolator.h
+++ b/rtc_base/time/timestamp_extrapolator.h
@@ -11,8 +11,9 @@
#ifndef RTC_BASE_TIME_TIMESTAMP_EXTRAPOLATOR_H_
#define RTC_BASE_TIME_TIMESTAMP_EXTRAPOLATOR_H_
+#include <stdint.h>
+
#include "rtc_base/synchronization/rw_lock_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/rtc_base/timeutils.cc b/rtc_base/timeutils.cc
index f65bd15..de8fc32 100644
--- a/rtc_base/timeutils.cc
+++ b/rtc_base/timeutils.cc
@@ -201,6 +201,9 @@
}
int64_t TimeUTCMicros() {
+ if (g_clock) {
+ return g_clock->TimeNanos() / kNumNanosecsPerMicrosec;
+ }
#if defined(WEBRTC_POSIX)
struct timeval time;
gettimeofday(&time, nullptr);
@@ -217,4 +220,8 @@
#endif
}
+int64_t TimeUTCMillis() {
+ return TimeUTCMicros() / kNumMicrosecsPerMillisec;
+}
+
} // namespace rtc
diff --git a/rtc_base/timeutils.h b/rtc_base/timeutils.h
index 48b5c8d..20b1dac 100644
--- a/rtc_base/timeutils.h
+++ b/rtc_base/timeutils.h
@@ -126,6 +126,10 @@
// measuring time intervals and timeouts.
int64_t TimeUTCMicros();
+// Return the number of milliseconds since January 1, 1970, UTC.
+// See above.
+int64_t TimeUTCMillis();
+
// Interval of time from the range [min, max] inclusive.
class IntervalRange {
public:
diff --git a/script/sync-apm.sh b/script/sync-apm.sh
index ab645f9..47eccdd 100755
--- a/script/sync-apm.sh
+++ b/script/sync-apm.sh
@@ -24,6 +24,7 @@
rsync "${OPTIONS[@]}" ${FROM}/modules/audio_processing ${TO}/modules
rsync "${OPTIONS[@]}" ${FROM}/modules/include ${TO}/modules
rsync "${OPTIONS[@]}" ${FROM}/modules/rtp_rtcp ${TO}/modules
+rsync "${OPTIONS[@]}" ${FROM}/modules/third_party ${TO}/modules
# Add video codecs headers for common includes to work.
mkdir -p ${TO}/modules/video_coding/codecs
diff --git a/system_wrappers/BUILD.gn b/system_wrappers/BUILD.gn
index 4c09164..106c63b 100644
--- a/system_wrappers/BUILD.gn
+++ b/system_wrappers/BUILD.gn
@@ -39,10 +39,10 @@
":metrics_api",
":runtime_enabled_features_api",
"..:webrtc_common",
- "../:typedefs",
"../modules:module_api_public",
"../rtc_base:checks",
"../rtc_base/synchronization:rw_lock_wrapper",
+ "../rtc_base/system:arch",
"//third_party/abseil-cpp/absl/types:optional",
]
@@ -103,7 +103,6 @@
]
deps = [
"..:webrtc_common",
- "../:typedefs",
]
}
@@ -194,6 +193,7 @@
]
deps = [
":cpu_features_api",
+ "../rtc_base/system:arch",
]
}
}
@@ -218,7 +218,6 @@
":metrics_default",
":system_wrappers",
"..:webrtc_common",
- "../:typedefs",
"../rtc_base:rtc_base_approved",
"../test:test_main",
"//testing/gtest",
diff --git a/system_wrappers/include/clock.h b/system_wrappers/include/clock.h
index 0164288..4b6eab8 100644
--- a/system_wrappers/include/clock.h
+++ b/system_wrappers/include/clock.h
@@ -15,7 +15,6 @@
#include "rtc_base/synchronization/rw_lock_wrapper.h"
#include "system_wrappers/include/ntp_time.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
diff --git a/system_wrappers/include/cpu_features_wrapper.h b/system_wrappers/include/cpu_features_wrapper.h
index 07ee912..739161a 100644
--- a/system_wrappers/include/cpu_features_wrapper.h
+++ b/system_wrappers/include/cpu_features_wrapper.h
@@ -11,12 +11,12 @@
#ifndef SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_
#define SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_
+#include <stdint.h>
+
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
-#include "typedefs.h" // NOLINT(build/include)
-
// List of features in x86.
typedef enum { kSSE2, kSSE3 } CPUFeature;
diff --git a/system_wrappers/include/cpu_info.h b/system_wrappers/include/cpu_info.h
index dbd5d60..ab546c7 100644
--- a/system_wrappers/include/cpu_info.h
+++ b/system_wrappers/include/cpu_info.h
@@ -11,7 +11,7 @@
#ifndef SYSTEM_WRAPPERS_INCLUDE_CPU_INFO_H_
#define SYSTEM_WRAPPERS_INCLUDE_CPU_INFO_H_
-#include "typedefs.h" // NOLINT(build/include)
+#include <stdint.h>
namespace webrtc {
diff --git a/system_wrappers/include/rtp_to_ntp_estimator.h b/system_wrappers/include/rtp_to_ntp_estimator.h
index 62a79a5..d7009d8 100644
--- a/system_wrappers/include/rtp_to_ntp_estimator.h
+++ b/system_wrappers/include/rtp_to_ntp_estimator.h
@@ -17,7 +17,6 @@
#include "modules/include/module_common_types_public.h"
#include "rtc_base/numerics/moving_median_filter.h"
#include "system_wrappers/include/ntp_time.h"
-#include "typedefs.h" // NOLINT(build/include)
namespace webrtc {
// Class for converting an RTP timestamp to the NTP domain in milliseconds.
diff --git a/system_wrappers/source/cpu_features.cc b/system_wrappers/source/cpu_features.cc
index 7417f53..d433a77 100644
--- a/system_wrappers/source/cpu_features.cc
+++ b/system_wrappers/source/cpu_features.cc
@@ -10,13 +10,13 @@
// Parts of this file derived from Chromium's base/cpu.cc.
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#if defined(WEBRTC_ARCH_X86_FAMILY) && defined(_MSC_VER)
#include <intrin.h>
#endif
-#include "typedefs.h" // NOLINT(build/include)
// No CPU feature is available => straight C path.
int GetCPUInfoNoASM(CPUFeature feature) {
diff --git a/system_wrappers/source/cpu_features_linux.c b/system_wrappers/source/cpu_features_linux.c
index 9c56450..004de5a 100644
--- a/system_wrappers/source/cpu_features_linux.c
+++ b/system_wrappers/source/cpu_features_linux.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <link.h>
#endif
+#include "rtc_base/system/arch.h"
#include "system_wrappers/include/cpu_features_wrapper.h"
#if defined(WEBRTC_ARCH_ARM_FAMILY)
diff --git a/system_wrappers/source/event_timer_win.h b/system_wrappers/source/event_timer_win.h
index 0b4dff6..c99f8c6 100644
--- a/system_wrappers/source/event_timer_win.h
+++ b/system_wrappers/source/event_timer_win.h
@@ -11,12 +11,12 @@
#ifndef SYSTEM_WRAPPERS_SOURCE_EVENT_WIN_H_
#define SYSTEM_WRAPPERS_SOURCE_EVENT_WIN_H_
+#include <stdint.h>
+
#include <windows.h>
#include "system_wrappers/include/event_wrapper.h"
-#include "typedefs.h" // NOLINT(build/include)
-
namespace webrtc {
class EventTimerWin : public EventTimerWrapper {
diff --git a/webrtc_apm.cc b/webrtc_apm.cc
index 4985ac1..beba356 100644
--- a/webrtc_apm.cc
+++ b/webrtc_apm.cc
@@ -17,17 +17,27 @@
const struct aec_config *config,
webrtc::EchoCanceller3Config *aec3_config)
{
- aec3_config->delay = {
- config->delay.default_delay,
- config->delay.down_sampling_factor,
- config->delay.num_filters,
- config->delay.api_call_jitter_blocks,
+ aec3_config->delay.default_delay =
+ config->delay.default_delay;
+ aec3_config->delay.down_sampling_factor =
+ config->delay.down_sampling_factor;
+ aec3_config->delay.num_filters =
+ config->delay.num_filters;
+ aec3_config->delay.api_call_jitter_blocks =
+ config->delay.api_call_jitter_blocks;
+ aec3_config->delay.min_echo_path_delay_blocks =
config->delay.min_echo_path_delay_blocks,
- config->delay.delay_headroom_blocks,
- config->delay.hysteresis_limit_1_blocks,
+ aec3_config->delay.delay_headroom_blocks =
+ config->delay.delay_headroom_blocks;
+ aec3_config->delay.hysteresis_limit_1_blocks =
+ config->delay.hysteresis_limit_1_blocks;
+ aec3_config->delay.hysteresis_limit_2_blocks =
config->delay.hysteresis_limit_2_blocks,
- config->delay.skew_hysteresis_blocks
- };
+ aec3_config->delay.skew_hysteresis_blocks =
+ config->delay.skew_hysteresis_blocks;
+ aec3_config->delay.fixed_capture_delay_samples =
+ config->delay.fixed_capture_delay_samples;
+
aec3_config->filter.main = {
config->filter.main.length_blocks,
config->filter.main.leakage_converged,
@@ -54,20 +64,30 @@
};
aec3_config->filter.config_change_duration_blocks =
config->filter.config_change_duration_blocks;
+ aec3_config->filter.initial_state_seconds =
+ config->filter.initial_state_seconds;
+ aec3_config->filter.conservative_initial_phase =
+ static_cast<bool>(config->filter.conservative_initial_phase);
+ aec3_config->filter.enable_shadow_filter_output_usage =
+ static_cast<bool>(
+ config->filter.enable_shadow_filter_output_usage);
aec3_config->erle = {
config->erle.min,
config->erle.max_l,
config->erle.max_h,
+ static_cast<bool>(config->erle.onset_detection)
};
aec3_config->ep_strength = {
config->ep_strength.lf,
config->ep_strength.mf,
config->ep_strength.hf,
config->ep_strength.default_len,
+ static_cast<bool>(config->ep_strength.reverb_based_on_render),
static_cast<bool>(config->ep_strength.echo_can_saturate),
static_cast<bool>(config->ep_strength.bounded_erl)
};
+ aec3_config->gain_mask.m0 = config->gain_mask.m0;
aec3_config->gain_mask.m1 = config->gain_mask.m1;
aec3_config->gain_mask.m2 = config->gain_mask.m2;
aec3_config->gain_mask.m3 = config->gain_mask.m3;
@@ -100,49 +120,8 @@
aec3_config->render_levels = {
config->render_levels.active_render_limit,
config->render_levels.poor_excitation_render_limit,
+ config->render_levels.poor_excitation_render_limit_ds8,
};
- aec3_config->gain_updates.low_noise = {
- config->gain_updates.low_noise.max_inc,
- config->gain_updates.low_noise.max_dec,
- config->gain_updates.low_noise.rate_inc,
- config->gain_updates.low_noise.rate_dec,
- config->gain_updates.low_noise.min_inc,
- config->gain_updates.low_noise.min_dec,
- };
- aec3_config->gain_updates.initial = {
- config->gain_updates.initial.max_inc,
- config->gain_updates.initial.max_dec,
- config->gain_updates.initial.rate_inc,
- config->gain_updates.initial.rate_dec,
- config->gain_updates.initial.min_inc,
- config->gain_updates.initial.min_dec,
- };
- aec3_config->gain_updates.normal = {
- config->gain_updates.normal.max_inc,
- config->gain_updates.normal.max_dec,
- config->gain_updates.normal.rate_inc,
- config->gain_updates.normal.rate_dec,
- config->gain_updates.normal.min_inc,
- config->gain_updates.normal.min_dec,
- };
- aec3_config->gain_updates.saturation = {
- config->gain_updates.saturation.max_inc,
- config->gain_updates.saturation.max_dec,
- config->gain_updates.saturation.rate_inc,
- config->gain_updates.saturation.rate_dec,
- config->gain_updates.saturation.min_inc,
- config->gain_updates.saturation.min_dec,
- };
- aec3_config->gain_updates.nonlinear = {
- config->gain_updates.nonlinear.max_inc,
- config->gain_updates.nonlinear.max_dec,
- config->gain_updates.nonlinear.rate_inc,
- config->gain_updates.nonlinear.rate_dec,
- config->gain_updates.nonlinear.min_inc,
- config->gain_updates.nonlinear.min_dec,
- };
- aec3_config->gain_updates.floor_first_increase =
- config->gain_updates.floor_first_increase;
aec3_config->echo_removal_control = {
{
@@ -169,11 +148,69 @@
config->echo_model.render_pre_window_size;
echo_model.render_post_window_size =
config->echo_model.render_post_window_size;
+ echo_model.render_pre_window_size_init =
+ config->echo_model.render_pre_window_size_init;
+ echo_model.render_post_window_size_init =
+ config->echo_model.render_post_window_size_init;
echo_model.nonlinear_hold = config->echo_model.nonlinear_hold;
echo_model.nonlinear_release = config->echo_model.nonlinear_release;
aec3_config->echo_model = echo_model;
+ aec3_config->suppressor.normal_tuning.mask_lf.enr_transparent =
+ config->suppressor.normal_tuning.mask_lf.enr_transparent;
+ aec3_config->suppressor.normal_tuning.mask_lf.enr_suppress =
+ config->suppressor.normal_tuning.mask_lf.enr_suppress;
+ aec3_config->suppressor.normal_tuning.mask_lf.emr_transparent =
+ config->suppressor.normal_tuning.mask_lf.emr_transparent;
+ aec3_config->suppressor.normal_tuning.mask_hf.enr_transparent =
+ config->suppressor.normal_tuning.mask_hf.enr_transparent;
+ aec3_config->suppressor.normal_tuning.mask_hf.enr_suppress =
+ config->suppressor.normal_tuning.mask_hf.enr_suppress;
+ aec3_config->suppressor.normal_tuning.mask_hf.emr_transparent =
+ config->suppressor.normal_tuning.mask_hf.emr_transparent;
+ aec3_config->suppressor.normal_tuning.max_inc_factor =
+ config->suppressor.normal_tuning.max_inc_factor;
+ aec3_config->suppressor.normal_tuning.max_dec_factor_lf =
+ config->suppressor.normal_tuning.max_dec_factor_lf;
+
+ aec3_config->suppressor.nearend_tuning.mask_lf.enr_transparent =
+ config->suppressor.nearend_tuning.mask_lf.enr_transparent;
+ aec3_config->suppressor.nearend_tuning.mask_lf.enr_suppress =
+ config->suppressor.nearend_tuning.mask_lf.enr_suppress;
+ aec3_config->suppressor.nearend_tuning.mask_lf.emr_transparent =
+ config->suppressor.nearend_tuning.mask_lf.emr_transparent;
+ aec3_config->suppressor.nearend_tuning.mask_hf.enr_transparent =
+ config->suppressor.nearend_tuning.mask_hf.enr_transparent;
+ aec3_config->suppressor.nearend_tuning.mask_hf.enr_suppress =
+ config->suppressor.nearend_tuning.mask_hf.enr_suppress,
+ aec3_config->suppressor.nearend_tuning.mask_hf.emr_transparent =
+ config->suppressor.nearend_tuning.mask_hf.emr_transparent;
+ aec3_config->suppressor.nearend_tuning.max_inc_factor =
+ config->suppressor.nearend_tuning.max_inc_factor;
+ aec3_config->suppressor.nearend_tuning.max_dec_factor_lf =
+ config->suppressor.nearend_tuning.max_dec_factor_lf;
+
+ aec3_config->suppressor.dominant_nearend_detection.enr_threshold =
+ config->suppressor.dominant_nearend_detection.enr_threshold;
+ aec3_config->suppressor.dominant_nearend_detection.snr_threshold =
+ config->suppressor.dominant_nearend_detection.snr_threshold;
+ aec3_config->suppressor.dominant_nearend_detection.hold_duration =
+ config->suppressor.dominant_nearend_detection.hold_duration;
+ aec3_config->suppressor.dominant_nearend_detection.trigger_threshold =
+ config->suppressor.dominant_nearend_detection.trigger_threshold;
+
+ aec3_config->suppressor.high_bands_suppression.enr_threshold =
+ config->suppressor.high_bands_suppression.enr_threshold;
+ aec3_config->suppressor.high_bands_suppression.max_gain_during_echo =
+ config->suppressor.high_bands_suppression.max_gain_during_echo;
+
+ aec3_config->suppressor.floor_first_increase =
+ config->suppressor.floor_first_increase;
+ aec3_config->suppressor.enforce_transparent =
+ config->suppressor.enforce_transparent;
+ aec3_config->suppressor.enforce_empty_higher_bands =
+ config->suppressor.enforce_empty_higher_bands;
return 0;
}
diff --git a/webrtc_apm.h b/webrtc_apm.h
index 31761fa..d32060b 100644
--- a/webrtc_apm.h
+++ b/webrtc_apm.h
@@ -27,6 +27,7 @@
size_t hysteresis_limit_1_blocks;
size_t hysteresis_limit_2_blocks;
size_t skew_hysteresis_blocks;
+ size_t fixed_capture_delay_samples;
};
struct MainConfiguration {
@@ -49,12 +50,16 @@
struct MainConfiguration main_initial;
struct ShadowConfiguration shadow_initial;
int config_change_duration_blocks;
+ float initial_state_seconds;
+ int conservative_initial_phase;
+ int enable_shadow_filter_output_usage;
};
struct erle {
float min;
float max_l;
float max_h;
+ int onset_detection;
};
struct ep_strength {
@@ -101,26 +106,6 @@
float poor_excitation_render_limit_ds8;
};
-struct GainChanges {
- float max_inc;
- float max_dec;
- float rate_inc;
- float rate_dec;
- float min_inc;
- float min_dec;
-};
-
-struct gain_updates {
- struct GainChanges low_noise;
- struct GainChanges initial;
- struct GainChanges normal;
- struct GainChanges saturation;
- struct GainChanges nonlinear;
- float max_inc_factor;
- float max_dec_factor_lf;
- float floor_first_increase;
-};
-
struct GainRampup {
float initial_gain;
float first_non_zero_gain;
@@ -148,16 +133,41 @@
float nonlinear_release;
};
+struct masking_thresholds {
+ float enr_transparent;
+ float enr_suppress;
+ float emr_transparent;
+};
+
+struct tuning {
+ struct masking_thresholds mask_lf;
+ struct masking_thresholds mask_hf;
+ float max_inc_factor;
+ float max_dec_factor_lf;
+};
+
+struct dominant_nearend_detection {
+ float enr_threshold;
+ float snr_threshold;
+ int hold_duration;
+ int trigger_threshold;
+};
+
+struct high_bands_suppression {
+ float enr_threshold;
+ float max_gain_during_echo;
+};
+
struct suppressor {
- size_t bands_with_reliable_coherence;
size_t nearend_average_blocks;
- float mask_lf_enr_transparent;
- float mask_lf_enr_suppress;
- float mask_lf_emr_transparent;
- float mask_hf_enr_transparent;
- float mask_hf_enr_suppress;
- float mask_hf_emr_transparent;
- };
+ struct tuning normal_tuning;
+ struct tuning nearend_tuning;
+ struct dominant_nearend_detection dominant_nearend_detection;
+ struct high_bands_suppression high_bands_suppression;
+ float floor_first_increase;
+ int enforce_transparent;
+ int enforce_empty_higher_bands;
+};
struct aec_config {
struct delay delay;
@@ -167,7 +177,6 @@
struct mask gain_mask;
struct echo_audibility echo_audibility;
struct render_levels render_levels;
- struct gain_updates gain_updates;
struct echo_removal_control echo_removal_control;
struct echo_model echo_model;
struct suppressor suppressor;