Merge commit 'upstream-main' into master
Bug: 261600888 Test: none, build files to be updated in follow up cl Change-Id: Ib520938290c6bbdee4a9f73b6419b6c947a96ec4
This commit is contained in:
612
api/BUILD.gn
612
api/BUILD.gn
File diff suppressed because it is too large
Load Diff
109
api/DEPS
109
api/DEPS
@ -11,10 +11,13 @@ include_rules = [
|
||||
"-common_video",
|
||||
"-data",
|
||||
"-examples",
|
||||
"-experiments",
|
||||
"-g3doc",
|
||||
"-ios",
|
||||
"-infra",
|
||||
"-logging",
|
||||
"-media",
|
||||
"-net",
|
||||
"-modules",
|
||||
"-out",
|
||||
"-p2p",
|
||||
@ -40,12 +43,16 @@ include_rules = [
|
||||
|
||||
specific_include_rules = {
|
||||
# Some internal headers are allowed even in API headers:
|
||||
|
||||
"call_factory_interface\.h": [
|
||||
"+call/rtp_transport_controller_send_factory_interface.h",
|
||||
],
|
||||
|
||||
".*\.h": [
|
||||
"+rtc_base/checks.h",
|
||||
"+rtc_base/system/rtc_export.h",
|
||||
"+rtc_base/system/rtc_export_template.h",
|
||||
"+rtc_base/units/unit_base.h",
|
||||
"+rtc_base/deprecation.h",
|
||||
],
|
||||
|
||||
"array_view\.h": [
|
||||
@ -63,6 +70,10 @@ specific_include_rules = {
|
||||
"+rtc_base/async_resolver_interface.h",
|
||||
],
|
||||
|
||||
"async_dns_resolver\.h": [
|
||||
"+rtc_base/socket_address.h",
|
||||
],
|
||||
|
||||
"candidate\.h": [
|
||||
"+rtc_base/network_constants.h",
|
||||
"+rtc_base/socket_address.h",
|
||||
@ -102,14 +113,6 @@ specific_include_rules = {
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"jsep_ice_candidate\.h": [
|
||||
"+rtc_base/constructor_magic.h",
|
||||
],
|
||||
|
||||
"jsep_session_description\.h": [
|
||||
"+rtc_base/constructor_magic.h",
|
||||
],
|
||||
|
||||
"media_stream_interface\.h": [
|
||||
"+modules/audio_processing/include/audio_processing_statistics.h",
|
||||
"+rtc_base/ref_count.h",
|
||||
@ -120,31 +123,31 @@ specific_include_rules = {
|
||||
"+rtc_base/async_packet_socket.h",
|
||||
],
|
||||
|
||||
"peer_connection_factory_proxy\.h": [
|
||||
"+rtc_base/bind.h",
|
||||
],
|
||||
|
||||
"peer_connection_interface\.h": [
|
||||
"+call/rtp_transport_controller_send_factory_interface.h",
|
||||
"+media/base/media_config.h",
|
||||
"+media/base/media_engine.h",
|
||||
"+p2p/base/port.h",
|
||||
"+p2p/base/port_allocator.h",
|
||||
"+rtc_base/network.h",
|
||||
"+rtc_base/network_constants.h",
|
||||
"+rtc_base/network_monitor_factory.h",
|
||||
"+rtc_base/ref_count.h",
|
||||
"+rtc_base/rtc_certificate.h",
|
||||
"+rtc_base/rtc_certificate_generator.h",
|
||||
"+rtc_base/socket_address.h",
|
||||
"+rtc_base/ssl_certificate.h",
|
||||
"+rtc_base/ssl_stream_adapter.h",
|
||||
"+rtc_base/thread.h",
|
||||
],
|
||||
|
||||
"proxy\.h": [
|
||||
"+rtc_base/event.h",
|
||||
"+rtc_base/message_handler.h", # Inherits from it.
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
"+rtc_base/thread.h",
|
||||
],
|
||||
|
||||
"ref_counted_base\.h": [
|
||||
"+rtc_base/constructor_magic.h",
|
||||
"+rtc_base/ref_count.h",
|
||||
"+rtc_base/ref_counter.h",
|
||||
],
|
||||
@ -172,14 +175,15 @@ specific_include_rules = {
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"set_local_description_observer_interface\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
"set_remote_description_observer_interface\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"stats_types\.h": [
|
||||
"+rtc_base/constructor_magic.h",
|
||||
"legacy_stats_types\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
"+rtc_base/string_encode.h",
|
||||
"+rtc_base/thread_checker.h",
|
||||
],
|
||||
|
||||
@ -187,27 +191,18 @@ specific_include_rules = {
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"audio_frame\.h": [
|
||||
"+rtc_base/constructor_magic.h",
|
||||
],
|
||||
|
||||
"audio_mixer\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"audio_decoder\.h": [
|
||||
"+rtc_base/buffer.h",
|
||||
"+rtc_base/constructor_magic.h",
|
||||
],
|
||||
|
||||
"audio_decoder_factory\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"audio_decoder_factory_template\.h": [
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
],
|
||||
|
||||
"audio_encoder\.h": [
|
||||
"+rtc_base/buffer.h",
|
||||
],
|
||||
@ -216,10 +211,6 @@ specific_include_rules = {
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"audio_encoder_factory_template\.h": [
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
],
|
||||
|
||||
"frame_decryptor_interface\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
@ -234,7 +225,6 @@ specific_include_rules = {
|
||||
|
||||
"rtc_stats_report\.h": [
|
||||
"+rtc_base/ref_count.h",
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
],
|
||||
|
||||
"audioproc_float\.h": [
|
||||
@ -245,11 +235,14 @@ specific_include_rules = {
|
||||
"+modules/audio_processing/include/audio_processing.h",
|
||||
],
|
||||
|
||||
"fake_frame_decryptor\.h": [
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
"fake_metronome\.h": [
|
||||
"+rtc_base/synchronization/mutex.h",
|
||||
"+rtc_base/task_queue.h",
|
||||
"+rtc_base/task_utils/repeating_task.h",
|
||||
"+rtc_base/thread_annotations.h",
|
||||
],
|
||||
|
||||
"fake_frame_encryptor\.h": [
|
||||
"make_ref_counted\.h": [
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
],
|
||||
|
||||
@ -257,6 +250,18 @@ specific_include_rules = {
|
||||
"+test/gmock.h",
|
||||
],
|
||||
|
||||
"mock_peerconnectioninterface\.h": [
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
],
|
||||
|
||||
"mock_video_track\.h": [
|
||||
"+rtc_base/ref_counted_object.h",
|
||||
],
|
||||
|
||||
"notifier\.h": [
|
||||
"+rtc_base/system/no_unique_address.h",
|
||||
],
|
||||
|
||||
"simulated_network\.h": [
|
||||
"+rtc_base/random.h",
|
||||
"+rtc_base/thread_annotations.h",
|
||||
@ -278,6 +283,39 @@ specific_include_rules = {
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
"sequence_checker\.h": [
|
||||
"+rtc_base/synchronization/sequence_checker_internal.h",
|
||||
"+rtc_base/thread_annotations.h",
|
||||
],
|
||||
|
||||
"wrapping_async_dns_resolver\.h": [
|
||||
"+rtc_base/async_resolver.h",
|
||||
"+rtc_base/async_resolver_interface.h",
|
||||
"+rtc_base/socket_address.h",
|
||||
"+rtc_base/third_party/sigslot/sigslot.h",
|
||||
"+rtc_base/thread_annotations.h",
|
||||
],
|
||||
|
||||
"video_encoder_factory_template.*\.h": [
|
||||
"+modules/video_coding",
|
||||
],
|
||||
|
||||
"video_decoder_factory_template.*\.h": [
|
||||
"+modules/video_coding",
|
||||
],
|
||||
|
||||
"field_trials\.h": [
|
||||
"+rtc_base/containers/flat_map.h",
|
||||
],
|
||||
|
||||
"video_track_source_proxy_factory.h": [
|
||||
"+rtc_base/thread.h",
|
||||
],
|
||||
|
||||
"field_trials_registry\.h": [
|
||||
"+rtc_base/containers/flat_set.h",
|
||||
],
|
||||
|
||||
# .cc files in api/ should not be restricted in what they can #include,
|
||||
# so we re-add all the top-level directories here. (That's because .h
|
||||
# files leak their #includes to whoever's #including them, but .cc files
|
||||
@ -288,6 +326,7 @@ specific_include_rules = {
|
||||
"+common_audio",
|
||||
"+common_video",
|
||||
"+examples",
|
||||
"+experiments",
|
||||
"+logging",
|
||||
"+media",
|
||||
"+modules",
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
crodbro@webrtc.org
|
||||
deadbeef@webrtc.org
|
||||
hta@webrtc.org
|
||||
juberti@webrtc.org
|
||||
kwiberg@webrtc.org
|
||||
magjed@webrtc.org
|
||||
perkj@webrtc.org
|
||||
tkchin@webrtc.org
|
||||
tommi@webrtc.org
|
||||
|
||||
# For approvals that absolutely must be done on US Pacific time
|
||||
deadbeef@webrtc.org
|
||||
tkchin@webrtc.org
|
||||
|
||||
per-file peer_connection*=hbos@webrtc.org
|
||||
|
||||
per-file DEPS=mbonadei@webrtc.org
|
||||
per-file DEPS=kwiberg@webrtc.org
|
||||
|
||||
per-file uma_metrics.h=kron@webrtc.org
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# How to write code in the `api/` directory
|
||||
|
||||
Mostly, just follow the regular [style guide](../style-guide.md), but:
|
||||
Mostly, just follow the regular [style guide](../g3doc/style-guide.md), but:
|
||||
|
||||
* Note that `api/` code is not exempt from the “`.h` and `.cc` files come in
|
||||
pairs” rule, so if you declare something in `api/path/to/foo.h`, it should be
|
||||
@ -17,7 +17,7 @@ it from a `.cc` file, so that users of our API headers won’t transitively
|
||||
|
||||
For headers in `api/` that need to refer to non-public types, forward
|
||||
declarations are often a lesser evil than including non-public header files. The
|
||||
usual [rules](../style-guide.md#forward-declarations) still apply, though.
|
||||
usual [rules](../g3doc/style-guide.md#forward-declarations) still apply, though.
|
||||
|
||||
`.cc` files in `api/` should preferably be kept reasonably small. If a
|
||||
substantial implementation is needed, consider putting it with our non-public
|
||||
|
||||
@ -16,8 +16,8 @@ rtc_source_set("resource_adaptation_api") {
|
||||
]
|
||||
deps = [
|
||||
"../../api:scoped_refptr",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:refcount",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base/system:rtc_export",
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
specific_include_rules = {
|
||||
"resource\.h": [
|
||||
# ref_count.h is a public_deps of rtc_base_approved. Necessary because of
|
||||
# ref_count.h is a public_deps of rtc_base:refcount. Necessary because of
|
||||
# rtc::RefCountInterface.
|
||||
"+rtc_base/ref_count.h",
|
||||
],
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
|
||||
#include "api/adaptation/resource.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const char* ResourceUsageStateToString(ResourceUsageState usage_state) {
|
||||
@ -19,6 +21,7 @@ const char* ResourceUsageStateToString(ResourceUsageState usage_state) {
|
||||
case ResourceUsageState::kUnderuse:
|
||||
return "kUnderuse";
|
||||
}
|
||||
RTC_CHECK_NOTREACHED();
|
||||
}
|
||||
|
||||
ResourceListener::~ResourceListener() {}
|
||||
|
||||
@ -57,7 +57,7 @@ class RTC_EXPORT Resource : public rtc::RefCountInterface {
|
||||
~Resource() override;
|
||||
|
||||
virtual std::string Name() const = 0;
|
||||
// The |listener| may be informed of resource usage measurements on any task
|
||||
// The `listener` may be informed of resource usage measurements on any task
|
||||
// queue, but not after this method is invoked with the null argument.
|
||||
virtual void SetResourceListener(ResourceListener* listener) = 0;
|
||||
};
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
@ -83,7 +84,7 @@ namespace rtc {
|
||||
// a pointer if fix-sized) and trivially copyable, so it's probably cheaper to
|
||||
// pass it by value than by const reference.
|
||||
|
||||
namespace impl {
|
||||
namespace array_view_internal {
|
||||
|
||||
// Magic constant for indicating that the size of an ArrayView is variable
|
||||
// instead of fixed.
|
||||
@ -124,7 +125,7 @@ class ArrayViewBase<T, 0> {
|
||||
|
||||
// Specialized base class for ArrayViews of variable size.
|
||||
template <typename T>
|
||||
class ArrayViewBase<T, impl::kArrayViewVarSize> {
|
||||
class ArrayViewBase<T, array_view_internal::kArrayViewVarSize> {
|
||||
public:
|
||||
ArrayViewBase(T* data, size_t size)
|
||||
: data_(size == 0 ? nullptr : data), size_(size) {}
|
||||
@ -141,10 +142,11 @@ class ArrayViewBase<T, impl::kArrayViewVarSize> {
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
} // namespace array_view_internal
|
||||
|
||||
template <typename T, std::ptrdiff_t Size = impl::kArrayViewVarSize>
|
||||
class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
template <typename T,
|
||||
std::ptrdiff_t Size = array_view_internal::kArrayViewVarSize>
|
||||
class ArrayView final : public array_view_internal::ArrayViewBase<T, Size> {
|
||||
public:
|
||||
using value_type = T;
|
||||
using const_iterator = const T*;
|
||||
@ -152,7 +154,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
// Construct an ArrayView from a pointer and a length.
|
||||
template <typename U>
|
||||
ArrayView(U* data, size_t size)
|
||||
: impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) {
|
||||
: array_view_internal::ArrayViewBase<T, Size>::ArrayViewBase(data, size) {
|
||||
RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data());
|
||||
RTC_DCHECK_EQ(size, this->size());
|
||||
RTC_DCHECK_EQ(!this->data(),
|
||||
@ -166,7 +168,8 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
: ArrayView() {}
|
||||
ArrayView(std::nullptr_t, size_t size)
|
||||
: ArrayView(static_cast<T*>(nullptr), size) {
|
||||
static_assert(Size == 0 || Size == impl::kArrayViewVarSize, "");
|
||||
static_assert(Size == 0 || Size == array_view_internal::kArrayViewVarSize,
|
||||
"");
|
||||
RTC_DCHECK_EQ(0, size);
|
||||
}
|
||||
|
||||
@ -174,7 +177,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
template <typename U, size_t N>
|
||||
ArrayView(U (&array)[N]) // NOLINT
|
||||
: ArrayView(array, N) {
|
||||
static_assert(Size == N || Size == impl::kArrayViewVarSize,
|
||||
static_assert(Size == N || Size == array_view_internal::kArrayViewVarSize,
|
||||
"Array size must match ArrayView size");
|
||||
}
|
||||
|
||||
@ -207,7 +210,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
// N> when M != N.
|
||||
template <
|
||||
typename U,
|
||||
typename std::enable_if<Size != impl::kArrayViewVarSize &&
|
||||
typename std::enable_if<Size != array_view_internal::kArrayViewVarSize &&
|
||||
HasDataAndSize<U, T>::value>::type* = nullptr>
|
||||
ArrayView(U& u) // NOLINT
|
||||
: ArrayView(u.data(), u.size()) {
|
||||
@ -215,7 +218,7 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
}
|
||||
template <
|
||||
typename U,
|
||||
typename std::enable_if<Size != impl::kArrayViewVarSize &&
|
||||
typename std::enable_if<Size != array_view_internal::kArrayViewVarSize &&
|
||||
HasDataAndSize<U, T>::value>::type* = nullptr>
|
||||
ArrayView(const U& u) // NOLINT(runtime/explicit)
|
||||
: ArrayView(u.data(), u.size()) {
|
||||
@ -235,13 +238,13 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
// const rtc::Buffer to ArrayView<const uint8_t>.
|
||||
template <
|
||||
typename U,
|
||||
typename std::enable_if<Size == impl::kArrayViewVarSize &&
|
||||
typename std::enable_if<Size == array_view_internal::kArrayViewVarSize &&
|
||||
HasDataAndSize<U, T>::value>::type* = nullptr>
|
||||
ArrayView(U& u) // NOLINT
|
||||
: ArrayView(u.data(), u.size()) {}
|
||||
template <
|
||||
typename U,
|
||||
typename std::enable_if<Size == impl::kArrayViewVarSize &&
|
||||
typename std::enable_if<Size == array_view_internal::kArrayViewVarSize &&
|
||||
HasDataAndSize<U, T>::value>::type* = nullptr>
|
||||
ArrayView(const U& u) // NOLINT(runtime/explicit)
|
||||
: ArrayView(u.data(), u.size()) {}
|
||||
@ -258,6 +261,18 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
||||
T* end() const { return this->data() + this->size(); }
|
||||
const T* cbegin() const { return this->data(); }
|
||||
const T* cend() const { return this->data() + this->size(); }
|
||||
std::reverse_iterator<T*> rbegin() const {
|
||||
return std::make_reverse_iterator(end());
|
||||
}
|
||||
std::reverse_iterator<T*> rend() const {
|
||||
return std::make_reverse_iterator(begin());
|
||||
}
|
||||
std::reverse_iterator<const T*> crbegin() const {
|
||||
return std::make_reverse_iterator(cend());
|
||||
}
|
||||
std::reverse_iterator<const T*> crend() const {
|
||||
return std::make_reverse_iterator(cbegin());
|
||||
}
|
||||
|
||||
ArrayView<T> subview(size_t offset, size_t size) const {
|
||||
return offset < this->size()
|
||||
|
||||
@ -451,6 +451,20 @@ TEST(ArrayViewTest, TestIterationEmpty) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArrayViewTest, TestReverseIterationEmpty) {
|
||||
// Variable-size.
|
||||
ArrayView<std::vector<std::vector<std::vector<std::string>>>> av;
|
||||
EXPECT_EQ(av.rbegin(), av.rend());
|
||||
EXPECT_EQ(av.crbegin(), av.crend());
|
||||
EXPECT_TRUE(av.empty());
|
||||
|
||||
// Fixed-size.
|
||||
ArrayView<std::vector<std::vector<std::vector<std::string>>>, 0> af;
|
||||
EXPECT_EQ(af.begin(), af.end());
|
||||
EXPECT_EQ(af.cbegin(), af.cend());
|
||||
EXPECT_TRUE(af.empty());
|
||||
}
|
||||
|
||||
TEST(ArrayViewTest, TestIterationVariable) {
|
||||
char arr[] = "Arrr!";
|
||||
ArrayView<char> av(arr);
|
||||
@ -472,6 +486,25 @@ TEST(ArrayViewTest, TestIterationVariable) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArrayViewTest, TestReverseIterationVariable) {
|
||||
char arr[] = "Arrr!";
|
||||
ArrayView<char> av(arr);
|
||||
EXPECT_EQ('\0', *av.rbegin());
|
||||
EXPECT_EQ('\0', *av.crbegin());
|
||||
EXPECT_EQ('A', *(av.rend() - 1));
|
||||
EXPECT_EQ('A', *(av.crend() - 1));
|
||||
|
||||
const char* cit = av.cend() - 1;
|
||||
for (auto crit = av.crbegin(); crit != av.crend(); ++crit, --cit) {
|
||||
EXPECT_EQ(*cit, *crit);
|
||||
}
|
||||
|
||||
char* it = av.end() - 1;
|
||||
for (auto rit = av.rbegin(); rit != av.rend(); ++rit, --it) {
|
||||
EXPECT_EQ(*it, *rit);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArrayViewTest, TestIterationFixed) {
|
||||
char arr[] = "Arrr!";
|
||||
ArrayView<char, 6> av(arr);
|
||||
@ -493,6 +526,25 @@ TEST(ArrayViewTest, TestIterationFixed) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArrayViewTest, TestReverseIterationFixed) {
|
||||
char arr[] = "Arrr!";
|
||||
ArrayView<char, 6> av(arr);
|
||||
EXPECT_EQ('\0', *av.rbegin());
|
||||
EXPECT_EQ('\0', *av.crbegin());
|
||||
EXPECT_EQ('A', *(av.rend() - 1));
|
||||
EXPECT_EQ('A', *(av.crend() - 1));
|
||||
|
||||
const char* cit = av.cend() - 1;
|
||||
for (auto crit = av.crbegin(); crit != av.crend(); ++crit, --cit) {
|
||||
EXPECT_EQ(*cit, *crit);
|
||||
}
|
||||
|
||||
char* it = av.end() - 1;
|
||||
for (auto rit = av.rbegin(); rit != av.rend(); ++rit, --it) {
|
||||
EXPECT_EQ(*it, *rit);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArrayViewTest, TestEmpty) {
|
||||
EXPECT_TRUE(ArrayView<int>().empty());
|
||||
const int a[] = {1, 2, 3};
|
||||
|
||||
104
api/async_dns_resolver.h
Normal file
104
api/async_dns_resolver.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2021 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_ASYNC_DNS_RESOLVER_H_
|
||||
#define API_ASYNC_DNS_RESOLVER_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/socket_address.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// This interface defines the methods to resolve a hostname asynchronously.
|
||||
// The AsyncDnsResolverInterface class encapsulates a single name query.
|
||||
//
|
||||
// Usage:
|
||||
// std::unique_ptr<AsyncDnsResolverInterface> resolver =
|
||||
// factory->Create(address-to-be-resolved, [r = resolver.get()]() {
|
||||
// if (r->result.GetResolvedAddress(AF_INET, &addr) {
|
||||
// // success
|
||||
// } else {
|
||||
// // failure
|
||||
// error = r->result().GetError();
|
||||
// }
|
||||
// // Release resolver.
|
||||
// resolver_list.erase(std::remove_if(resolver_list.begin(),
|
||||
// resolver_list.end(),
|
||||
// [](refptr) { refptr.get() == r; });
|
||||
// });
|
||||
// resolver_list.push_back(std::move(resolver));
|
||||
|
||||
class AsyncDnsResolverResult {
|
||||
public:
|
||||
virtual ~AsyncDnsResolverResult() = default;
|
||||
// Returns true iff the address from `Start` was successfully resolved.
|
||||
// If the address was successfully resolved, sets `addr` to a copy of the
|
||||
// address from `Start` with the IP address set to the top most resolved
|
||||
// address of `family` (`addr` will have both hostname and the resolved ip).
|
||||
virtual bool GetResolvedAddress(int family,
|
||||
rtc::SocketAddress* addr) const = 0;
|
||||
// Returns error from resolver.
|
||||
virtual int GetError() const = 0;
|
||||
};
|
||||
|
||||
// The API for a single name query.
|
||||
// The constructor, destructor and all functions must be called from
|
||||
// the same sequence, and the callback will also be called on that sequence.
|
||||
// The class guarantees that the callback will not be called if the
|
||||
// resolver's destructor has been called.
|
||||
class RTC_EXPORT AsyncDnsResolverInterface {
|
||||
public:
|
||||
virtual ~AsyncDnsResolverInterface() = default;
|
||||
|
||||
// Start address resolution of the hostname in `addr`.
|
||||
virtual void Start(const rtc::SocketAddress& addr,
|
||||
std::function<void()> callback) = 0;
|
||||
// Start address resolution of the hostname in `addr` matching `family`.
|
||||
virtual void Start(const rtc::SocketAddress& addr,
|
||||
int family,
|
||||
std::function<void()> callback) = 0;
|
||||
virtual const AsyncDnsResolverResult& result() const = 0;
|
||||
};
|
||||
|
||||
// An abstract factory for creating AsyncDnsResolverInterfaces. This allows
|
||||
// client applications to provide WebRTC with their own mechanism for
|
||||
// performing DNS resolution.
|
||||
class AsyncDnsResolverFactoryInterface {
|
||||
public:
|
||||
virtual ~AsyncDnsResolverFactoryInterface() = default;
|
||||
|
||||
// Creates an AsyncDnsResolver and starts resolving the name. The callback
|
||||
// will be called when resolution is finished.
|
||||
// The callback will be called on the sequence that the caller runs on.
|
||||
virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAndResolve(
|
||||
const rtc::SocketAddress& addr,
|
||||
std::function<void()> callback) = 0;
|
||||
// Creates an AsyncDnsResolver and starts resolving the name to an address
|
||||
// matching the specified family. The callback will be called when resolution
|
||||
// is finished. The callback will be called on the sequence that the caller
|
||||
// runs on.
|
||||
virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> CreateAndResolve(
|
||||
const rtc::SocketAddress& addr,
|
||||
int family,
|
||||
std::function<void()> callback) = 0;
|
||||
// Creates an AsyncDnsResolver and does not start it.
|
||||
// For backwards compatibility, will be deprecated and removed.
|
||||
// One has to do a separate Start() call on the
|
||||
// resolver to start name resolution.
|
||||
virtual std::unique_ptr<webrtc::AsyncDnsResolverInterface> Create() = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_ASYNC_DNS_RESOLVER_H_
|
||||
@ -20,17 +20,25 @@ rtc_library("audio_frame_api") {
|
||||
deps = [
|
||||
"..:rtp_packet_info",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:logging",
|
||||
"../../rtc_base:macromagic",
|
||||
"../../rtc_base:timeutils",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_source_set("audio_frame_processor") {
|
||||
visibility = [ "*" ]
|
||||
sources = [ "audio_frame_processor.h" ]
|
||||
}
|
||||
|
||||
rtc_source_set("audio_mixer_api") {
|
||||
visibility = [ "*" ]
|
||||
sources = [ "audio_mixer.h" ]
|
||||
|
||||
deps = [
|
||||
":audio_frame_api",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"..:make_ref_counted",
|
||||
"../../rtc_base:refcount",
|
||||
]
|
||||
}
|
||||
|
||||
@ -42,7 +50,6 @@ rtc_library("aec3_config") {
|
||||
]
|
||||
deps = [
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:safe_minmax",
|
||||
"../../rtc_base/system:rtc_export",
|
||||
]
|
||||
@ -58,8 +65,9 @@ rtc_library("aec3_config_json") {
|
||||
deps = [
|
||||
":aec3_config",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:logging",
|
||||
"../../rtc_base:rtc_json",
|
||||
"../../rtc_base:stringutils",
|
||||
"../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
|
||||
@ -77,7 +85,6 @@ rtc_library("aec3_factory") {
|
||||
":aec3_config",
|
||||
":echo_control",
|
||||
"../../modules/audio_processing/aec3",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base/system:rtc_export",
|
||||
]
|
||||
}
|
||||
@ -90,14 +97,15 @@ rtc_source_set("echo_control") {
|
||||
|
||||
rtc_source_set("echo_detector_creator") {
|
||||
visibility = [ "*" ]
|
||||
allow_poison = [ "default_echo_detector" ]
|
||||
sources = [
|
||||
"echo_detector_creator.cc",
|
||||
"echo_detector_creator.h",
|
||||
]
|
||||
deps = [
|
||||
"..:make_ref_counted",
|
||||
"../../api:scoped_refptr",
|
||||
"../../modules/audio_processing:api",
|
||||
"../../modules/audio_processing:audio_processing",
|
||||
"../../rtc_base:refcount",
|
||||
"../../modules/audio_processing:residual_echo_detector",
|
||||
]
|
||||
}
|
||||
|
||||
@ -11,8 +11,6 @@
|
||||
#include "api/audio/audio_frame.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
@ -24,35 +22,13 @@ AudioFrame::AudioFrame() {
|
||||
static_assert(sizeof(data_) == kMaxDataSizeBytes, "kMaxDataSizeBytes");
|
||||
}
|
||||
|
||||
void swap(AudioFrame& a, AudioFrame& b) {
|
||||
using std::swap;
|
||||
swap(a.timestamp_, b.timestamp_);
|
||||
swap(a.elapsed_time_ms_, b.elapsed_time_ms_);
|
||||
swap(a.ntp_time_ms_, b.ntp_time_ms_);
|
||||
swap(a.samples_per_channel_, b.samples_per_channel_);
|
||||
swap(a.sample_rate_hz_, b.sample_rate_hz_);
|
||||
swap(a.num_channels_, b.num_channels_);
|
||||
swap(a.channel_layout_, b.channel_layout_);
|
||||
swap(a.speech_type_, b.speech_type_);
|
||||
swap(a.vad_activity_, b.vad_activity_);
|
||||
swap(a.profile_timestamp_ms_, b.profile_timestamp_ms_);
|
||||
swap(a.packet_infos_, b.packet_infos_);
|
||||
const size_t length_a = a.samples_per_channel_ * a.num_channels_;
|
||||
const size_t length_b = b.samples_per_channel_ * b.num_channels_;
|
||||
RTC_DCHECK_LE(length_a, AudioFrame::kMaxDataSizeSamples);
|
||||
RTC_DCHECK_LE(length_b, AudioFrame::kMaxDataSizeSamples);
|
||||
std::swap_ranges(a.data_, a.data_ + std::max(length_a, length_b), b.data_);
|
||||
swap(a.muted_, b.muted_);
|
||||
swap(a.absolute_capture_timestamp_ms_, b.absolute_capture_timestamp_ms_);
|
||||
}
|
||||
|
||||
void AudioFrame::Reset() {
|
||||
ResetWithoutMuting();
|
||||
muted_ = true;
|
||||
}
|
||||
|
||||
void AudioFrame::ResetWithoutMuting() {
|
||||
// TODO(wu): Zero is a valid value for |timestamp_|. We should initialize
|
||||
// TODO(wu): Zero is a valid value for `timestamp_`. We should initialize
|
||||
// to an invalid value, or add a new member to indicate invalidity.
|
||||
timestamp_ = 0;
|
||||
elapsed_time_ms_ = -1;
|
||||
|
||||
@ -14,11 +14,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "api/audio/channel_layout.h"
|
||||
#include "api/rtp_packet_infos.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -60,7 +57,8 @@ class AudioFrame {
|
||||
|
||||
AudioFrame();
|
||||
|
||||
friend void swap(AudioFrame& a, AudioFrame& b);
|
||||
AudioFrame(const AudioFrame&) = delete;
|
||||
AudioFrame& operator=(const AudioFrame&) = delete;
|
||||
|
||||
// Resets all members to their default state.
|
||||
void Reset();
|
||||
@ -139,7 +137,7 @@ class AudioFrame {
|
||||
int64_t profile_timestamp_ms_ = 0;
|
||||
|
||||
// Information about packets used to assemble this audio frame. This is needed
|
||||
// by |SourceTracker| when the frame is delivered to the RTCRtpReceiver's
|
||||
// by `SourceTracker` when the frame is delivered to the RTCRtpReceiver's
|
||||
// MediaStreamTrack, in order to implement getContributingSources(). See:
|
||||
// https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-getcontributingsources
|
||||
//
|
||||
@ -149,7 +147,7 @@ class AudioFrame {
|
||||
// sync buffer is the small sample-holding buffer located after the audio
|
||||
// decoder and before where samples are assembled into output frames.
|
||||
//
|
||||
// |RtpPacketInfos| may also be empty if the audio samples did not come from
|
||||
// `RtpPacketInfos` may also be empty if the audio samples did not come from
|
||||
// RTP packets. E.g. if the audio were locally generated by packet loss
|
||||
// concealment, comfort noise generation, etc.
|
||||
RtpPacketInfos packet_infos_;
|
||||
@ -165,11 +163,9 @@ class AudioFrame {
|
||||
|
||||
// Absolute capture timestamp when this audio frame was originally captured.
|
||||
// This is only valid for audio frames captured on this machine. The absolute
|
||||
// capture timestamp of a received frame is found in |packet_infos_|.
|
||||
// capture timestamp of a received frame is found in `packet_infos_`.
|
||||
// This timestamp MUST be based on the same clock as rtc::TimeMillis().
|
||||
absl::optional<int64_t> absolute_capture_timestamp_ms_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioFrame);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
43
api/audio/audio_frame_processor.h
Normal file
43
api/audio/audio_frame_processor.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
|
||||
#define API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class AudioFrame;
|
||||
|
||||
// If passed into PeerConnectionFactory, will be used for additional
|
||||
// processing of captured audio frames, performed before encoding.
|
||||
// Implementations must be thread-safe.
|
||||
class AudioFrameProcessor {
|
||||
public:
|
||||
using OnAudioFrameCallback = std::function<void(std::unique_ptr<AudioFrame>)>;
|
||||
virtual ~AudioFrameProcessor() = default;
|
||||
|
||||
// Processes the frame received from WebRTC, is called by WebRTC off the
|
||||
// realtime audio capturing path. AudioFrameProcessor must reply with
|
||||
// processed frames by calling `sink_callback` if it was provided in SetSink()
|
||||
// call. `sink_callback` can be called in the context of Process().
|
||||
virtual void Process(std::unique_ptr<AudioFrame> frame) = 0;
|
||||
|
||||
// Atomically replaces the current sink with the new one. Before the
|
||||
// first call to this function, or if the provided `sink_callback` is nullptr,
|
||||
// processed frames are simply discarded.
|
||||
virtual void SetSink(OnAudioFrameCallback sink_callback) = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_AUDIO_FRAME_PROCESSOR_H_
|
||||
@ -35,9 +35,9 @@ class AudioMixer : public rtc::RefCountInterface {
|
||||
kError, // The audio_frame will not be used.
|
||||
};
|
||||
|
||||
// Overwrites |audio_frame|. The data_ field is overwritten with
|
||||
// Overwrites `audio_frame`. The data_ field is overwritten with
|
||||
// 10 ms of new audio (either 1 or 2 interleaved channels) at
|
||||
// |sample_rate_hz|. All fields in |audio_frame| must be updated.
|
||||
// `sample_rate_hz`. All fields in `audio_frame` must be updated.
|
||||
virtual AudioFrameInfo GetAudioFrameWithInfo(int sample_rate_hz,
|
||||
AudioFrame* audio_frame) = 0;
|
||||
|
||||
@ -66,7 +66,7 @@ class AudioMixer : public rtc::RefCountInterface {
|
||||
// should mix at a rate that doesn't cause quality loss of the
|
||||
// sources' audio. The mixing rate is one of the rates listed in
|
||||
// AudioProcessing::NativeRate. All fields in
|
||||
// |audio_frame_for_mixing| must be updated.
|
||||
// `audio_frame_for_mixing` must be updated.
|
||||
virtual void Mix(size_t number_of_channels,
|
||||
AudioFrame* audio_frame_for_mixing) = 0;
|
||||
|
||||
|
||||
@ -275,7 +275,7 @@ const char* ChannelLayoutToString(ChannelLayout layout) {
|
||||
case CHANNEL_LAYOUT_BITSTREAM:
|
||||
return "BITSTREAM";
|
||||
}
|
||||
RTC_NOTREACHED() << "Invalid channel layout provided: " << layout;
|
||||
RTC_DCHECK_NOTREACHED() << "Invalid channel layout provided: " << layout;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@ -153,6 +153,7 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
|
||||
|
||||
res = res & Limit(&c->filter.config_change_duration_blocks, 0, 100000);
|
||||
res = res & Limit(&c->filter.initial_state_seconds, 0.f, 100.f);
|
||||
res = res & Limit(&c->filter.coarse_reset_hangover_blocks, 0, 250000);
|
||||
|
||||
res = res & Limit(&c->erle.min, 1.f, 100000.f);
|
||||
res = res & Limit(&c->erle.max_l, 1.f, 100000.f);
|
||||
@ -165,6 +166,7 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
|
||||
|
||||
res = res & Limit(&c->ep_strength.default_gain, 0.f, 1000000.f);
|
||||
res = res & Limit(&c->ep_strength.default_len, -1.f, 1.f);
|
||||
res = res & Limit(&c->ep_strength.nearend_len, -1.0f, 1.0f);
|
||||
|
||||
res =
|
||||
res & Limit(&c->echo_audibility.low_render_limit, 0.f, 32768.f * 32768.f);
|
||||
@ -228,6 +230,12 @@ bool EchoCanceller3Config::Validate(EchoCanceller3Config* config) {
|
||||
res =
|
||||
res & Limit(&c->suppressor.nearend_tuning.max_dec_factor_lf, 0.f, 100.f);
|
||||
|
||||
res = res & Limit(&c->suppressor.last_permanent_lf_smoothing_band, 0, 64);
|
||||
res = res & Limit(&c->suppressor.last_lf_smoothing_band, 0, 64);
|
||||
res = res & Limit(&c->suppressor.last_lf_band, 0, 63);
|
||||
res = res &
|
||||
Limit(&c->suppressor.first_hf_band, c->suppressor.last_lf_band + 1, 64);
|
||||
|
||||
res = res & Limit(&c->suppressor.dominant_nearend_detection.enr_threshold,
|
||||
0.f, 1000000.f);
|
||||
res = res & Limit(&c->suppressor.dominant_nearend_detection.snr_threshold,
|
||||
|
||||
@ -43,6 +43,7 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
size_t hysteresis_limit_blocks = 1;
|
||||
size_t fixed_capture_delay_samples = 0;
|
||||
float delay_estimate_smoothing = 0.7f;
|
||||
float delay_estimate_smoothing_delay_found = 0.7f;
|
||||
float delay_candidate_detection_threshold = 0.2f;
|
||||
struct DelaySelectionThresholds {
|
||||
int initial;
|
||||
@ -58,6 +59,7 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
};
|
||||
AlignmentMixing render_alignment_mixing = {false, true, 10000.f, true};
|
||||
AlignmentMixing capture_alignment_mixing = {false, true, 10000.f, false};
|
||||
bool detect_pre_echo = true;
|
||||
} delay;
|
||||
|
||||
struct Filter {
|
||||
@ -86,9 +88,11 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
|
||||
size_t config_change_duration_blocks = 250;
|
||||
float initial_state_seconds = 2.5f;
|
||||
int coarse_reset_hangover_blocks = 25;
|
||||
bool conservative_initial_phase = false;
|
||||
bool enable_coarse_filter_output_usage = true;
|
||||
bool use_linear_filter = true;
|
||||
bool high_pass_filter_echo_reference = false;
|
||||
bool export_linear_aec_output = false;
|
||||
} filter;
|
||||
|
||||
@ -105,8 +109,11 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
struct EpStrength {
|
||||
float default_gain = 1.f;
|
||||
float default_len = 0.83f;
|
||||
float nearend_len = 0.83f;
|
||||
bool echo_can_saturate = true;
|
||||
bool bounded_erl = false;
|
||||
bool erle_onset_compensation_in_dominant_nearend = false;
|
||||
bool use_conservative_tail_frequency_response = true;
|
||||
} ep_strength;
|
||||
|
||||
struct EchoAudibility {
|
||||
@ -143,6 +150,7 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
float noise_gate_slope = 0.3f;
|
||||
size_t render_pre_window_size = 1;
|
||||
size_t render_post_window_size = 1;
|
||||
bool model_reverb_in_nonlinear_mode = true;
|
||||
} echo_model;
|
||||
|
||||
struct ComfortNoise {
|
||||
@ -189,6 +197,12 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
2.0f,
|
||||
0.25f);
|
||||
|
||||
bool lf_smoothing_during_initial_phase = true;
|
||||
int last_permanent_lf_smoothing_band = 0;
|
||||
int last_lf_smoothing_band = 5;
|
||||
int last_lf_band = 5;
|
||||
int first_hf_band = 8;
|
||||
|
||||
struct DominantNearendDetection {
|
||||
float enr_threshold = .25f;
|
||||
float enr_exit_threshold = 10.f;
|
||||
@ -196,6 +210,7 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
int hold_duration = 50;
|
||||
int trigger_threshold = 12;
|
||||
bool use_during_initial_phase = true;
|
||||
bool use_unbounded_echo_spectrum = true;
|
||||
} dominant_nearend_detection;
|
||||
|
||||
struct SubbandNearendDetection {
|
||||
@ -215,12 +230,20 @@ struct RTC_EXPORT EchoCanceller3Config {
|
||||
struct HighBandsSuppression {
|
||||
float enr_threshold = 1.f;
|
||||
float max_gain_during_echo = 1.f;
|
||||
float anti_howling_activation_threshold = 25.f;
|
||||
float anti_howling_gain = 0.01f;
|
||||
float anti_howling_activation_threshold = 400.f;
|
||||
float anti_howling_gain = 1.f;
|
||||
} high_bands_suppression;
|
||||
|
||||
float floor_first_increase = 0.00001f;
|
||||
bool conservative_hf_suppression = false;
|
||||
} suppressor;
|
||||
|
||||
struct MultiChannel {
|
||||
bool detect_stereo_content = true;
|
||||
float stereo_detection_threshold = 0.0f;
|
||||
int stereo_detection_timeout_threshold_seconds = 300;
|
||||
float stereo_detection_hysteresis_seconds = 2.0f;
|
||||
} multi_channel;
|
||||
};
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -156,9 +157,14 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
*parsing_successful = true;
|
||||
|
||||
Json::Value root;
|
||||
bool success = Json::Reader().parse(std::string(json_string), root);
|
||||
Json::CharReaderBuilder builder;
|
||||
std::string error_message;
|
||||
std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
|
||||
bool success =
|
||||
reader->parse(json_string.data(), json_string.data() + json_string.size(),
|
||||
&root, &error_message);
|
||||
if (!success) {
|
||||
RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << json_string;
|
||||
RTC_LOG(LS_ERROR) << "Incorrect JSON format: " << error_message;
|
||||
*parsing_successful = false;
|
||||
return;
|
||||
}
|
||||
@ -191,6 +197,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
&cfg.delay.fixed_capture_delay_samples);
|
||||
ReadParam(section, "delay_estimate_smoothing",
|
||||
&cfg.delay.delay_estimate_smoothing);
|
||||
ReadParam(section, "delay_estimate_smoothing_delay_found",
|
||||
&cfg.delay.delay_estimate_smoothing_delay_found);
|
||||
ReadParam(section, "delay_candidate_detection_threshold",
|
||||
&cfg.delay.delay_candidate_detection_threshold);
|
||||
|
||||
@ -212,6 +220,7 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
&cfg.delay.render_alignment_mixing);
|
||||
ReadParam(section, "capture_alignment_mixing",
|
||||
&cfg.delay.capture_alignment_mixing);
|
||||
ReadParam(section, "detect_pre_echo", &cfg.delay.detect_pre_echo);
|
||||
}
|
||||
|
||||
if (rtc::GetValueFromJsonObject(aec3_root, "filter", §ion)) {
|
||||
@ -223,11 +232,15 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
&cfg.filter.config_change_duration_blocks);
|
||||
ReadParam(section, "initial_state_seconds",
|
||||
&cfg.filter.initial_state_seconds);
|
||||
ReadParam(section, "coarse_reset_hangover_blocks",
|
||||
&cfg.filter.coarse_reset_hangover_blocks);
|
||||
ReadParam(section, "conservative_initial_phase",
|
||||
&cfg.filter.conservative_initial_phase);
|
||||
ReadParam(section, "enable_coarse_filter_output_usage",
|
||||
&cfg.filter.enable_coarse_filter_output_usage);
|
||||
ReadParam(section, "use_linear_filter", &cfg.filter.use_linear_filter);
|
||||
ReadParam(section, "high_pass_filter_echo_reference",
|
||||
&cfg.filter.high_pass_filter_echo_reference);
|
||||
ReadParam(section, "export_linear_aec_output",
|
||||
&cfg.filter.export_linear_aec_output);
|
||||
}
|
||||
@ -247,8 +260,13 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
if (rtc::GetValueFromJsonObject(aec3_root, "ep_strength", §ion)) {
|
||||
ReadParam(section, "default_gain", &cfg.ep_strength.default_gain);
|
||||
ReadParam(section, "default_len", &cfg.ep_strength.default_len);
|
||||
ReadParam(section, "nearend_len", &cfg.ep_strength.nearend_len);
|
||||
ReadParam(section, "echo_can_saturate", &cfg.ep_strength.echo_can_saturate);
|
||||
ReadParam(section, "bounded_erl", &cfg.ep_strength.bounded_erl);
|
||||
ReadParam(section, "erle_onset_compensation_in_dominant_nearend",
|
||||
&cfg.ep_strength.erle_onset_compensation_in_dominant_nearend);
|
||||
ReadParam(section, "use_conservative_tail_frequency_response",
|
||||
&cfg.ep_strength.use_conservative_tail_frequency_response);
|
||||
}
|
||||
|
||||
if (rtc::GetValueFromJsonObject(aec3_root, "echo_audibility", §ion)) {
|
||||
@ -302,6 +320,8 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
&cfg.echo_model.render_pre_window_size);
|
||||
ReadParam(section, "render_post_window_size",
|
||||
&cfg.echo_model.render_post_window_size);
|
||||
ReadParam(section, "model_reverb_in_nonlinear_mode",
|
||||
&cfg.echo_model.model_reverb_in_nonlinear_mode);
|
||||
}
|
||||
|
||||
if (rtc::GetValueFromJsonObject(aec3_root, "comfort_noise", §ion)) {
|
||||
@ -331,6 +351,15 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
&cfg.suppressor.nearend_tuning.max_dec_factor_lf);
|
||||
}
|
||||
|
||||
ReadParam(section, "lf_smoothing_during_initial_phase",
|
||||
&cfg.suppressor.lf_smoothing_during_initial_phase);
|
||||
ReadParam(section, "last_permanent_lf_smoothing_band",
|
||||
&cfg.suppressor.last_permanent_lf_smoothing_band);
|
||||
ReadParam(section, "last_lf_smoothing_band",
|
||||
&cfg.suppressor.last_lf_smoothing_band);
|
||||
ReadParam(section, "last_lf_band", &cfg.suppressor.last_lf_band);
|
||||
ReadParam(section, "first_hf_band", &cfg.suppressor.first_hf_band);
|
||||
|
||||
if (rtc::GetValueFromJsonObject(section, "dominant_nearend_detection",
|
||||
&subsection)) {
|
||||
ReadParam(subsection, "enr_threshold",
|
||||
@ -346,6 +375,9 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
ReadParam(
|
||||
subsection, "use_during_initial_phase",
|
||||
&cfg.suppressor.dominant_nearend_detection.use_during_initial_phase);
|
||||
ReadParam(subsection, "use_unbounded_echo_spectrum",
|
||||
&cfg.suppressor.dominant_nearend_detection
|
||||
.use_unbounded_echo_spectrum);
|
||||
}
|
||||
|
||||
if (rtc::GetValueFromJsonObject(section, "subband_nearend_detection",
|
||||
@ -381,6 +413,19 @@ void Aec3ConfigFromJsonString(absl::string_view json_string,
|
||||
|
||||
ReadParam(section, "floor_first_increase",
|
||||
&cfg.suppressor.floor_first_increase);
|
||||
ReadParam(section, "conservative_hf_suppression",
|
||||
&cfg.suppressor.conservative_hf_suppression);
|
||||
}
|
||||
|
||||
if (rtc::GetValueFromJsonObject(aec3_root, "multi_channel", §ion)) {
|
||||
ReadParam(section, "detect_stereo_content",
|
||||
&cfg.multi_channel.detect_stereo_content);
|
||||
ReadParam(section, "stereo_detection_threshold",
|
||||
&cfg.multi_channel.stereo_detection_threshold);
|
||||
ReadParam(section, "stereo_detection_timeout_threshold_seconds",
|
||||
&cfg.multi_channel.stereo_detection_timeout_threshold_seconds);
|
||||
ReadParam(section, "stereo_detection_hysteresis_seconds",
|
||||
&cfg.multi_channel.stereo_detection_hysteresis_seconds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,6 +460,8 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
<< config.delay.fixed_capture_delay_samples << ",";
|
||||
ost << "\"delay_estimate_smoothing\": "
|
||||
<< config.delay.delay_estimate_smoothing << ",";
|
||||
ost << "\"delay_estimate_smoothing_delay_found\": "
|
||||
<< config.delay.delay_estimate_smoothing_delay_found << ",";
|
||||
ost << "\"delay_candidate_detection_threshold\": "
|
||||
<< config.delay.delay_candidate_detection_threshold << ",";
|
||||
|
||||
@ -459,7 +506,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
<< (config.delay.capture_alignment_mixing.prefer_first_two_channels
|
||||
? "true"
|
||||
: "false");
|
||||
ost << "}";
|
||||
ost << "},";
|
||||
ost << "\"detect_pre_echo\": "
|
||||
<< (config.delay.detect_pre_echo ? "true" : "false");
|
||||
ost << "},";
|
||||
|
||||
ost << "\"filter\": {";
|
||||
@ -498,6 +547,8 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
<< config.filter.config_change_duration_blocks << ",";
|
||||
ost << "\"initial_state_seconds\": " << config.filter.initial_state_seconds
|
||||
<< ",";
|
||||
ost << "\"coarse_reset_hangover_blocks\": "
|
||||
<< config.filter.coarse_reset_hangover_blocks << ",";
|
||||
ost << "\"conservative_initial_phase\": "
|
||||
<< (config.filter.conservative_initial_phase ? "true" : "false") << ",";
|
||||
ost << "\"enable_coarse_filter_output_usage\": "
|
||||
@ -505,6 +556,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
<< ",";
|
||||
ost << "\"use_linear_filter\": "
|
||||
<< (config.filter.use_linear_filter ? "true" : "false") << ",";
|
||||
ost << "\"high_pass_filter_echo_reference\": "
|
||||
<< (config.filter.high_pass_filter_echo_reference ? "true" : "false")
|
||||
<< ",";
|
||||
ost << "\"export_linear_aec_output\": "
|
||||
<< (config.filter.export_linear_aec_output ? "true" : "false");
|
||||
|
||||
@ -526,11 +580,20 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
ost << "\"ep_strength\": {";
|
||||
ost << "\"default_gain\": " << config.ep_strength.default_gain << ",";
|
||||
ost << "\"default_len\": " << config.ep_strength.default_len << ",";
|
||||
ost << "\"nearend_len\": " << config.ep_strength.nearend_len << ",";
|
||||
ost << "\"echo_can_saturate\": "
|
||||
<< (config.ep_strength.echo_can_saturate ? "true" : "false") << ",";
|
||||
ost << "\"bounded_erl\": "
|
||||
<< (config.ep_strength.bounded_erl ? "true" : "false");
|
||||
|
||||
<< (config.ep_strength.bounded_erl ? "true" : "false") << ",";
|
||||
ost << "\"erle_onset_compensation_in_dominant_nearend\": "
|
||||
<< (config.ep_strength.erle_onset_compensation_in_dominant_nearend
|
||||
? "true"
|
||||
: "false")
|
||||
<< ",";
|
||||
ost << "\"use_conservative_tail_frequency_response\": "
|
||||
<< (config.ep_strength.use_conservative_tail_frequency_response
|
||||
? "true"
|
||||
: "false");
|
||||
ost << "},";
|
||||
|
||||
ost << "\"echo_audibility\": {";
|
||||
@ -585,7 +648,9 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
ost << "\"render_pre_window_size\": "
|
||||
<< config.echo_model.render_pre_window_size << ",";
|
||||
ost << "\"render_post_window_size\": "
|
||||
<< config.echo_model.render_post_window_size;
|
||||
<< config.echo_model.render_post_window_size << ",";
|
||||
ost << "\"model_reverb_in_nonlinear_mode\": "
|
||||
<< (config.echo_model.model_reverb_in_nonlinear_mode ? "true" : "false");
|
||||
ost << "},";
|
||||
|
||||
ost << "\"comfort_noise\": {";
|
||||
@ -627,20 +692,30 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
ost << "\"max_dec_factor_lf\": "
|
||||
<< config.suppressor.nearend_tuning.max_dec_factor_lf;
|
||||
ost << "},";
|
||||
ost << "\"dominant_nearend_detection\": {";
|
||||
ost << "\"enr_threshold\": "
|
||||
<< config.suppressor.dominant_nearend_detection.enr_threshold << ",";
|
||||
ost << "\"enr_exit_threshold\": "
|
||||
<< config.suppressor.dominant_nearend_detection.enr_exit_threshold << ",";
|
||||
ost << "\"snr_threshold\": "
|
||||
<< config.suppressor.dominant_nearend_detection.snr_threshold << ",";
|
||||
ost << "\"hold_duration\": "
|
||||
<< config.suppressor.dominant_nearend_detection.hold_duration << ",";
|
||||
ost << "\"trigger_threshold\": "
|
||||
<< config.suppressor.dominant_nearend_detection.trigger_threshold << ",";
|
||||
ost << "\"use_during_initial_phase\": "
|
||||
<< config.suppressor.dominant_nearend_detection.use_during_initial_phase;
|
||||
ost << "},";
|
||||
ost << "\"lf_smoothing_during_initial_phase\": "
|
||||
<< (config.suppressor.lf_smoothing_during_initial_phase ? "true"
|
||||
: "false")
|
||||
<< ",";
|
||||
ost << "\"last_permanent_lf_smoothing_band\": "
|
||||
<< config.suppressor.last_permanent_lf_smoothing_band << ",";
|
||||
ost << "\"last_lf_smoothing_band\": "
|
||||
<< config.suppressor.last_lf_smoothing_band << ",";
|
||||
ost << "\"last_lf_band\": " << config.suppressor.last_lf_band << ",";
|
||||
ost << "\"first_hf_band\": " << config.suppressor.first_hf_band << ",";
|
||||
{
|
||||
const auto& dnd = config.suppressor.dominant_nearend_detection;
|
||||
ost << "\"dominant_nearend_detection\": {";
|
||||
ost << "\"enr_threshold\": " << dnd.enr_threshold << ",";
|
||||
ost << "\"enr_exit_threshold\": " << dnd.enr_exit_threshold << ",";
|
||||
ost << "\"snr_threshold\": " << dnd.snr_threshold << ",";
|
||||
ost << "\"hold_duration\": " << dnd.hold_duration << ",";
|
||||
ost << "\"trigger_threshold\": " << dnd.trigger_threshold << ",";
|
||||
ost << "\"use_during_initial_phase\": " << dnd.use_during_initial_phase
|
||||
<< ",";
|
||||
ost << "\"use_unbounded_echo_spectrum\": "
|
||||
<< dnd.use_unbounded_echo_spectrum;
|
||||
ost << "},";
|
||||
}
|
||||
ost << "\"subband_nearend_detection\": {";
|
||||
ost << "\"nearend_average_blocks\": "
|
||||
<< config.suppressor.subband_nearend_detection.nearend_average_blocks
|
||||
@ -672,8 +747,23 @@ std::string Aec3ConfigToJsonString(const EchoCanceller3Config& config) {
|
||||
ost << "\"anti_howling_gain\": "
|
||||
<< config.suppressor.high_bands_suppression.anti_howling_gain;
|
||||
ost << "},";
|
||||
ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase;
|
||||
ost << "\"floor_first_increase\": " << config.suppressor.floor_first_increase
|
||||
<< ",";
|
||||
ost << "\"conservative_hf_suppression\": "
|
||||
<< config.suppressor.conservative_hf_suppression;
|
||||
ost << "},";
|
||||
|
||||
ost << "\"multi_channel\": {";
|
||||
ost << "\"detect_stereo_content\": "
|
||||
<< (config.multi_channel.detect_stereo_content ? "true" : "false") << ",";
|
||||
ost << "\"stereo_detection_threshold\": "
|
||||
<< config.multi_channel.stereo_detection_threshold << ",";
|
||||
ost << "\"stereo_detection_timeout_threshold_seconds\": "
|
||||
<< config.multi_channel.stereo_detection_timeout_threshold_seconds << ",";
|
||||
ost << "\"stereo_detection_hysteresis_seconds\": "
|
||||
<< config.multi_channel.stereo_detection_hysteresis_seconds;
|
||||
ost << "}";
|
||||
|
||||
ost << "}";
|
||||
ost << "}";
|
||||
|
||||
|
||||
@ -25,7 +25,8 @@ std::unique_ptr<EchoControl> EchoCanceller3Factory::Create(
|
||||
int num_render_channels,
|
||||
int num_capture_channels) {
|
||||
return std::make_unique<EchoCanceller3>(
|
||||
config_, sample_rate_hz, num_render_channels, num_capture_channels);
|
||||
config_, /*multichannel_config=*/absl::nullopt, sample_rate_hz,
|
||||
num_render_channels, num_capture_channels);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -48,6 +48,13 @@ class EchoControl {
|
||||
// Provides an optional external estimate of the audio buffer delay.
|
||||
virtual void SetAudioBufferDelay(int delay_ms) = 0;
|
||||
|
||||
// Specifies whether the capture output will be used. The purpose of this is
|
||||
// to allow the echo controller to deactivate some of the processing when the
|
||||
// resulting output is anyway not used, for instance when the endpoint is
|
||||
// muted.
|
||||
// TODO(b/177830919): Make pure virtual.
|
||||
virtual void SetCaptureOutputUsage(bool capture_output_used) {}
|
||||
|
||||
// Returns wheter the signal is altered.
|
||||
virtual bool ActiveProcessing() const = 0;
|
||||
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
*/
|
||||
#include "api/audio/echo_detector_creator.h"
|
||||
|
||||
#include "api/make_ref_counted.h"
|
||||
#include "modules/audio_processing/residual_echo_detector.h"
|
||||
#include "rtc_base/ref_counted_object.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
rtc::scoped_refptr<EchoDetector> CreateEchoDetector() {
|
||||
return new rtc::RefCountedObject<ResidualEchoDetector>();
|
||||
return rtc::make_ref_counted<ResidualEchoDetector>();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -24,7 +24,6 @@ if (rtc_include_tests) {
|
||||
"..:aec3_config",
|
||||
"..:aec3_config_json",
|
||||
"..:audio_frame_api",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../test:test_support",
|
||||
]
|
||||
}
|
||||
|
||||
@ -133,54 +133,4 @@ TEST(AudioFrameTest, CopyFrom) {
|
||||
EXPECT_EQ(0, memcmp(frame2.data(), frame1.data(), sizeof(samples)));
|
||||
}
|
||||
|
||||
TEST(AudioFrameTest, SwapFrames) {
|
||||
AudioFrame frame1, frame2;
|
||||
int16_t samples1[kNumChannelsMono * kSamplesPerChannel];
|
||||
for (size_t i = 0; i < kNumChannelsMono * kSamplesPerChannel; ++i) {
|
||||
samples1[i] = i;
|
||||
}
|
||||
frame1.UpdateFrame(kTimestamp, samples1, kSamplesPerChannel, kSampleRateHz,
|
||||
AudioFrame::kPLC, AudioFrame::kVadActive,
|
||||
kNumChannelsMono);
|
||||
frame1.set_absolute_capture_timestamp_ms(12345678);
|
||||
const auto frame1_channel_layout = frame1.channel_layout();
|
||||
|
||||
int16_t samples2[(kNumChannelsMono + 1) * (kSamplesPerChannel + 1)];
|
||||
for (size_t i = 0; i < (kNumChannelsMono + 1) * (kSamplesPerChannel + 1);
|
||||
++i) {
|
||||
samples2[i] = 1000 + i;
|
||||
}
|
||||
frame2.UpdateFrame(kTimestamp + 1, samples2, kSamplesPerChannel + 1,
|
||||
kSampleRateHz + 1, AudioFrame::kNormalSpeech,
|
||||
AudioFrame::kVadPassive, kNumChannelsMono + 1);
|
||||
const auto frame2_channel_layout = frame2.channel_layout();
|
||||
|
||||
swap(frame1, frame2);
|
||||
|
||||
EXPECT_EQ(kTimestamp + 1, frame1.timestamp_);
|
||||
ASSERT_EQ(kSamplesPerChannel + 1, frame1.samples_per_channel_);
|
||||
EXPECT_EQ(kSampleRateHz + 1, frame1.sample_rate_hz_);
|
||||
EXPECT_EQ(AudioFrame::kNormalSpeech, frame1.speech_type_);
|
||||
EXPECT_EQ(AudioFrame::kVadPassive, frame1.vad_activity_);
|
||||
ASSERT_EQ(kNumChannelsMono + 1, frame1.num_channels_);
|
||||
for (size_t i = 0; i < (kNumChannelsMono + 1) * (kSamplesPerChannel + 1);
|
||||
++i) {
|
||||
EXPECT_EQ(samples2[i], frame1.data()[i]);
|
||||
}
|
||||
EXPECT_FALSE(frame1.absolute_capture_timestamp_ms());
|
||||
EXPECT_EQ(frame2_channel_layout, frame1.channel_layout());
|
||||
|
||||
EXPECT_EQ(kTimestamp, frame2.timestamp_);
|
||||
ASSERT_EQ(kSamplesPerChannel, frame2.samples_per_channel_);
|
||||
EXPECT_EQ(kSampleRateHz, frame2.sample_rate_hz_);
|
||||
EXPECT_EQ(AudioFrame::kPLC, frame2.speech_type_);
|
||||
EXPECT_EQ(AudioFrame::kVadActive, frame2.vad_activity_);
|
||||
ASSERT_EQ(kNumChannelsMono, frame2.num_channels_);
|
||||
for (size_t i = 0; i < kNumChannelsMono * kSamplesPerChannel; ++i) {
|
||||
EXPECT_EQ(samples1[i], frame2.data()[i]);
|
||||
}
|
||||
EXPECT_EQ(12345678, frame2.absolute_capture_timestamp_ms());
|
||||
EXPECT_EQ(frame1_channel_layout, frame2.channel_layout());
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -21,19 +21,29 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
|
||||
cfg.delay.log_warning_on_delay_changes = true;
|
||||
cfg.filter.refined.error_floor = 2.f;
|
||||
cfg.filter.coarse_initial.length_blocks = 3u;
|
||||
cfg.filter.high_pass_filter_echo_reference =
|
||||
!cfg.filter.high_pass_filter_echo_reference;
|
||||
cfg.comfort_noise.noise_floor_dbfs = 100.f;
|
||||
cfg.echo_model.model_reverb_in_nonlinear_mode = false;
|
||||
cfg.suppressor.normal_tuning.mask_hf.enr_suppress = .5f;
|
||||
cfg.suppressor.subband_nearend_detection.nearend_average_blocks = 3;
|
||||
cfg.suppressor.subband_nearend_detection.subband1 = {1, 3};
|
||||
cfg.suppressor.subband_nearend_detection.subband1 = {4, 5};
|
||||
cfg.suppressor.subband_nearend_detection.nearend_threshold = 2.f;
|
||||
cfg.suppressor.subband_nearend_detection.snr_threshold = 100.f;
|
||||
cfg.multi_channel.detect_stereo_content =
|
||||
!cfg.multi_channel.detect_stereo_content;
|
||||
cfg.multi_channel.stereo_detection_threshold += 1.0f;
|
||||
cfg.multi_channel.stereo_detection_timeout_threshold_seconds += 1;
|
||||
cfg.multi_channel.stereo_detection_hysteresis_seconds += 1;
|
||||
std::string json_string = Aec3ConfigToJsonString(cfg);
|
||||
EchoCanceller3Config cfg_transformed = Aec3ConfigFromJsonString(json_string);
|
||||
|
||||
// Expect unchanged values to remain default.
|
||||
EXPECT_EQ(cfg.ep_strength.default_len,
|
||||
cfg_transformed.ep_strength.default_len);
|
||||
EXPECT_EQ(cfg.ep_strength.nearend_len,
|
||||
cfg_transformed.ep_strength.nearend_len);
|
||||
EXPECT_EQ(cfg.suppressor.normal_tuning.mask_lf.enr_suppress,
|
||||
cfg_transformed.suppressor.normal_tuning.mask_lf.enr_suppress);
|
||||
|
||||
@ -46,8 +56,12 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
|
||||
cfg_transformed.filter.coarse_initial.length_blocks);
|
||||
EXPECT_EQ(cfg.filter.refined.error_floor,
|
||||
cfg_transformed.filter.refined.error_floor);
|
||||
EXPECT_EQ(cfg.filter.high_pass_filter_echo_reference,
|
||||
cfg_transformed.filter.high_pass_filter_echo_reference);
|
||||
EXPECT_EQ(cfg.comfort_noise.noise_floor_dbfs,
|
||||
cfg_transformed.comfort_noise.noise_floor_dbfs);
|
||||
EXPECT_EQ(cfg.echo_model.model_reverb_in_nonlinear_mode,
|
||||
cfg_transformed.echo_model.model_reverb_in_nonlinear_mode);
|
||||
EXPECT_EQ(cfg.suppressor.normal_tuning.mask_hf.enr_suppress,
|
||||
cfg_transformed.suppressor.normal_tuning.mask_hf.enr_suppress);
|
||||
EXPECT_EQ(cfg.suppressor.subband_nearend_detection.nearend_average_blocks,
|
||||
@ -66,5 +80,14 @@ TEST(EchoCanceller3JsonHelpers, ToStringAndParseJson) {
|
||||
cfg_transformed.suppressor.subband_nearend_detection.nearend_threshold);
|
||||
EXPECT_EQ(cfg.suppressor.subband_nearend_detection.snr_threshold,
|
||||
cfg_transformed.suppressor.subband_nearend_detection.snr_threshold);
|
||||
EXPECT_EQ(cfg.multi_channel.detect_stereo_content,
|
||||
cfg_transformed.multi_channel.detect_stereo_content);
|
||||
EXPECT_EQ(cfg.multi_channel.stereo_detection_threshold,
|
||||
cfg_transformed.multi_channel.stereo_detection_threshold);
|
||||
EXPECT_EQ(
|
||||
cfg.multi_channel.stereo_detection_timeout_threshold_seconds,
|
||||
cfg_transformed.multi_channel.stereo_detection_timeout_threshold_seconds);
|
||||
EXPECT_EQ(cfg.multi_channel.stereo_detection_hysteresis_seconds,
|
||||
cfg_transformed.multi_channel.stereo_detection_hysteresis_seconds);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -31,15 +31,19 @@ rtc_library("audio_codecs_api") {
|
||||
deps = [
|
||||
"..:array_view",
|
||||
"..:bitrate_allocation",
|
||||
"..:make_ref_counted",
|
||||
"..:scoped_refptr",
|
||||
"../../api:field_trials_view",
|
||||
"../../rtc_base:buffer",
|
||||
"../../rtc_base:checks",
|
||||
"../../rtc_base:deprecation",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../rtc_base:event_tracer",
|
||||
"../../rtc_base:refcount",
|
||||
"../../rtc_base:sanitizer",
|
||||
"../../rtc_base/system:rtc_export",
|
||||
"../units:time_delta",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/base:core_headers",
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
@ -55,11 +59,9 @@ rtc_library("builtin_audio_decoder_factory") {
|
||||
deps = [
|
||||
":audio_codecs_api",
|
||||
"..:scoped_refptr",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"L16:audio_decoder_L16",
|
||||
"g711:audio_decoder_g711",
|
||||
"g722:audio_decoder_g722",
|
||||
"isac:audio_decoder_isac",
|
||||
]
|
||||
defines = []
|
||||
if (rtc_include_ilbc) {
|
||||
@ -89,11 +91,9 @@ rtc_library("builtin_audio_encoder_factory") {
|
||||
deps = [
|
||||
":audio_codecs_api",
|
||||
"..:scoped_refptr",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"L16:audio_encoder_L16",
|
||||
"g711:audio_encoder_g711",
|
||||
"g722:audio_encoder_g722",
|
||||
"isac:audio_encoder_isac",
|
||||
]
|
||||
defines = []
|
||||
if (rtc_include_ilbc) {
|
||||
@ -123,7 +123,6 @@ rtc_library("opus_audio_decoder_factory") {
|
||||
deps = [
|
||||
":audio_codecs_api",
|
||||
"..:scoped_refptr",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"opus:audio_decoder_multiopus",
|
||||
"opus:audio_decoder_opus",
|
||||
]
|
||||
@ -139,7 +138,6 @@ rtc_library("opus_audio_encoder_factory") {
|
||||
deps = [
|
||||
":audio_codecs_api",
|
||||
"..:scoped_refptr",
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"opus:audio_encoder_multiopus",
|
||||
"opus:audio_encoder_opus",
|
||||
]
|
||||
|
||||
@ -21,9 +21,11 @@ rtc_library("audio_encoder_L16") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:pcm16b",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base:safe_minmax",
|
||||
"../../../rtc_base:stringutils",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
@ -41,8 +43,9 @@ rtc_library("audio_decoder_L16") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:pcm16b",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
|
||||
@ -24,9 +24,10 @@ absl::optional<AudioDecoderL16::Config> AudioDecoderL16::SdpToConfig(
|
||||
Config config;
|
||||
config.sample_rate_hz = format.clockrate_hz;
|
||||
config.num_channels = rtc::checked_cast<int>(format.num_channels);
|
||||
return absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()
|
||||
? absl::optional<Config>(config)
|
||||
: absl::nullopt;
|
||||
if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
|
||||
return config;
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
void AudioDecoderL16::AppendSupportedDecoders(
|
||||
@ -36,10 +37,13 @@ void AudioDecoderL16::AppendSupportedDecoders(
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderL16::MakeAudioDecoder(
|
||||
const Config& config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
return config.IsOk() ? std::make_unique<AudioDecoderPcm16B>(
|
||||
config.sample_rate_hz, config.num_channels)
|
||||
: nullptr;
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<AudioDecoderPcm16B>(config.sample_rate_hz,
|
||||
config.num_channels);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -29,7 +30,8 @@ struct RTC_EXPORT AudioDecoderL16 {
|
||||
bool IsOk() const {
|
||||
return (sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
|
||||
sample_rate_hz == 32000 || sample_rate_hz == 48000) &&
|
||||
num_channels >= 1;
|
||||
(num_channels >= 1 &&
|
||||
num_channels <= AudioDecoder::kMaxNumberOfChannels);
|
||||
}
|
||||
int sample_rate_hz = 8000;
|
||||
int num_channels = 1;
|
||||
@ -38,7 +40,8 @@ struct RTC_EXPORT AudioDecoderL16 {
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const Config& config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -24,6 +24,7 @@ namespace webrtc {
|
||||
absl::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
|
||||
const SdpAudioFormat& format) {
|
||||
if (!rtc::IsValueInRangeForNumericType<int>(format.num_channels)) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return absl::nullopt;
|
||||
}
|
||||
Config config;
|
||||
@ -36,9 +37,10 @@ absl::optional<AudioEncoderL16::Config> AudioEncoderL16::SdpToConfig(
|
||||
config.frame_size_ms = rtc::SafeClamp(10 * (*ptime / 10), 10, 60);
|
||||
}
|
||||
}
|
||||
return absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()
|
||||
? absl::optional<Config>(config)
|
||||
: absl::nullopt;
|
||||
if (absl::EqualsIgnoreCase(format.name, "L16") && config.IsOk()) {
|
||||
return config;
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
void AudioEncoderL16::AppendSupportedEncoders(
|
||||
@ -57,13 +59,17 @@ AudioCodecInfo AudioEncoderL16::QueryAudioEncoder(
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderL16::MakeAudioEncoder(
|
||||
const AudioEncoderL16::Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
AudioEncoderPcm16B::Config c;
|
||||
c.sample_rate_hz = config.sample_rate_hz;
|
||||
c.num_channels = config.num_channels;
|
||||
c.frame_size_ms = config.frame_size_ms;
|
||||
c.payload_type = payload_type;
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<AudioEncoderPcm16B>(c);
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -29,7 +30,9 @@ struct RTC_EXPORT AudioEncoderL16 {
|
||||
bool IsOk() const {
|
||||
return (sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
|
||||
sample_rate_hz == 32000 || sample_rate_hz == 48000) &&
|
||||
num_channels >= 1 && frame_size_ms > 0 && frame_size_ms <= 120 &&
|
||||
num_channels >= 1 &&
|
||||
num_channels <= AudioEncoder::kMaxNumberOfChannels &&
|
||||
frame_size_ms > 0 && frame_size_ms <= 120 &&
|
||||
frame_size_ms % 10 == 0;
|
||||
}
|
||||
int sample_rate_hz = 8000;
|
||||
@ -42,7 +45,8 @@ struct RTC_EXPORT AudioEncoderL16 {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -1 +1,3 @@
|
||||
kwiberg@webrtc.org
|
||||
alessiob@webrtc.org
|
||||
henrik.lundin@webrtc.org
|
||||
jakobi@webrtc.org
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
@ -162,9 +161,10 @@ AudioDecoder::SpeechType AudioDecoder::ConvertSpeechType(int16_t type) {
|
||||
case 2:
|
||||
return kComfortNoise;
|
||||
default:
|
||||
assert(false);
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return kSpeech;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int AudioDecoder::kMaxNumberOfChannels;
|
||||
} // namespace webrtc
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
#include "rtc_base/constructor_magic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -37,6 +36,9 @@ class AudioDecoder {
|
||||
AudioDecoder() = default;
|
||||
virtual ~AudioDecoder() = default;
|
||||
|
||||
AudioDecoder(const AudioDecoder&) = delete;
|
||||
AudioDecoder& operator=(const AudioDecoder&) = delete;
|
||||
|
||||
class EncodedAudioFrame {
|
||||
public:
|
||||
struct DecodeResult {
|
||||
@ -53,8 +55,8 @@ class AudioDecoder {
|
||||
// Returns true if this packet contains DTX.
|
||||
virtual bool IsDtxPacket() const;
|
||||
|
||||
// Decodes this frame of audio and writes the result in |decoded|.
|
||||
// |decoded| must be large enough to store as many samples as indicated by a
|
||||
// Decodes this frame of audio and writes the result in `decoded`.
|
||||
// `decoded` must be large enough to store as many samples as indicated by a
|
||||
// call to Duration() . On success, returns an absl::optional containing the
|
||||
// total number of samples across all channels, as well as whether the
|
||||
// decoder produced comfort noise or speech. On failure, returns an empty
|
||||
@ -85,8 +87,8 @@ class AudioDecoder {
|
||||
// Let the decoder parse this payload and prepare zero or more decodable
|
||||
// frames. Each frame must be between 10 ms and 120 ms long. The caller must
|
||||
// ensure that the AudioDecoder object outlives any frame objects returned by
|
||||
// this call. The decoder is free to swap or move the data from the |payload|
|
||||
// buffer. |timestamp| is the input timestamp, in samples, corresponding to
|
||||
// this call. The decoder is free to swap or move the data from the `payload`
|
||||
// buffer. `timestamp` is the input timestamp, in samples, corresponding to
|
||||
// the start of the payload.
|
||||
virtual std::vector<ParseResult> ParsePayload(rtc::Buffer&& payload,
|
||||
uint32_t timestamp);
|
||||
@ -95,12 +97,12 @@ class AudioDecoder {
|
||||
// obsolete; callers should call ParsePayload instead. For now, subclasses
|
||||
// must still implement DecodeInternal.
|
||||
|
||||
// Decodes |encode_len| bytes from |encoded| and writes the result in
|
||||
// |decoded|. The maximum bytes allowed to be written into |decoded| is
|
||||
// |max_decoded_bytes|. Returns the total number of samples across all
|
||||
// channels. If the decoder produced comfort noise, |speech_type|
|
||||
// Decodes `encode_len` bytes from `encoded` and writes the result in
|
||||
// `decoded`. The maximum bytes allowed to be written into `decoded` is
|
||||
// `max_decoded_bytes`. Returns the total number of samples across all
|
||||
// channels. If the decoder produced comfort noise, `speech_type`
|
||||
// is set to kComfortNoise, otherwise it is kSpeech. The desired output
|
||||
// sample rate is provided in |sample_rate_hz|, which must be valid for the
|
||||
// sample rate is provided in `sample_rate_hz`, which must be valid for the
|
||||
// codec at hand.
|
||||
int Decode(const uint8_t* encoded,
|
||||
size_t encoded_len,
|
||||
@ -123,11 +125,11 @@ class AudioDecoder {
|
||||
|
||||
// Calls the packet-loss concealment of the decoder to update the state after
|
||||
// one or several lost packets. The caller has to make sure that the
|
||||
// memory allocated in |decoded| should accommodate |num_frames| frames.
|
||||
// memory allocated in `decoded` should accommodate `num_frames` frames.
|
||||
virtual size_t DecodePlc(size_t num_frames, int16_t* decoded);
|
||||
|
||||
// Asks the decoder to generate packet-loss concealment and append it to the
|
||||
// end of |concealment_audio|. The concealment audio should be in
|
||||
// end of `concealment_audio`. The concealment audio should be in
|
||||
// channel-interleaved format, with as many channels as the last decoded
|
||||
// packet produced. The implementation must produce at least
|
||||
// requested_samples_per_channel, or nothing at all. This is a signal to the
|
||||
@ -136,7 +138,7 @@ class AudioDecoder {
|
||||
// with the decoded audio on either side of the concealment.
|
||||
// Note: The default implementation of GeneratePlc will be deleted soon. All
|
||||
// implementations must provide their own, which can be a simple as a no-op.
|
||||
// TODO(bugs.webrtc.org/9676): Remove default impementation.
|
||||
// TODO(bugs.webrtc.org/9676): Remove default implementation.
|
||||
virtual void GeneratePlc(size_t requested_samples_per_channel,
|
||||
rtc::BufferT<int16_t>* concealment_audio);
|
||||
|
||||
@ -146,19 +148,19 @@ class AudioDecoder {
|
||||
// Returns the last error code from the decoder.
|
||||
virtual int ErrorCode();
|
||||
|
||||
// Returns the duration in samples-per-channel of the payload in |encoded|
|
||||
// which is |encoded_len| bytes long. Returns kNotImplemented if no duration
|
||||
// Returns the duration in samples-per-channel of the payload in `encoded`
|
||||
// which is `encoded_len` bytes long. Returns kNotImplemented if no duration
|
||||
// estimate is available, or -1 in case of an error.
|
||||
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
|
||||
|
||||
// Returns the duration in samples-per-channel of the redandant payload in
|
||||
// |encoded| which is |encoded_len| bytes long. Returns kNotImplemented if no
|
||||
// `encoded` which is `encoded_len` bytes long. Returns kNotImplemented if no
|
||||
// duration estimate is available, or -1 in case of an error.
|
||||
virtual int PacketDurationRedundant(const uint8_t* encoded,
|
||||
size_t encoded_len) const;
|
||||
|
||||
// Detects whether a packet has forward error correction. The packet is
|
||||
// comprised of the samples in |encoded| which is |encoded_len| bytes long.
|
||||
// comprised of the samples in `encoded` which is `encoded_len` bytes long.
|
||||
// Returns true if the packet has FEC and false otherwise.
|
||||
virtual bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const;
|
||||
|
||||
@ -170,6 +172,9 @@ class AudioDecoder {
|
||||
// during the lifetime of the decoder.
|
||||
virtual size_t Channels() const = 0;
|
||||
|
||||
// The maximum number of audio channels supported by WebRTC decoders.
|
||||
static constexpr int kMaxNumberOfChannels = 24;
|
||||
|
||||
protected:
|
||||
static SpeechType ConvertSpeechType(int16_t type);
|
||||
|
||||
@ -184,9 +189,6 @@ class AudioDecoder {
|
||||
int sample_rate_hz,
|
||||
int16_t* decoded,
|
||||
SpeechType* speech_type);
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(AudioDecoder);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -38,6 +38,8 @@ class AudioDecoderFactory : public rtc::RefCountInterface {
|
||||
// communication between the AudioEncoder and AudioDecoder instances, which is
|
||||
// needed for some codecs with built-in bandwidth adaptation.)
|
||||
//
|
||||
// Returns null if the format isn't supported.
|
||||
//
|
||||
// Note: Implementations need to be robust against combinations other than
|
||||
// one encoder, one decoder getting the same ID; such decoders must still
|
||||
// work.
|
||||
|
||||
@ -15,8 +15,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "api/make_ref_counted.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "rtc_base/ref_counted_object.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -32,7 +33,8 @@ struct Helper<> {
|
||||
static bool IsSupportedDecoder(const SdpAudioFormat& format) { return false; }
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const SdpAudioFormat& format,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id) {
|
||||
absl::optional<AudioCodecPairId> codec_pair_id,
|
||||
const FieldTrialsView* field_trials) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@ -55,16 +57,22 @@ struct Helper<T, Ts...> {
|
||||
}
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const SdpAudioFormat& format,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id) {
|
||||
absl::optional<AudioCodecPairId> codec_pair_id,
|
||||
const FieldTrialsView* field_trials) {
|
||||
auto opt_config = T::SdpToConfig(format);
|
||||
return opt_config ? T::MakeAudioDecoder(*opt_config, codec_pair_id)
|
||||
: Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id);
|
||||
: Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id,
|
||||
field_trials);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
class AudioDecoderFactoryT : public AudioDecoderFactory {
|
||||
public:
|
||||
explicit AudioDecoderFactoryT(const FieldTrialsView* field_trials) {
|
||||
field_trials_ = field_trials;
|
||||
}
|
||||
|
||||
std::vector<AudioCodecSpec> GetSupportedDecoders() override {
|
||||
std::vector<AudioCodecSpec> specs;
|
||||
Helper<Ts...>::AppendSupportedDecoders(&specs);
|
||||
@ -78,8 +86,11 @@ class AudioDecoderFactoryT : public AudioDecoderFactory {
|
||||
std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const SdpAudioFormat& format,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id) override {
|
||||
return Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id);
|
||||
return Helper<Ts...>::MakeAudioDecoder(format, codec_pair_id,
|
||||
field_trials_);
|
||||
}
|
||||
|
||||
const FieldTrialsView* field_trials_;
|
||||
};
|
||||
|
||||
} // namespace audio_decoder_factory_template_impl
|
||||
@ -89,8 +100,8 @@ class AudioDecoderFactoryT : public AudioDecoderFactory {
|
||||
// Each decoder type is given as a template argument to the function; it should
|
||||
// be a struct with the following static member functions:
|
||||
//
|
||||
// // Converts |audio_format| to a ConfigType instance. Returns an empty
|
||||
// // optional if |audio_format| doesn't correctly specify a decoder of our
|
||||
// // Converts `audio_format` to a ConfigType instance. Returns an empty
|
||||
// // optional if `audio_format` doesn't correctly specify a decoder of our
|
||||
// // type.
|
||||
// absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
|
||||
//
|
||||
@ -115,7 +126,8 @@ class AudioDecoderFactoryT : public AudioDecoderFactory {
|
||||
// TODO(kwiberg): Point at CreateBuiltinAudioDecoderFactory() for an example of
|
||||
// how it is used.
|
||||
template <typename... Ts>
|
||||
rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory() {
|
||||
rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory(
|
||||
const FieldTrialsView* field_trials = nullptr) {
|
||||
// There's no technical reason we couldn't allow zero template parameters,
|
||||
// but such a factory couldn't create any decoders, and callers can do this
|
||||
// by mistake by simply forgetting the <> altogether. So we forbid it in
|
||||
@ -123,9 +135,9 @@ rtc::scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory() {
|
||||
static_assert(sizeof...(Ts) >= 1,
|
||||
"Caller must give at least one template parameter");
|
||||
|
||||
return rtc::scoped_refptr<AudioDecoderFactory>(
|
||||
new rtc::RefCountedObject<
|
||||
audio_decoder_factory_template_impl::AudioDecoderFactoryT<Ts...>>());
|
||||
return rtc::make_ref_counted<
|
||||
audio_decoder_factory_template_impl::AudioDecoderFactoryT<Ts...>>(
|
||||
field_trials);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -83,7 +83,7 @@ void AudioEncoder::OnReceivedUplinkPacketLossFraction(
|
||||
|
||||
void AudioEncoder::OnReceivedUplinkRecoverablePacketLossFraction(
|
||||
float uplink_recoverable_packet_loss_fraction) {
|
||||
RTC_NOTREACHED();
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
|
||||
void AudioEncoder::OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) {
|
||||
@ -110,4 +110,5 @@ ANAStats AudioEncoder::GetANAStats() const {
|
||||
return ANAStats();
|
||||
}
|
||||
|
||||
constexpr int AudioEncoder::kMaxNumberOfChannels;
|
||||
} // namespace webrtc
|
||||
|
||||
@ -16,12 +16,12 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/array_view.h"
|
||||
#include "api/call/bitrate_allocation.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/buffer.h"
|
||||
#include "rtc_base/deprecation.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -95,13 +95,13 @@ class AudioEncoder {
|
||||
|
||||
// This is the main struct for auxiliary encoding information. Each encoded
|
||||
// packet should be accompanied by one EncodedInfo struct, containing the
|
||||
// total number of |encoded_bytes|, the |encoded_timestamp| and the
|
||||
// |payload_type|. If the packet contains redundant encodings, the |redundant|
|
||||
// total number of `encoded_bytes`, the `encoded_timestamp` and the
|
||||
// `payload_type`. If the packet contains redundant encodings, the `redundant`
|
||||
// vector will be populated with EncodedInfoLeaf structs. Each struct in the
|
||||
// vector represents one encoding; the order of structs in the vector is the
|
||||
// same as the order in which the actual payloads are written to the byte
|
||||
// stream. When EncoderInfoLeaf structs are present in the vector, the main
|
||||
// struct's |encoded_bytes| will be the sum of all the |encoded_bytes| in the
|
||||
// struct's `encoded_bytes` will be the sum of all the `encoded_bytes` in the
|
||||
// vector.
|
||||
struct EncodedInfo : public EncodedInfoLeaf {
|
||||
EncodedInfo();
|
||||
@ -143,7 +143,7 @@ class AudioEncoder {
|
||||
|
||||
// Accepts one 10 ms block of input audio (i.e., SampleRateHz() / 100 *
|
||||
// NumChannels() samples). Multi-channel audio must be sample-interleaved.
|
||||
// The encoder appends zero or more bytes of output to |encoded| and returns
|
||||
// The encoder appends zero or more bytes of output to `encoded` and returns
|
||||
// additional encoding information. Encode() checks some preconditions, calls
|
||||
// EncodeImpl() which does the actual work, and then checks some
|
||||
// postconditions.
|
||||
@ -182,12 +182,11 @@ class AudioEncoder {
|
||||
// implementation does nothing.
|
||||
virtual void SetMaxPlaybackRate(int frequency_hz);
|
||||
|
||||
// This is to be deprecated. Please use |OnReceivedTargetAudioBitrate|
|
||||
// instead.
|
||||
// Tells the encoder what average bitrate we'd like it to produce. The
|
||||
// encoder is free to adjust or disregard the given bitrate (the default
|
||||
// implementation does the latter).
|
||||
RTC_DEPRECATED virtual void SetTargetBitrate(int target_bps);
|
||||
ABSL_DEPRECATED("Use OnReceivedTargetAudioBitrate instead")
|
||||
virtual void SetTargetBitrate(int target_bps);
|
||||
|
||||
// Causes this encoder to let go of any other encoders it contains, and
|
||||
// returns a pointer to an array where they are stored (which is required to
|
||||
@ -206,11 +205,12 @@ class AudioEncoder {
|
||||
virtual void DisableAudioNetworkAdaptor();
|
||||
|
||||
// Provides uplink packet loss fraction to this encoder to allow it to adapt.
|
||||
// |uplink_packet_loss_fraction| is in the range [0.0, 1.0].
|
||||
// `uplink_packet_loss_fraction` is in the range [0.0, 1.0].
|
||||
virtual void OnReceivedUplinkPacketLossFraction(
|
||||
float uplink_packet_loss_fraction);
|
||||
|
||||
RTC_DEPRECATED virtual void OnReceivedUplinkRecoverablePacketLossFraction(
|
||||
ABSL_DEPRECATED("")
|
||||
virtual void OnReceivedUplinkRecoverablePacketLossFraction(
|
||||
float uplink_recoverable_packet_loss_fraction);
|
||||
|
||||
// Provides target audio bitrate to this encoder to allow it to adapt.
|
||||
@ -246,6 +246,9 @@ class AudioEncoder {
|
||||
virtual absl::optional<std::pair<TimeDelta, TimeDelta>> GetFrameLengthRange()
|
||||
const = 0;
|
||||
|
||||
// The maximum number of audio channels supported by WebRTC encoders.
|
||||
static constexpr int kMaxNumberOfChannels = 24;
|
||||
|
||||
protected:
|
||||
// Subclasses implement this to perform the actual encoding. Called by
|
||||
// Encode().
|
||||
|
||||
@ -44,6 +44,8 @@ class AudioEncoderFactory : public rtc::RefCountInterface {
|
||||
// communication between the AudioEncoder and AudioDecoder instances, which is
|
||||
// needed for some codecs with built-in bandwidth adaptation.)
|
||||
//
|
||||
// Returns null if the format isn't supported.
|
||||
//
|
||||
// Note: Implementations need to be robust against combinations other than
|
||||
// one encoder, one decoder getting the same ID; such encoders must still
|
||||
// work.
|
||||
|
||||
@ -15,8 +15,9 @@
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_encoder_factory.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "api/make_ref_counted.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "rtc_base/ref_counted_object.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -36,7 +37,8 @@ struct Helper<> {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id) {
|
||||
absl::optional<AudioCodecPairId> codec_pair_id,
|
||||
const FieldTrialsView* field_trials) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
@ -63,13 +65,14 @@ struct Helper<T, Ts...> {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id) {
|
||||
absl::optional<AudioCodecPairId> codec_pair_id,
|
||||
const FieldTrialsView* field_trials) {
|
||||
auto opt_config = T::SdpToConfig(format);
|
||||
if (opt_config) {
|
||||
return T::MakeAudioEncoder(*opt_config, payload_type, codec_pair_id);
|
||||
} else {
|
||||
return Helper<Ts...>::MakeAudioEncoder(payload_type, format,
|
||||
codec_pair_id);
|
||||
codec_pair_id, field_trials);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -77,6 +80,10 @@ struct Helper<T, Ts...> {
|
||||
template <typename... Ts>
|
||||
class AudioEncoderFactoryT : public AudioEncoderFactory {
|
||||
public:
|
||||
explicit AudioEncoderFactoryT(const FieldTrialsView* field_trials) {
|
||||
field_trials_ = field_trials;
|
||||
}
|
||||
|
||||
std::vector<AudioCodecSpec> GetSupportedEncoders() override {
|
||||
std::vector<AudioCodecSpec> specs;
|
||||
Helper<Ts...>::AppendSupportedEncoders(&specs);
|
||||
@ -92,8 +99,11 @@ class AudioEncoderFactoryT : public AudioEncoderFactory {
|
||||
int payload_type,
|
||||
const SdpAudioFormat& format,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id) override {
|
||||
return Helper<Ts...>::MakeAudioEncoder(payload_type, format, codec_pair_id);
|
||||
return Helper<Ts...>::MakeAudioEncoder(payload_type, format, codec_pair_id,
|
||||
field_trials_);
|
||||
}
|
||||
|
||||
const FieldTrialsView* field_trials_;
|
||||
};
|
||||
|
||||
} // namespace audio_encoder_factory_template_impl
|
||||
@ -103,8 +113,8 @@ class AudioEncoderFactoryT : public AudioEncoderFactory {
|
||||
// Each encoder type is given as a template argument to the function; it should
|
||||
// be a struct with the following static member functions:
|
||||
//
|
||||
// // Converts |audio_format| to a ConfigType instance. Returns an empty
|
||||
// // optional if |audio_format| doesn't correctly specify an encoder of our
|
||||
// // Converts `audio_format` to a ConfigType instance. Returns an empty
|
||||
// // optional if `audio_format` doesn't correctly specify an encoder of our
|
||||
// // type.
|
||||
// absl::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
|
||||
//
|
||||
@ -134,7 +144,8 @@ class AudioEncoderFactoryT : public AudioEncoderFactory {
|
||||
// TODO(kwiberg): Point at CreateBuiltinAudioEncoderFactory() for an example of
|
||||
// how it is used.
|
||||
template <typename... Ts>
|
||||
rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory() {
|
||||
rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory(
|
||||
const FieldTrialsView* field_trials = nullptr) {
|
||||
// There's no technical reason we couldn't allow zero template parameters,
|
||||
// but such a factory couldn't create any encoders, and callers can do this
|
||||
// by mistake by simply forgetting the <> altogether. So we forbid it in
|
||||
@ -142,9 +153,9 @@ rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory() {
|
||||
static_assert(sizeof...(Ts) >= 1,
|
||||
"Caller must give at least one template parameter");
|
||||
|
||||
return rtc::scoped_refptr<AudioEncoderFactory>(
|
||||
new rtc::RefCountedObject<
|
||||
audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>());
|
||||
return rtc::make_ref_counted<
|
||||
audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>(
|
||||
field_trials);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -39,7 +39,7 @@ struct RTC_EXPORT SdpAudioFormat {
|
||||
Parameters&& param);
|
||||
~SdpAudioFormat();
|
||||
|
||||
// Returns true if this format is compatible with |o|. In SDP terminology:
|
||||
// Returns true if this format is compatible with `o`. In SDP terminology:
|
||||
// would it represent the same codec between an offer and an answer? As
|
||||
// opposed to operator==, this method disregards codec parameters.
|
||||
bool Matches(const SdpAudioFormat& o) const;
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#if WEBRTC_USE_BUILTIN_ILBC
|
||||
#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h" // nogncheck
|
||||
#endif
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac.h"
|
||||
#if WEBRTC_USE_BUILTIN_OPUS
|
||||
#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
|
||||
#include "api/audio_codecs/opus/audio_decoder_opus.h" // nogncheck
|
||||
@ -57,7 +56,7 @@ rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
|
||||
AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>,
|
||||
#endif
|
||||
|
||||
AudioDecoderIsac, AudioDecoderG722,
|
||||
AudioDecoderG722,
|
||||
|
||||
#if WEBRTC_USE_BUILTIN_ILBC
|
||||
AudioDecoderIlbc,
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
#if WEBRTC_USE_BUILTIN_ILBC
|
||||
#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h" // nogncheck
|
||||
#endif
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac.h"
|
||||
#if WEBRTC_USE_BUILTIN_OPUS
|
||||
#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
|
||||
#include "api/audio_codecs/opus/audio_encoder_opus.h" // nogncheck
|
||||
@ -47,8 +46,10 @@ struct NotAdvertised {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
|
||||
return T::MakeAudioEncoder(config, payload_type, codec_pair_id);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr) {
|
||||
return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
|
||||
field_trials);
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,7 +62,7 @@ rtc::scoped_refptr<AudioEncoderFactory> CreateBuiltinAudioEncoderFactory() {
|
||||
AudioEncoderOpus, NotAdvertised<AudioEncoderMultiChannelOpus>,
|
||||
#endif
|
||||
|
||||
AudioEncoderIsac, AudioEncoderG722,
|
||||
AudioEncoderG722,
|
||||
|
||||
#if WEBRTC_USE_BUILTIN_ILBC
|
||||
AudioEncoderIlbc,
|
||||
|
||||
@ -21,9 +21,11 @@ rtc_library("audio_encoder_g711") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:g711",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base:safe_minmax",
|
||||
"../../../rtc_base:stringutils",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
@ -41,8 +43,9 @@ rtc_library("audio_decoder_g711") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:g711",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
|
||||
@ -28,7 +28,10 @@ absl::optional<AudioDecoderG711::Config> AudioDecoderG711::SdpToConfig(
|
||||
Config config;
|
||||
config.type = is_pcmu ? Config::Type::kPcmU : Config::Type::kPcmA;
|
||||
config.num_channels = rtc::dchecked_cast<int>(format.num_channels);
|
||||
RTC_DCHECK(config.IsOk());
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return absl::nullopt;
|
||||
}
|
||||
return config;
|
||||
} else {
|
||||
return absl::nullopt;
|
||||
@ -44,14 +47,19 @@ void AudioDecoderG711::AppendSupportedDecoders(
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderG711::MakeAudioDecoder(
|
||||
const Config& config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
switch (config.type) {
|
||||
case Config::Type::kPcmU:
|
||||
return std::make_unique<AudioDecoderPcmU>(config.num_channels);
|
||||
case Config::Type::kPcmA:
|
||||
return std::make_unique<AudioDecoderPcmA>(config.num_channels);
|
||||
default:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -28,7 +29,9 @@ struct RTC_EXPORT AudioDecoderG711 {
|
||||
struct Config {
|
||||
enum class Type { kPcmU, kPcmA };
|
||||
bool IsOk() const {
|
||||
return (type == Type::kPcmU || type == Type::kPcmA) && num_channels >= 1;
|
||||
return (type == Type::kPcmU || type == Type::kPcmA) &&
|
||||
num_channels >= 1 &&
|
||||
num_channels <= AudioDecoder::kMaxNumberOfChannels;
|
||||
}
|
||||
Type type;
|
||||
int num_channels;
|
||||
@ -37,7 +40,8 @@ struct RTC_EXPORT AudioDecoderG711 {
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
const Config& config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -38,7 +38,10 @@ absl::optional<AudioEncoderG711::Config> AudioEncoderG711::SdpToConfig(
|
||||
config.frame_size_ms = rtc::SafeClamp(10 * (*ptime / 10), 10, 60);
|
||||
}
|
||||
}
|
||||
RTC_DCHECK(config.IsOk());
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return absl::nullopt;
|
||||
}
|
||||
return config;
|
||||
} else {
|
||||
return absl::nullopt;
|
||||
@ -61,8 +64,12 @@ AudioCodecInfo AudioEncoderG711::QueryAudioEncoder(const Config& config) {
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderG711::MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
switch (config.type) {
|
||||
case Config::Type::kPcmU: {
|
||||
AudioEncoderPcmU::Config impl_config;
|
||||
@ -79,6 +86,7 @@ std::unique_ptr<AudioEncoder> AudioEncoderG711::MakeAudioEncoder(
|
||||
return std::make_unique<AudioEncoderPcmA>(impl_config);
|
||||
}
|
||||
default: {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -29,7 +30,9 @@ struct RTC_EXPORT AudioEncoderG711 {
|
||||
enum class Type { kPcmU, kPcmA };
|
||||
bool IsOk() const {
|
||||
return (type == Type::kPcmU || type == Type::kPcmA) &&
|
||||
frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1;
|
||||
frame_size_ms > 0 && frame_size_ms % 10 == 0 &&
|
||||
num_channels >= 1 &&
|
||||
num_channels <= AudioEncoder::kMaxNumberOfChannels;
|
||||
}
|
||||
Type type = Type::kPcmU;
|
||||
int num_channels = 1;
|
||||
@ -42,7 +45,8 @@ struct RTC_EXPORT AudioEncoderG711 {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -15,6 +15,7 @@ if (is_android) {
|
||||
rtc_source_set("audio_encoder_g722_config") {
|
||||
visibility = [ "*" ]
|
||||
sources = [ "audio_encoder_g722_config.h" ]
|
||||
deps = [ "..:audio_codecs_api" ]
|
||||
}
|
||||
|
||||
rtc_library("audio_encoder_g722") {
|
||||
@ -27,9 +28,11 @@ rtc_library("audio_encoder_g722") {
|
||||
deps = [
|
||||
":audio_encoder_g722_config",
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:g722",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base:safe_minmax",
|
||||
"../../../rtc_base:stringutils",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
@ -47,8 +50,9 @@ rtc_library("audio_decoder_g722") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:g722",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
|
||||
@ -21,12 +21,12 @@ namespace webrtc {
|
||||
|
||||
absl::optional<AudioDecoderG722::Config> AudioDecoderG722::SdpToConfig(
|
||||
const SdpAudioFormat& format) {
|
||||
return absl::EqualsIgnoreCase(format.name, "G722") &&
|
||||
format.clockrate_hz == 8000 &&
|
||||
(format.num_channels == 1 || format.num_channels == 2)
|
||||
? absl::optional<Config>(
|
||||
Config{rtc::dchecked_cast<int>(format.num_channels)})
|
||||
: absl::nullopt;
|
||||
if (absl::EqualsIgnoreCase(format.name, "G722") &&
|
||||
format.clockrate_hz == 8000 &&
|
||||
(format.num_channels == 1 || format.num_channels == 2)) {
|
||||
return Config{rtc::dchecked_cast<int>(format.num_channels)};
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
void AudioDecoderG722::AppendSupportedDecoders(
|
||||
@ -36,13 +36,19 @@ void AudioDecoderG722::AppendSupportedDecoders(
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderG722::MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
switch (config.num_channels) {
|
||||
case 1:
|
||||
return std::make_unique<AudioDecoderG722Impl>();
|
||||
case 2:
|
||||
return std::make_unique<AudioDecoderG722StereoImpl>();
|
||||
default:
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -33,7 +34,8 @@ struct RTC_EXPORT AudioDecoderG722 {
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -38,8 +38,11 @@ absl::optional<AudioEncoderG722Config> AudioEncoderG722::SdpToConfig(
|
||||
config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 10, 60);
|
||||
}
|
||||
}
|
||||
return config.IsOk() ? absl::optional<AudioEncoderG722Config>(config)
|
||||
: absl::nullopt;
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return absl::nullopt;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
void AudioEncoderG722::AppendSupportedEncoders(
|
||||
@ -59,8 +62,12 @@ AudioCodecInfo AudioEncoderG722::QueryAudioEncoder(
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderG722::MakeAudioEncoder(
|
||||
const AudioEncoderG722Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<AudioEncoderG722Impl>(config, payload_type);
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/audio_codecs/g722/audio_encoder_g722_config.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -34,7 +35,8 @@ struct RTC_EXPORT AudioEncoderG722 {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const AudioEncoderG722Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -11,11 +11,14 @@
|
||||
#ifndef API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
|
||||
#define API_AUDIO_CODECS_G722_AUDIO_ENCODER_G722_CONFIG_H_
|
||||
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
struct AudioEncoderG722Config {
|
||||
bool IsOk() const {
|
||||
return frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1;
|
||||
return frame_size_ms > 0 && frame_size_ms % 10 == 0 && num_channels >= 1 &&
|
||||
num_channels <= AudioEncoder::kMaxNumberOfChannels;
|
||||
}
|
||||
int frame_size_ms = 20;
|
||||
int num_channels = 1;
|
||||
|
||||
@ -27,9 +27,11 @@ rtc_library("audio_encoder_ilbc") {
|
||||
deps = [
|
||||
":audio_encoder_ilbc_config",
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:ilbc",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base:safe_conversions",
|
||||
"../../../rtc_base:safe_minmax",
|
||||
"../../../rtc_base:stringutils",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
@ -46,8 +48,8 @@ rtc_library("audio_decoder_ilbc") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:ilbc",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
|
||||
@ -20,10 +20,11 @@ namespace webrtc {
|
||||
|
||||
absl::optional<AudioDecoderIlbc::Config> AudioDecoderIlbc::SdpToConfig(
|
||||
const SdpAudioFormat& format) {
|
||||
return absl::EqualsIgnoreCase(format.name, "ILBC") &&
|
||||
format.clockrate_hz == 8000 && format.num_channels == 1
|
||||
? absl::optional<Config>(Config())
|
||||
: absl::nullopt;
|
||||
if (absl::EqualsIgnoreCase(format.name, "ILBC") &&
|
||||
format.clockrate_hz == 8000 && format.num_channels == 1) {
|
||||
return Config();
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
||||
|
||||
void AudioDecoderIlbc::AppendSupportedDecoders(
|
||||
@ -33,7 +34,8 @@ void AudioDecoderIlbc::AppendSupportedDecoders(
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderIlbc::MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
return std::make_unique<AudioDecoderIlbcImpl>();
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -29,7 +30,8 @@ struct AudioDecoderIlbc {
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -32,7 +32,7 @@ int GetIlbcBitrate(int ptime) {
|
||||
// 50 bytes per frame of 30 ms => (approx) 13333 bits/s.
|
||||
return 13333;
|
||||
default:
|
||||
FATAL();
|
||||
RTC_CHECK_NOTREACHED();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@ -53,8 +53,11 @@ absl::optional<AudioEncoderIlbcConfig> AudioEncoderIlbc::SdpToConfig(
|
||||
config.frame_size_ms = rtc::SafeClamp<int>(whole_packets * 10, 20, 60);
|
||||
}
|
||||
}
|
||||
return config.IsOk() ? absl::optional<AudioEncoderIlbcConfig>(config)
|
||||
: absl::nullopt;
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return absl::nullopt;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
void AudioEncoderIlbc::AppendSupportedEncoders(
|
||||
@ -73,8 +76,12 @@ AudioCodecInfo AudioEncoderIlbc::QueryAudioEncoder(
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderIlbc::MakeAudioEncoder(
|
||||
const AudioEncoderIlbcConfig& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<AudioEncoderIlbcImpl>(config, payload_type);
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/audio_codecs/ilbc/audio_encoder_ilbc_config.h"
|
||||
#include "api/field_trials_view.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -33,7 +34,8 @@ struct AudioEncoderIlbc {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const AudioEncoderIlbcConfig& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import("../../../webrtc.gni")
|
||||
if (is_android) {
|
||||
import("//build/config/android/config.gni")
|
||||
import("//build/config/android/rules.gni")
|
||||
}
|
||||
|
||||
# The targets with _fix and _float suffixes unconditionally use the
|
||||
# fixed-point and floating-point iSAC implementations, respectively.
|
||||
# The targets without suffixes pick one of the implementations based
|
||||
# on cleverly chosen criteria.
|
||||
|
||||
rtc_source_set("audio_encoder_isac") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "audio_codecs" ]
|
||||
public = [ "audio_encoder_isac.h" ]
|
||||
public_configs = [ ":isac_config" ]
|
||||
if (current_cpu == "arm") {
|
||||
deps = [ ":audio_encoder_isac_fix" ]
|
||||
} else {
|
||||
deps = [ ":audio_encoder_isac_float" ]
|
||||
}
|
||||
}
|
||||
|
||||
rtc_source_set("audio_decoder_isac") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "audio_codecs" ]
|
||||
public = [ "audio_decoder_isac.h" ]
|
||||
public_configs = [ ":isac_config" ]
|
||||
if (current_cpu == "arm") {
|
||||
deps = [ ":audio_decoder_isac_fix" ]
|
||||
} else {
|
||||
deps = [ ":audio_decoder_isac_float" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("isac_config") {
|
||||
visibility = [ ":*" ]
|
||||
if (current_cpu == "arm") {
|
||||
defines = [
|
||||
"WEBRTC_USE_BUILTIN_ISAC_FIX=1",
|
||||
"WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
|
||||
]
|
||||
} else {
|
||||
defines = [
|
||||
"WEBRTC_USE_BUILTIN_ISAC_FIX=0",
|
||||
"WEBRTC_USE_BUILTIN_ISAC_FLOAT=1",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
rtc_library("audio_encoder_isac_fix") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "audio_codecs" ]
|
||||
sources = [
|
||||
"audio_encoder_isac_fix.cc",
|
||||
"audio_encoder_isac_fix.h",
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../modules/audio_coding:isac_fix",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("audio_decoder_isac_fix") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "audio_codecs" ]
|
||||
sources = [
|
||||
"audio_decoder_isac_fix.cc",
|
||||
"audio_decoder_isac_fix.h",
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../modules/audio_coding:isac_fix",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("audio_encoder_isac_float") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "audio_codecs" ]
|
||||
sources = [
|
||||
"audio_encoder_isac_float.cc",
|
||||
"audio_encoder_isac_float.h",
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../modules/audio_coding:isac",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("audio_decoder_isac_float") {
|
||||
visibility = [ "*" ]
|
||||
poisonous = [ "audio_codecs" ]
|
||||
sources = [
|
||||
"audio_decoder_isac_float.cc",
|
||||
"audio_decoder_isac_float.h",
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../modules/audio_coding:isac",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
"//third_party/abseil-cpp/absl/strings",
|
||||
"//third_party/abseil-cpp/absl/types:optional",
|
||||
]
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
|
||||
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
|
||||
|
||||
#if WEBRTC_USE_BUILTIN_ISAC_FIX && !WEBRTC_USE_BUILTIN_ISAC_FLOAT
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h" // nogncheck
|
||||
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT && !WEBRTC_USE_BUILTIN_ISAC_FIX
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_float.h" // nogncheck
|
||||
#else
|
||||
#error "Must choose either fix or float"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
#if WEBRTC_USE_BUILTIN_ISAC_FIX
|
||||
using AudioDecoderIsac = AudioDecoderIsacFix;
|
||||
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
|
||||
using AudioDecoderIsac = AudioDecoderIsacFloat;
|
||||
#endif
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
|
||||
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
absl::optional<AudioDecoderIsacFix::Config> AudioDecoderIsacFix::SdpToConfig(
|
||||
const SdpAudioFormat& format) {
|
||||
return absl::EqualsIgnoreCase(format.name, "ISAC") &&
|
||||
format.clockrate_hz == 16000 && format.num_channels == 1
|
||||
? absl::optional<Config>(Config())
|
||||
: absl::nullopt;
|
||||
}
|
||||
|
||||
void AudioDecoderIsacFix::AppendSupportedDecoders(
|
||||
std::vector<AudioCodecSpec>* specs) {
|
||||
specs->push_back({{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}});
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderIsacFix::MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
AudioDecoderIsacFixImpl::Config c;
|
||||
c.sample_rate_hz = 16000;
|
||||
return std::make_unique<AudioDecoderIsacFixImpl>(c);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
|
||||
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// iSAC decoder API (fixed-point implementation) for use as a template
|
||||
// parameter to CreateAudioDecoderFactory<...>().
|
||||
struct RTC_EXPORT AudioDecoderIsacFix {
|
||||
struct Config {}; // Empty---no config values needed!
|
||||
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
|
||||
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_float.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
absl::optional<AudioDecoderIsacFloat::Config>
|
||||
AudioDecoderIsacFloat::SdpToConfig(const SdpAudioFormat& format) {
|
||||
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
|
||||
(format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
|
||||
format.num_channels == 1) {
|
||||
Config config;
|
||||
config.sample_rate_hz = format.clockrate_hz;
|
||||
return config;
|
||||
} else {
|
||||
return absl::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDecoderIsacFloat::AppendSupportedDecoders(
|
||||
std::vector<AudioCodecSpec>* specs) {
|
||||
specs->push_back({{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}});
|
||||
specs->push_back({{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}});
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderIsacFloat::MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
AudioDecoderIsacFloatImpl::Config c;
|
||||
c.sample_rate_hz = config.sample_rate_hz;
|
||||
return std::make_unique<AudioDecoderIsacFloatImpl>(c);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
|
||||
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// iSAC decoder API (floating-point implementation) for use as a template
|
||||
// parameter to CreateAudioDecoderFactory<...>().
|
||||
struct RTC_EXPORT AudioDecoderIsacFloat {
|
||||
struct Config {
|
||||
bool IsOk() const {
|
||||
return sample_rate_hz == 16000 || sample_rate_hz == 32000;
|
||||
}
|
||||
int sample_rate_hz = 16000;
|
||||
};
|
||||
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
|
||||
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
|
||||
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
|
||||
|
||||
#if WEBRTC_USE_BUILTIN_ISAC_FIX && !WEBRTC_USE_BUILTIN_ISAC_FLOAT
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h" // nogncheck
|
||||
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT && !WEBRTC_USE_BUILTIN_ISAC_FIX
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_float.h" // nogncheck
|
||||
#else
|
||||
#error "Must choose either fix or float"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
#if WEBRTC_USE_BUILTIN_ISAC_FIX
|
||||
using AudioEncoderIsac = AudioEncoderIsacFix;
|
||||
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
|
||||
using AudioEncoderIsac = AudioEncoderIsacFloat;
|
||||
#endif
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
|
||||
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"
|
||||
#include "rtc_base/string_to_number.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
absl::optional<AudioEncoderIsacFix::Config> AudioEncoderIsacFix::SdpToConfig(
|
||||
const SdpAudioFormat& format) {
|
||||
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
|
||||
format.clockrate_hz == 16000 && format.num_channels == 1) {
|
||||
Config config;
|
||||
const auto ptime_iter = format.parameters.find("ptime");
|
||||
if (ptime_iter != format.parameters.end()) {
|
||||
const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
|
||||
if (ptime && *ptime >= 60) {
|
||||
config.frame_size_ms = 60;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
} else {
|
||||
return absl::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEncoderIsacFix::AppendSupportedEncoders(
|
||||
std::vector<AudioCodecSpec>* specs) {
|
||||
const SdpAudioFormat fmt = {"ISAC", 16000, 1};
|
||||
const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
|
||||
specs->push_back({fmt, info});
|
||||
}
|
||||
|
||||
AudioCodecInfo AudioEncoderIsacFix::QueryAudioEncoder(
|
||||
AudioEncoderIsacFix::Config config) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
return {16000, 1, 32000, 10000, 32000};
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderIsacFix::MakeAudioEncoder(
|
||||
AudioEncoderIsacFix::Config config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
AudioEncoderIsacFixImpl::Config c;
|
||||
c.frame_size_ms = config.frame_size_ms;
|
||||
c.bit_rate = config.bit_rate;
|
||||
c.payload_type = payload_type;
|
||||
return std::make_unique<AudioEncoderIsacFixImpl>(c);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
|
||||
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// iSAC encoder API (fixed-point implementation) for use as a template
|
||||
// parameter to CreateAudioEncoderFactory<...>().
|
||||
struct RTC_EXPORT AudioEncoderIsacFix {
|
||||
struct Config {
|
||||
bool IsOk() const {
|
||||
if (frame_size_ms != 30 && frame_size_ms != 60) {
|
||||
return false;
|
||||
}
|
||||
if (bit_rate < 10000 || bit_rate > 32000) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int frame_size_ms = 30;
|
||||
int bit_rate = 32000; // Limit on short-term average bit rate, in bits/s.
|
||||
};
|
||||
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
|
||||
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
|
||||
static AudioCodecInfo QueryAudioEncoder(Config config);
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
Config config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
|
||||
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "absl/strings/match.h"
|
||||
#include "modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"
|
||||
#include "rtc_base/string_to_number.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
absl::optional<AudioEncoderIsacFloat::Config>
|
||||
AudioEncoderIsacFloat::SdpToConfig(const SdpAudioFormat& format) {
|
||||
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
|
||||
(format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
|
||||
format.num_channels == 1) {
|
||||
Config config;
|
||||
config.sample_rate_hz = format.clockrate_hz;
|
||||
config.bit_rate = format.clockrate_hz == 16000 ? 32000 : 56000;
|
||||
if (config.sample_rate_hz == 16000) {
|
||||
// For sample rate 16 kHz, optionally use 60 ms frames, instead of the
|
||||
// default 30 ms.
|
||||
const auto ptime_iter = format.parameters.find("ptime");
|
||||
if (ptime_iter != format.parameters.end()) {
|
||||
const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
|
||||
if (ptime && *ptime >= 60) {
|
||||
config.frame_size_ms = 60;
|
||||
}
|
||||
}
|
||||
}
|
||||
return config;
|
||||
} else {
|
||||
return absl::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioEncoderIsacFloat::AppendSupportedEncoders(
|
||||
std::vector<AudioCodecSpec>* specs) {
|
||||
for (int sample_rate_hz : {16000, 32000}) {
|
||||
const SdpAudioFormat fmt = {"ISAC", sample_rate_hz, 1};
|
||||
const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
|
||||
specs->push_back({fmt, info});
|
||||
}
|
||||
}
|
||||
|
||||
AudioCodecInfo AudioEncoderIsacFloat::QueryAudioEncoder(
|
||||
const AudioEncoderIsacFloat::Config& config) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
constexpr int min_bitrate = 10000;
|
||||
const int max_bitrate = config.sample_rate_hz == 16000 ? 32000 : 56000;
|
||||
const int default_bitrate = max_bitrate;
|
||||
return {config.sample_rate_hz, 1, default_bitrate, min_bitrate, max_bitrate};
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderIsacFloat::MakeAudioEncoder(
|
||||
const AudioEncoderIsacFloat::Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
AudioEncoderIsacFloatImpl::Config c;
|
||||
c.payload_type = payload_type;
|
||||
c.sample_rate_hz = config.sample_rate_hz;
|
||||
c.frame_size_ms = config.frame_size_ms;
|
||||
c.bit_rate = config.bit_rate;
|
||||
return std::make_unique<AudioEncoderIsacFloatImpl>(c);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
|
||||
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// iSAC encoder API (floating-point implementation) for use as a template
|
||||
// parameter to CreateAudioEncoderFactory<...>().
|
||||
struct RTC_EXPORT AudioEncoderIsacFloat {
|
||||
struct Config {
|
||||
bool IsOk() const {
|
||||
switch (sample_rate_hz) {
|
||||
case 16000:
|
||||
if (frame_size_ms != 30 && frame_size_ms != 60) {
|
||||
return false;
|
||||
}
|
||||
if (bit_rate < 10000 || bit_rate > 32000) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 32000:
|
||||
if (frame_size_ms != 30) {
|
||||
return false;
|
||||
}
|
||||
if (bit_rate < 10000 || bit_rate > 56000) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int sample_rate_hz = 16000;
|
||||
int frame_size_ms = 30;
|
||||
int bit_rate = 32000; // Limit on short-term average bit rate, in bits/s.
|
||||
};
|
||||
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
|
||||
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
|
||||
static AudioCodecInfo QueryAudioEncoder(const Config& config);
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
|
||||
@ -20,10 +20,7 @@ rtc_library("audio_encoder_opus_config") {
|
||||
"audio_encoder_opus_config.cc",
|
||||
"audio_encoder_opus_config.h",
|
||||
]
|
||||
deps = [
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
deps = [ "../../../rtc_base/system:rtc_export" ]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
defines = []
|
||||
if (rtc_opus_variable_complexity) {
|
||||
@ -36,6 +33,7 @@ rtc_library("audio_encoder_opus_config") {
|
||||
rtc_source_set("audio_decoder_opus_config") {
|
||||
visibility = [ "*" ]
|
||||
sources = [ "audio_decoder_multi_channel_opus_config.h" ]
|
||||
deps = [ "..:audio_codecs_api" ]
|
||||
}
|
||||
|
||||
rtc_library("audio_encoder_opus") {
|
||||
@ -46,8 +44,8 @@ rtc_library("audio_encoder_opus") {
|
||||
deps = [
|
||||
":audio_encoder_opus_config",
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:webrtc_opus",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
@ -65,8 +63,8 @@ rtc_library("audio_decoder_opus") {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:webrtc_opus",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
@ -82,8 +80,8 @@ rtc_library("audio_encoder_multiopus") {
|
||||
sources = [ "audio_encoder_multi_channel_opus.cc" ]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:webrtc_multiopus",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
"../opus:audio_encoder_opus_config",
|
||||
]
|
||||
@ -100,8 +98,8 @@ rtc_library("audio_decoder_multiopus") {
|
||||
deps = [
|
||||
":audio_decoder_opus_config",
|
||||
"..:audio_codecs_api",
|
||||
"../../../api:field_trials_view",
|
||||
"../../../modules/audio_coding:webrtc_multiopus",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/system:rtc_export",
|
||||
]
|
||||
absl_deps = [
|
||||
|
||||
@ -64,7 +64,8 @@ void AudioDecoderMultiChannelOpus::AppendSupportedDecoders(
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderMultiChannelOpus::MakeAudioDecoder(
|
||||
AudioDecoderMultiChannelOpusConfig config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
return AudioDecoderMultiChannelOpusImpl::MakeAudioDecoder(config);
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus_config.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -32,7 +33,8 @@ struct RTC_EXPORT AudioDecoderMultiChannelOpus {
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
AudioDecoderMultiChannelOpusConfig config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
struct AudioDecoderMultiChannelOpusConfig {
|
||||
// The number of channels that the decoder will output.
|
||||
@ -30,7 +32,8 @@ struct AudioDecoderMultiChannelOpusConfig {
|
||||
std::vector<unsigned char> channel_mapping;
|
||||
|
||||
bool IsOk() const {
|
||||
if (num_channels < 0 || num_streams < 0 || coupled_streams < 0) {
|
||||
if (num_channels < 1 || num_channels > AudioDecoder::kMaxNumberOfChannels ||
|
||||
num_streams < 0 || coupled_streams < 0) {
|
||||
return false;
|
||||
}
|
||||
if (num_streams < coupled_streams) {
|
||||
|
||||
@ -51,7 +51,10 @@ absl::optional<AudioDecoderOpus::Config> AudioDecoderOpus::SdpToConfig(
|
||||
num_channels) {
|
||||
Config config;
|
||||
config.num_channels = *num_channels;
|
||||
RTC_DCHECK(config.IsOk());
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return absl::nullopt;
|
||||
}
|
||||
return config;
|
||||
} else {
|
||||
return absl::nullopt;
|
||||
@ -70,8 +73,12 @@ void AudioDecoderOpus::AppendSupportedDecoders(
|
||||
|
||||
std::unique_ptr<AudioDecoder> AudioDecoderOpus::MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
RTC_DCHECK(config.IsOk());
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<AudioDecoderOpusImpl>(config.num_channels,
|
||||
config.sample_rate_hz);
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/audio_codecs/audio_codec_pair_id.h"
|
||||
#include "api/audio_codecs/audio_decoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -34,7 +35,8 @@ struct RTC_EXPORT AudioDecoderOpus {
|
||||
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
|
||||
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
|
||||
Config config,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -66,7 +66,8 @@ AudioCodecInfo AudioEncoderMultiChannelOpus::QueryAudioEncoder(
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderMultiChannelOpus::MakeAudioEncoder(
|
||||
const AudioEncoderMultiChannelOpusConfig& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
return AudioEncoderMultiChannelOpusImpl::MakeAudioEncoder(config,
|
||||
payload_type);
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus_config.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -33,7 +34,8 @@ struct RTC_EXPORT AudioEncoderMultiChannelOpus {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -38,7 +38,7 @@ operator=(const AudioEncoderMultiChannelOpusConfig&) = default;
|
||||
bool AudioEncoderMultiChannelOpusConfig::IsOk() const {
|
||||
if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
|
||||
return false;
|
||||
if (num_channels < 0 || num_channels >= 255) {
|
||||
if (num_channels >= 255) {
|
||||
return false;
|
||||
}
|
||||
if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps)
|
||||
@ -47,7 +47,7 @@ bool AudioEncoderMultiChannelOpusConfig::IsOk() const {
|
||||
return false;
|
||||
|
||||
// Check the lengths:
|
||||
if (num_channels < 0 || num_streams < 0 || coupled_streams < 0) {
|
||||
if (num_streams < 0 || coupled_streams < 0) {
|
||||
return false;
|
||||
}
|
||||
if (num_streams < coupled_streams) {
|
||||
|
||||
@ -32,7 +32,12 @@ AudioCodecInfo AudioEncoderOpus::QueryAudioEncoder(
|
||||
std::unique_ptr<AudioEncoder> AudioEncoderOpus::MakeAudioEncoder(
|
||||
const AudioEncoderOpusConfig& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/) {
|
||||
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
|
||||
const FieldTrialsView* field_trials) {
|
||||
if (!config.IsOk()) {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
return AudioEncoderOpusImpl::MakeAudioEncoder(config, payload_type);
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "api/audio_codecs/audio_encoder.h"
|
||||
#include "api/audio_codecs/audio_format.h"
|
||||
#include "api/audio_codecs/opus/audio_encoder_opus_config.h"
|
||||
#include "api/field_trials_view.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -34,7 +35,8 @@ struct RTC_EXPORT AudioEncoderOpus {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const AudioEncoderOpusConfig& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -61,7 +61,7 @@ bool AudioEncoderOpusConfig::IsOk() const {
|
||||
// well; we can add support for them when needed.)
|
||||
return false;
|
||||
}
|
||||
if (num_channels < 0 || num_channels >= 255) {
|
||||
if (num_channels >= 255) {
|
||||
return false;
|
||||
}
|
||||
if (!bitrate_bps)
|
||||
|
||||
@ -49,10 +49,10 @@ struct RTC_EXPORT AudioEncoderOpusConfig {
|
||||
bool cbr_enabled;
|
||||
int max_playback_rate_hz;
|
||||
|
||||
// |complexity| is used when the bitrate goes above
|
||||
// |complexity_threshold_bps| + |complexity_threshold_window_bps|;
|
||||
// |low_rate_complexity| is used when the bitrate falls below
|
||||
// |complexity_threshold_bps| - |complexity_threshold_window_bps|. In the
|
||||
// `complexity` is used when the bitrate goes above
|
||||
// `complexity_threshold_bps` + `complexity_threshold_window_bps`;
|
||||
// `low_rate_complexity` is used when the bitrate falls below
|
||||
// `complexity_threshold_bps` - `complexity_threshold_window_bps`. In the
|
||||
// interval in the middle, we keep using the most recent of the two
|
||||
// complexity settings.
|
||||
int complexity;
|
||||
|
||||
@ -37,8 +37,10 @@ struct NotAdvertised {
|
||||
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
|
||||
const Config& config,
|
||||
int payload_type,
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt) {
|
||||
return T::MakeAudioEncoder(config, payload_type, codec_pair_id);
|
||||
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
|
||||
const FieldTrialsView* field_trials = nullptr) {
|
||||
return T::MakeAudioEncoder(config, payload_type, codec_pair_id,
|
||||
field_trials);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -21,8 +21,8 @@ if (rtc_include_tests) {
|
||||
]
|
||||
deps = [
|
||||
"..:audio_codecs_api",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../test:audio_codec_mocks",
|
||||
"../../../test:scoped_key_value_config",
|
||||
"../../../test:test_support",
|
||||
"../L16:audio_decoder_L16",
|
||||
"../L16:audio_encoder_L16",
|
||||
@ -32,10 +32,6 @@ if (rtc_include_tests) {
|
||||
"../g722:audio_encoder_g722",
|
||||
"../ilbc:audio_decoder_ilbc",
|
||||
"../ilbc:audio_encoder_ilbc",
|
||||
"../isac:audio_decoder_isac_fix",
|
||||
"../isac:audio_decoder_isac_float",
|
||||
"../isac:audio_encoder_isac_fix",
|
||||
"../isac:audio_encoder_isac_float",
|
||||
"../opus:audio_decoder_opus",
|
||||
"../opus:audio_encoder_opus",
|
||||
]
|
||||
|
||||
@ -16,12 +16,11 @@
|
||||
#include "api/audio_codecs/g711/audio_decoder_g711.h"
|
||||
#include "api/audio_codecs/g722/audio_decoder_g722.h"
|
||||
#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h"
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h"
|
||||
#include "api/audio_codecs/isac/audio_decoder_isac_float.h"
|
||||
#include "api/audio_codecs/opus/audio_decoder_opus.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/mock_audio_decoder.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -77,9 +76,11 @@ struct AudioDecoderFakeApi {
|
||||
} // namespace
|
||||
|
||||
TEST(AudioDecoderFactoryTemplateTest, NoDecoderTypes) {
|
||||
test::ScopedKeyValueConfig field_trials;
|
||||
rtc::scoped_refptr<AudioDecoderFactory> factory(
|
||||
new rtc::RefCountedObject<
|
||||
audio_decoder_factory_template_impl::AudioDecoderFactoryT<>>());
|
||||
rtc::make_ref_counted<
|
||||
audio_decoder_factory_template_impl::AudioDecoderFactoryT<>>(
|
||||
&field_trials));
|
||||
EXPECT_THAT(factory->GetSupportedDecoders(), ::testing::IsEmpty());
|
||||
EXPECT_FALSE(factory->IsSupportedDecoder({"foo", 8000, 1}));
|
||||
EXPECT_EQ(nullptr,
|
||||
@ -179,41 +180,6 @@ TEST(AudioDecoderFactoryTemplateTest, Ilbc) {
|
||||
EXPECT_EQ(8000, dec->SampleRateHz());
|
||||
}
|
||||
|
||||
TEST(AudioDecoderFactoryTemplateTest, IsacFix) {
|
||||
auto factory = CreateAudioDecoderFactory<AudioDecoderIsacFix>();
|
||||
EXPECT_THAT(factory->GetSupportedDecoders(),
|
||||
::testing::ElementsAre(AudioCodecSpec{
|
||||
{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}}));
|
||||
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 16000, 2}));
|
||||
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 16000, 1}));
|
||||
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 32000, 1}));
|
||||
EXPECT_EQ(nullptr,
|
||||
factory->MakeAudioDecoder({"isac", 8000, 1}, absl::nullopt));
|
||||
auto dec = factory->MakeAudioDecoder({"isac", 16000, 1}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, dec);
|
||||
EXPECT_EQ(16000, dec->SampleRateHz());
|
||||
}
|
||||
|
||||
TEST(AudioDecoderFactoryTemplateTest, IsacFloat) {
|
||||
auto factory = CreateAudioDecoderFactory<AudioDecoderIsacFloat>();
|
||||
EXPECT_THAT(
|
||||
factory->GetSupportedDecoders(),
|
||||
::testing::ElementsAre(
|
||||
AudioCodecSpec{{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}},
|
||||
AudioCodecSpec{{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}}));
|
||||
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 16000, 2}));
|
||||
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 16000, 1}));
|
||||
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 32000, 1}));
|
||||
EXPECT_EQ(nullptr,
|
||||
factory->MakeAudioDecoder({"isac", 8000, 1}, absl::nullopt));
|
||||
auto dec1 = factory->MakeAudioDecoder({"isac", 16000, 1}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, dec1);
|
||||
EXPECT_EQ(16000, dec1->SampleRateHz());
|
||||
auto dec2 = factory->MakeAudioDecoder({"isac", 32000, 1}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, dec2);
|
||||
EXPECT_EQ(32000, dec2->SampleRateHz());
|
||||
}
|
||||
|
||||
TEST(AudioDecoderFactoryTemplateTest, L16) {
|
||||
auto factory = CreateAudioDecoderFactory<AudioDecoderL16>();
|
||||
EXPECT_THAT(
|
||||
|
||||
@ -16,12 +16,11 @@
|
||||
#include "api/audio_codecs/g711/audio_encoder_g711.h"
|
||||
#include "api/audio_codecs/g722/audio_encoder_g722.h"
|
||||
#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h"
|
||||
#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
|
||||
#include "api/audio_codecs/opus/audio_encoder_opus.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/mock_audio_encoder.h"
|
||||
#include "test/scoped_key_value_config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -77,9 +76,11 @@ struct AudioEncoderFakeApi {
|
||||
} // namespace
|
||||
|
||||
TEST(AudioEncoderFactoryTemplateTest, NoEncoderTypes) {
|
||||
test::ScopedKeyValueConfig field_trials;
|
||||
rtc::scoped_refptr<AudioEncoderFactory> factory(
|
||||
new rtc::RefCountedObject<
|
||||
audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>());
|
||||
rtc::make_ref_counted<
|
||||
audio_encoder_factory_template_impl::AudioEncoderFactoryT<>>(
|
||||
&field_trials));
|
||||
EXPECT_THAT(factory->GetSupportedEncoders(), ::testing::IsEmpty());
|
||||
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"foo", 8000, 1}));
|
||||
EXPECT_EQ(nullptr,
|
||||
@ -177,49 +178,6 @@ TEST(AudioEncoderFactoryTemplateTest, Ilbc) {
|
||||
EXPECT_EQ(8000, enc->SampleRateHz());
|
||||
}
|
||||
|
||||
TEST(AudioEncoderFactoryTemplateTest, IsacFix) {
|
||||
auto factory = CreateAudioEncoderFactory<AudioEncoderIsacFix>();
|
||||
EXPECT_THAT(factory->GetSupportedEncoders(),
|
||||
::testing::ElementsAre(AudioCodecSpec{
|
||||
{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}}));
|
||||
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 16000, 2}));
|
||||
EXPECT_EQ(AudioCodecInfo(16000, 1, 32000, 10000, 32000),
|
||||
factory->QueryAudioEncoder({"isac", 16000, 1}));
|
||||
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 32000, 1}));
|
||||
EXPECT_EQ(nullptr,
|
||||
factory->MakeAudioEncoder(17, {"isac", 8000, 1}, absl::nullopt));
|
||||
auto enc1 = factory->MakeAudioEncoder(17, {"isac", 16000, 1}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, enc1);
|
||||
EXPECT_EQ(16000, enc1->SampleRateHz());
|
||||
EXPECT_EQ(3u, enc1->Num10MsFramesInNextPacket());
|
||||
auto enc2 = factory->MakeAudioEncoder(
|
||||
17, {"isac", 16000, 1, {{"ptime", "60"}}}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, enc2);
|
||||
EXPECT_EQ(6u, enc2->Num10MsFramesInNextPacket());
|
||||
}
|
||||
|
||||
TEST(AudioEncoderFactoryTemplateTest, IsacFloat) {
|
||||
auto factory = CreateAudioEncoderFactory<AudioEncoderIsacFloat>();
|
||||
EXPECT_THAT(
|
||||
factory->GetSupportedEncoders(),
|
||||
::testing::ElementsAre(
|
||||
AudioCodecSpec{{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}},
|
||||
AudioCodecSpec{{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}}));
|
||||
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 16000, 2}));
|
||||
EXPECT_EQ(AudioCodecInfo(16000, 1, 32000, 10000, 32000),
|
||||
factory->QueryAudioEncoder({"isac", 16000, 1}));
|
||||
EXPECT_EQ(AudioCodecInfo(32000, 1, 56000, 10000, 56000),
|
||||
factory->QueryAudioEncoder({"isac", 32000, 1}));
|
||||
EXPECT_EQ(nullptr,
|
||||
factory->MakeAudioEncoder(17, {"isac", 8000, 1}, absl::nullopt));
|
||||
auto enc1 = factory->MakeAudioEncoder(17, {"isac", 16000, 1}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, enc1);
|
||||
EXPECT_EQ(16000, enc1->SampleRateHz());
|
||||
auto enc2 = factory->MakeAudioEncoder(17, {"isac", 32000, 1}, absl::nullopt);
|
||||
ASSERT_NE(nullptr, enc2);
|
||||
EXPECT_EQ(32000, enc2->SampleRateHz());
|
||||
}
|
||||
|
||||
TEST(AudioEncoderFactoryTemplateTest, L16) {
|
||||
auto factory = CreateAudioEncoderFactory<AudioEncoderL16>();
|
||||
EXPECT_THAT(
|
||||
|
||||
@ -52,19 +52,10 @@ void AudioOptions::SetAll(const AudioOptions& change) {
|
||||
change.audio_jitter_buffer_fast_accelerate);
|
||||
SetFrom(&audio_jitter_buffer_min_delay_ms,
|
||||
change.audio_jitter_buffer_min_delay_ms);
|
||||
SetFrom(&audio_jitter_buffer_enable_rtx_handling,
|
||||
change.audio_jitter_buffer_enable_rtx_handling);
|
||||
SetFrom(&typing_detection, change.typing_detection);
|
||||
SetFrom(&experimental_agc, change.experimental_agc);
|
||||
SetFrom(&experimental_ns, change.experimental_ns);
|
||||
SetFrom(&residual_echo_detector, change.residual_echo_detector);
|
||||
SetFrom(&tx_agc_target_dbov, change.tx_agc_target_dbov);
|
||||
SetFrom(&tx_agc_digital_compression_gain,
|
||||
change.tx_agc_digital_compression_gain);
|
||||
SetFrom(&tx_agc_limiter, change.tx_agc_limiter);
|
||||
SetFrom(&combined_audio_video_bwe, change.combined_audio_video_bwe);
|
||||
SetFrom(&audio_network_adaptor, change.audio_network_adaptor);
|
||||
SetFrom(&audio_network_adaptor_config, change.audio_network_adaptor_config);
|
||||
SetFrom(&init_recording_on_send, change.init_recording_on_send);
|
||||
}
|
||||
|
||||
bool AudioOptions::operator==(const AudioOptions& o) const {
|
||||
@ -81,18 +72,10 @@ bool AudioOptions::operator==(const AudioOptions& o) const {
|
||||
o.audio_jitter_buffer_fast_accelerate &&
|
||||
audio_jitter_buffer_min_delay_ms ==
|
||||
o.audio_jitter_buffer_min_delay_ms &&
|
||||
audio_jitter_buffer_enable_rtx_handling ==
|
||||
o.audio_jitter_buffer_enable_rtx_handling &&
|
||||
typing_detection == o.typing_detection &&
|
||||
experimental_agc == o.experimental_agc &&
|
||||
experimental_ns == o.experimental_ns &&
|
||||
residual_echo_detector == o.residual_echo_detector &&
|
||||
tx_agc_target_dbov == o.tx_agc_target_dbov &&
|
||||
tx_agc_digital_compression_gain == o.tx_agc_digital_compression_gain &&
|
||||
tx_agc_limiter == o.tx_agc_limiter &&
|
||||
combined_audio_video_bwe == o.combined_audio_video_bwe &&
|
||||
audio_network_adaptor == o.audio_network_adaptor &&
|
||||
audio_network_adaptor_config == o.audio_network_adaptor_config;
|
||||
audio_network_adaptor_config == o.audio_network_adaptor_config &&
|
||||
init_recording_on_send == o.init_recording_on_send;
|
||||
}
|
||||
|
||||
std::string AudioOptions::ToString() const {
|
||||
@ -114,18 +97,9 @@ std::string AudioOptions::ToString() const {
|
||||
audio_jitter_buffer_fast_accelerate);
|
||||
ToStringIfSet(&result, "audio_jitter_buffer_min_delay_ms",
|
||||
audio_jitter_buffer_min_delay_ms);
|
||||
ToStringIfSet(&result, "audio_jitter_buffer_enable_rtx_handling",
|
||||
audio_jitter_buffer_enable_rtx_handling);
|
||||
ToStringIfSet(&result, "typing", typing_detection);
|
||||
ToStringIfSet(&result, "experimental_agc", experimental_agc);
|
||||
ToStringIfSet(&result, "experimental_ns", experimental_ns);
|
||||
ToStringIfSet(&result, "residual_echo_detector", residual_echo_detector);
|
||||
ToStringIfSet(&result, "tx_agc_target_dbov", tx_agc_target_dbov);
|
||||
ToStringIfSet(&result, "tx_agc_digital_compression_gain",
|
||||
tx_agc_digital_compression_gain);
|
||||
ToStringIfSet(&result, "tx_agc_limiter", tx_agc_limiter);
|
||||
ToStringIfSet(&result, "combined_audio_video_bwe", combined_audio_video_bwe);
|
||||
ToStringIfSet(&result, "audio_network_adaptor", audio_network_adaptor);
|
||||
ToStringIfSet(&result, "init_recording_on_send", init_recording_on_send);
|
||||
result << "}";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
@ -58,17 +58,6 @@ struct RTC_EXPORT AudioOptions {
|
||||
absl::optional<bool> audio_jitter_buffer_fast_accelerate;
|
||||
// Audio receiver jitter buffer (NetEq) minimum target delay in milliseconds.
|
||||
absl::optional<int> audio_jitter_buffer_min_delay_ms;
|
||||
// Audio receiver jitter buffer (NetEq) should handle retransmitted packets.
|
||||
absl::optional<bool> audio_jitter_buffer_enable_rtx_handling;
|
||||
// Audio processing to detect typing.
|
||||
absl::optional<bool> typing_detection;
|
||||
absl::optional<bool> experimental_agc;
|
||||
absl::optional<bool> experimental_ns;
|
||||
// Note that tx_agc_* only applies to non-experimental AGC.
|
||||
absl::optional<bool> residual_echo_detector;
|
||||
absl::optional<uint16_t> tx_agc_target_dbov;
|
||||
absl::optional<uint16_t> tx_agc_digital_compression_gain;
|
||||
absl::optional<bool> tx_agc_limiter;
|
||||
// Enable combined audio+bandwidth BWE.
|
||||
// TODO(pthatcher): This flag is set from the
|
||||
// "googCombinedAudioVideoBwe", but not used anywhere. So delete it,
|
||||
@ -80,6 +69,10 @@ struct RTC_EXPORT AudioOptions {
|
||||
absl::optional<bool> audio_network_adaptor;
|
||||
// Config string for audio network adaptor.
|
||||
absl::optional<std::string> audio_network_adaptor_config;
|
||||
// Pre-initialize the ADM for recording when starting to send. Default to
|
||||
// true.
|
||||
// TODO(webrtc:13566): Remove this option. See issue for details.
|
||||
absl::optional<bool> init_recording_on_send;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -11,13 +11,8 @@
|
||||
#ifndef API_CALL_AUDIO_SINK_H_
|
||||
#define API_CALL_AUDIO_SINK_H_
|
||||
|
||||
#if defined(WEBRTC_POSIX) && !defined(__STDC_FORMAT_MACROS)
|
||||
// Avoid conflict with format_macros.h.
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ struct BitrateAllocationUpdate {
|
||||
double packet_loss_ratio = 0;
|
||||
// Predicted round trip time.
|
||||
TimeDelta round_trip_time = TimeDelta::PlusInfinity();
|
||||
// |bwe_period| is deprecated, use |stable_target_bitrate| allocation instead.
|
||||
// `bwe_period` is deprecated, use `stable_target_bitrate` allocation instead.
|
||||
TimeDelta bwe_period = TimeDelta::PlusInfinity();
|
||||
// Congestion window pushback bitrate reduction fraction. Used in
|
||||
// VideoStreamEncoder to reduce the bitrate by the given fraction
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <vector>
|
||||
#include "api/ref_counted_base.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -30,7 +31,7 @@ struct PacketOptions {
|
||||
int packet_id = -1;
|
||||
// Additional data bound to the RTP packet for use in application code,
|
||||
// outside of WebRTC.
|
||||
std::vector<uint8_t> application_data;
|
||||
rtc::scoped_refptr<rtc::RefCountedBase> additional_data;
|
||||
// Whether this is a retransmission of an earlier packet.
|
||||
bool is_retransmit = false;
|
||||
bool included_in_feedback = false;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include "rtc_base/helpers.h"
|
||||
#include "rtc_base/ip_address.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
|
||||
namespace cricket {
|
||||
@ -21,19 +22,20 @@ Candidate::Candidate()
|
||||
component_(0),
|
||||
priority_(0),
|
||||
network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
|
||||
underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
|
||||
generation_(0),
|
||||
network_id_(0),
|
||||
network_cost_(0) {}
|
||||
|
||||
Candidate::Candidate(int component,
|
||||
const std::string& protocol,
|
||||
absl::string_view protocol,
|
||||
const rtc::SocketAddress& address,
|
||||
uint32_t priority,
|
||||
const std::string& username,
|
||||
const std::string& password,
|
||||
const std::string& type,
|
||||
absl::string_view username,
|
||||
absl::string_view password,
|
||||
absl::string_view type,
|
||||
uint32_t generation,
|
||||
const std::string& foundation,
|
||||
absl::string_view foundation,
|
||||
uint16_t network_id,
|
||||
uint16_t network_cost)
|
||||
: id_(rtc::CreateRandomString(8)),
|
||||
@ -45,6 +47,7 @@ Candidate::Candidate(int component,
|
||||
password_(password),
|
||||
type_(type),
|
||||
network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
|
||||
underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
|
||||
generation_(generation),
|
||||
foundation_(foundation),
|
||||
network_id_(network_id),
|
||||
@ -91,7 +94,7 @@ uint32_t Candidate::GetPriority(uint32_t type_preference,
|
||||
// (2^8)*(local preference) +
|
||||
// (2^0)*(256 - component ID)
|
||||
|
||||
// |local_preference| length is 2 bytes, 0-65535 inclusive.
|
||||
// `local_preference` length is 2 bytes, 0-65535 inclusive.
|
||||
// In our implemenation we will partion local_preference into
|
||||
// 0 1
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
@ -100,7 +103,9 @@ uint32_t Candidate::GetPriority(uint32_t type_preference,
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired.
|
||||
// Addr Pref - Address preference value as per RFC 3484.
|
||||
// local preference = (NIC Type << 8 | Addr_Pref) - relay preference.
|
||||
// local preference = (NIC Type << 8 | Addr_Pref) + relay preference.
|
||||
// The relay preference is based on the number of TURN servers, the
|
||||
// first TURN server gets the highest preference.
|
||||
|
||||
int addr_pref = IPAddressPrecedence(address_.ipaddr());
|
||||
int local_preference =
|
||||
@ -129,9 +134,21 @@ Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
|
||||
bool filter_related_address) const {
|
||||
Candidate copy(*this);
|
||||
if (use_hostname_address) {
|
||||
rtc::SocketAddress hostname_only_addr(address().hostname(),
|
||||
address().port());
|
||||
copy.set_address(hostname_only_addr);
|
||||
rtc::IPAddress ip;
|
||||
if (address().hostname().empty()) {
|
||||
// IP needs to be redacted, but no hostname available.
|
||||
rtc::SocketAddress redacted_addr("redacted-ip.invalid", address().port());
|
||||
copy.set_address(redacted_addr);
|
||||
} else if (IPFromString(address().hostname(), &ip)) {
|
||||
// The hostname is an IP literal, and needs to be redacted too.
|
||||
rtc::SocketAddress redacted_addr("redacted-literal.invalid",
|
||||
address().port());
|
||||
copy.set_address(redacted_addr);
|
||||
} else {
|
||||
rtc::SocketAddress hostname_only_addr(address().hostname(),
|
||||
address().port());
|
||||
copy.set_address(hostname_only_addr);
|
||||
}
|
||||
}
|
||||
if (filter_related_address) {
|
||||
copy.set_related_address(
|
||||
@ -140,4 +157,11 @@ Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
|
||||
return copy;
|
||||
}
|
||||
|
||||
void Candidate::Assign(std::string& s, absl::string_view view) {
|
||||
// Assigning via a temporary object, like s = std::string(view), results in
|
||||
// binary size bloat. To avoid that, extract pointer and size from the
|
||||
// string view, and use std::string::assign method.
|
||||
s.assign(view.data(), view.size());
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/network_constants.h"
|
||||
#include "rtc_base/socket_address.h"
|
||||
@ -24,6 +25,10 @@
|
||||
|
||||
namespace cricket {
|
||||
|
||||
// TURN servers are limited to 32 in accordance with
|
||||
// https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers
|
||||
static constexpr size_t kMaxTurnServers = 32;
|
||||
|
||||
// Candidate for ICE based connection discovery.
|
||||
// TODO(phoglund): remove things in here that are not needed in the public API.
|
||||
|
||||
@ -33,32 +38,32 @@ class RTC_EXPORT Candidate {
|
||||
// TODO(pthatcher): Match the ordering and param list as per RFC 5245
|
||||
// candidate-attribute syntax. http://tools.ietf.org/html/rfc5245#section-15.1
|
||||
Candidate(int component,
|
||||
const std::string& protocol,
|
||||
absl::string_view protocol,
|
||||
const rtc::SocketAddress& address,
|
||||
uint32_t priority,
|
||||
const std::string& username,
|
||||
const std::string& password,
|
||||
const std::string& type,
|
||||
absl::string_view username,
|
||||
absl::string_view password,
|
||||
absl::string_view type,
|
||||
uint32_t generation,
|
||||
const std::string& foundation,
|
||||
absl::string_view foundation,
|
||||
uint16_t network_id = 0,
|
||||
uint16_t network_cost = 0);
|
||||
Candidate(const Candidate&);
|
||||
~Candidate();
|
||||
|
||||
const std::string& id() const { return id_; }
|
||||
void set_id(const std::string& id) { id_ = id; }
|
||||
void set_id(absl::string_view id) { Assign(id_, id); }
|
||||
|
||||
int component() const { return component_; }
|
||||
void set_component(int component) { component_ = component; }
|
||||
|
||||
const std::string& protocol() const { return protocol_; }
|
||||
void set_protocol(const std::string& protocol) { protocol_ = protocol; }
|
||||
void set_protocol(absl::string_view protocol) { Assign(protocol_, protocol); }
|
||||
|
||||
// The protocol used to talk to relay.
|
||||
const std::string& relay_protocol() const { return relay_protocol_; }
|
||||
void set_relay_protocol(const std::string& protocol) {
|
||||
relay_protocol_ = protocol;
|
||||
void set_relay_protocol(absl::string_view protocol) {
|
||||
Assign(relay_protocol_, protocol);
|
||||
}
|
||||
|
||||
const rtc::SocketAddress& address() const { return address_; }
|
||||
@ -90,17 +95,17 @@ class RTC_EXPORT Candidate {
|
||||
|
||||
// TODO(honghaiz): Change to usernameFragment or ufrag.
|
||||
const std::string& username() const { return username_; }
|
||||
void set_username(const std::string& username) { username_ = username; }
|
||||
void set_username(absl::string_view username) { Assign(username_, username); }
|
||||
|
||||
const std::string& password() const { return password_; }
|
||||
void set_password(const std::string& password) { password_ = password; }
|
||||
void set_password(absl::string_view password) { Assign(password_, password); }
|
||||
|
||||
const std::string& type() const { return type_; }
|
||||
void set_type(const std::string& type) { type_ = type; }
|
||||
void set_type(absl::string_view type) { Assign(type_, type); }
|
||||
|
||||
const std::string& network_name() const { return network_name_; }
|
||||
void set_network_name(const std::string& network_name) {
|
||||
network_name_ = network_name;
|
||||
void set_network_name(absl::string_view network_name) {
|
||||
Assign(network_name_, network_name);
|
||||
}
|
||||
|
||||
rtc::AdapterType network_type() const { return network_type_; }
|
||||
@ -108,11 +113,18 @@ class RTC_EXPORT Candidate {
|
||||
network_type_ = network_type;
|
||||
}
|
||||
|
||||
rtc::AdapterType underlying_type_for_vpn() const {
|
||||
return underlying_type_for_vpn_;
|
||||
}
|
||||
void set_underlying_type_for_vpn(rtc::AdapterType network_type) {
|
||||
underlying_type_for_vpn_ = network_type;
|
||||
}
|
||||
|
||||
// Candidates in a new generation replace those in the old generation.
|
||||
uint32_t generation() const { return generation_; }
|
||||
void set_generation(uint32_t generation) { generation_ = generation; }
|
||||
|
||||
// |network_cost| measures the cost/penalty of using this candidate. A network
|
||||
// `network_cost` measures the cost/penalty of using this candidate. A network
|
||||
// cost of 0 indicates this candidate can be used freely. A value of
|
||||
// rtc::kNetworkCostMax indicates it should be used only as the last resort.
|
||||
void set_network_cost(uint16_t network_cost) {
|
||||
@ -126,8 +138,8 @@ class RTC_EXPORT Candidate {
|
||||
void set_network_id(uint16_t network_id) { network_id_ = network_id; }
|
||||
|
||||
const std::string& foundation() const { return foundation_; }
|
||||
void set_foundation(const std::string& foundation) {
|
||||
foundation_ = foundation;
|
||||
void set_foundation(absl::string_view foundation) {
|
||||
Assign(foundation_, foundation);
|
||||
}
|
||||
|
||||
const rtc::SocketAddress& related_address() const { return related_address_; }
|
||||
@ -135,18 +147,18 @@ class RTC_EXPORT Candidate {
|
||||
related_address_ = related_address;
|
||||
}
|
||||
const std::string& tcptype() const { return tcptype_; }
|
||||
void set_tcptype(const std::string& tcptype) { tcptype_ = tcptype; }
|
||||
void set_tcptype(absl::string_view tcptype) { Assign(tcptype_, tcptype); }
|
||||
|
||||
// The name of the transport channel of this candidate.
|
||||
// TODO(phoglund): remove.
|
||||
const std::string& transport_name() const { return transport_name_; }
|
||||
void set_transport_name(const std::string& transport_name) {
|
||||
transport_name_ = transport_name;
|
||||
void set_transport_name(absl::string_view transport_name) {
|
||||
Assign(transport_name_, transport_name);
|
||||
}
|
||||
|
||||
// The URL of the ICE server which this candidate is gathered from.
|
||||
const std::string& url() const { return url_; }
|
||||
void set_url(const std::string& url) { url_ = url; }
|
||||
void set_url(absl::string_view url) { Assign(url_, url); }
|
||||
|
||||
// Determines whether this candidate is equivalent to the given one.
|
||||
bool IsEquivalent(const Candidate& c) const;
|
||||
@ -167,9 +179,9 @@ class RTC_EXPORT Candidate {
|
||||
bool operator!=(const Candidate& o) const;
|
||||
|
||||
// Returns a sanitized copy configured by the given booleans. If
|
||||
// |use_host_address| is true, the returned copy has its IP removed from
|
||||
// |address()|, which leads |address()| to be a hostname address. If
|
||||
// |filter_related_address|, the returned copy has its related address reset
|
||||
// `use_host_address` is true, the returned copy has its IP removed from
|
||||
// `address()`, which leads `address()` to be a hostname address. If
|
||||
// `filter_related_address`, the returned copy has its related address reset
|
||||
// to the wildcard address (i.e. 0.0.0.0 for IPv4 and :: for IPv6). Note that
|
||||
// setting both booleans to false returns an identical copy to the original
|
||||
// candidate.
|
||||
@ -177,6 +189,10 @@ class RTC_EXPORT Candidate {
|
||||
bool filter_related_address) const;
|
||||
|
||||
private:
|
||||
// TODO(bugs.webrtc.org/13220): With C++17, we get a std::string assignment
|
||||
// operator accepting any object implicitly convertible to std::string_view,
|
||||
// and then we don't need this workaround.
|
||||
static void Assign(std::string& s, absl::string_view view);
|
||||
std::string ToStringInternal(bool sensitive) const;
|
||||
|
||||
std::string id_;
|
||||
@ -190,6 +206,7 @@ class RTC_EXPORT Candidate {
|
||||
std::string type_;
|
||||
std::string network_name_;
|
||||
rtc::AdapterType network_type_;
|
||||
rtc::AdapterType underlying_type_for_vpn_;
|
||||
uint32_t generation_;
|
||||
std::string foundation_;
|
||||
rtc::SocketAddress related_address_;
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "api/rtc_event_log/rtc_event_log_factory.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "api/task_queue/default_task_queue_factory.h"
|
||||
#include "api/transport/field_trial_based_config.h"
|
||||
#include "media/base/media_engine.h"
|
||||
#include "media/engine/webrtc_media_engine.h"
|
||||
#include "modules/audio_device/include/audio_device.h"
|
||||
@ -36,21 +37,34 @@ rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
|
||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
|
||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
|
||||
rtc::scoped_refptr<AudioMixer> audio_mixer,
|
||||
rtc::scoped_refptr<AudioProcessing> audio_processing) {
|
||||
rtc::scoped_refptr<AudioProcessing> audio_processing,
|
||||
AudioFrameProcessor* audio_frame_processor,
|
||||
std::unique_ptr<FieldTrialsView> field_trials) {
|
||||
if (!field_trials) {
|
||||
field_trials = std::make_unique<webrtc::FieldTrialBasedConfig>();
|
||||
}
|
||||
|
||||
PeerConnectionFactoryDependencies dependencies;
|
||||
dependencies.network_thread = network_thread;
|
||||
dependencies.worker_thread = worker_thread;
|
||||
dependencies.signaling_thread = signaling_thread;
|
||||
dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
|
||||
dependencies.task_queue_factory =
|
||||
CreateDefaultTaskQueueFactory(field_trials.get());
|
||||
dependencies.call_factory = CreateCallFactory();
|
||||
dependencies.event_log_factory = std::make_unique<RtcEventLogFactory>(
|
||||
dependencies.task_queue_factory.get());
|
||||
dependencies.trials = std::move(field_trials);
|
||||
|
||||
if (network_thread) {
|
||||
// TODO(bugs.webrtc.org/13145): Add an rtc::SocketFactory* argument.
|
||||
dependencies.socket_factory = network_thread->socketserver();
|
||||
}
|
||||
cricket::MediaEngineDependencies media_dependencies;
|
||||
media_dependencies.task_queue_factory = dependencies.task_queue_factory.get();
|
||||
media_dependencies.adm = std::move(default_adm);
|
||||
media_dependencies.audio_encoder_factory = std::move(audio_encoder_factory);
|
||||
media_dependencies.audio_decoder_factory = std::move(audio_decoder_factory);
|
||||
media_dependencies.audio_frame_processor = audio_frame_processor;
|
||||
if (audio_processing) {
|
||||
media_dependencies.audio_processing = std::move(audio_processing);
|
||||
} else {
|
||||
@ -59,6 +73,7 @@ rtc::scoped_refptr<PeerConnectionFactoryInterface> CreatePeerConnectionFactory(
|
||||
media_dependencies.audio_mixer = std::move(audio_mixer);
|
||||
media_dependencies.video_encoder_factory = std::move(video_encoder_factory);
|
||||
media_dependencies.video_decoder_factory = std::move(video_decoder_factory);
|
||||
media_dependencies.trials = dependencies.trials.get();
|
||||
dependencies.media_engine =
|
||||
cricket::CreateMediaEngine(std::move(media_dependencies));
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ class Thread;
|
||||
namespace webrtc {
|
||||
|
||||
class AudioDeviceModule;
|
||||
class AudioFrameProcessor;
|
||||
class AudioProcessing;
|
||||
|
||||
// Create a new instance of PeerConnectionFactoryInterface with optional video
|
||||
@ -47,7 +48,9 @@ CreatePeerConnectionFactory(
|
||||
std::unique_ptr<VideoEncoderFactory> video_encoder_factory,
|
||||
std::unique_ptr<VideoDecoderFactory> video_decoder_factory,
|
||||
rtc::scoped_refptr<AudioMixer> audio_mixer,
|
||||
rtc::scoped_refptr<AudioProcessing> audio_processing);
|
||||
rtc::scoped_refptr<AudioProcessing> audio_processing,
|
||||
AudioFrameProcessor* audio_frame_processor = nullptr,
|
||||
std::unique_ptr<FieldTrialsView> field_trials = nullptr);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
@ -32,24 +32,24 @@ CryptoOptions CryptoOptions::NoGcm() {
|
||||
|
||||
std::vector<int> CryptoOptions::GetSupportedDtlsSrtpCryptoSuites() const {
|
||||
std::vector<int> crypto_suites;
|
||||
// Note: SRTP_AES128_CM_SHA1_80 is what is required to be supported (by
|
||||
// draft-ietf-rtcweb-security-arch), but SRTP_AES128_CM_SHA1_32 is allowed as
|
||||
// Note: kSrtpAes128CmSha1_80 is what is required to be supported (by
|
||||
// draft-ietf-rtcweb-security-arch), but kSrtpAes128CmSha1_32 is allowed as
|
||||
// well, and saves a few bytes per packet if it ends up selected.
|
||||
// As the cipher suite is potentially insecure, it will only be used if
|
||||
// enabled by both peers.
|
||||
if (srtp.enable_aes128_sha1_32_crypto_cipher) {
|
||||
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_32);
|
||||
crypto_suites.push_back(rtc::kSrtpAes128CmSha1_32);
|
||||
}
|
||||
if (srtp.enable_aes128_sha1_80_crypto_cipher) {
|
||||
crypto_suites.push_back(rtc::SRTP_AES128_CM_SHA1_80);
|
||||
crypto_suites.push_back(rtc::kSrtpAes128CmSha1_80);
|
||||
}
|
||||
|
||||
// Note: GCM cipher suites are not the top choice since they increase the
|
||||
// packet size. In order to negotiate them the other side must not support
|
||||
// SRTP_AES128_CM_SHA1_80.
|
||||
// kSrtpAes128CmSha1_80.
|
||||
if (srtp.enable_gcm_crypto_suites) {
|
||||
crypto_suites.push_back(rtc::SRTP_AEAD_AES_256_GCM);
|
||||
crypto_suites.push_back(rtc::SRTP_AEAD_AES_128_GCM);
|
||||
crypto_suites.push_back(rtc::kSrtpAeadAes256Gcm);
|
||||
crypto_suites.push_back(rtc::kSrtpAeadAes128Gcm);
|
||||
}
|
||||
RTC_CHECK(!crypto_suites.empty());
|
||||
return crypto_suites;
|
||||
|
||||
@ -44,7 +44,7 @@ struct RTC_EXPORT CryptoOptions {
|
||||
bool enable_gcm_crypto_suites = false;
|
||||
|
||||
// If set to true, the (potentially insecure) crypto cipher
|
||||
// SRTP_AES128_CM_SHA1_32 will be included in the list of supported ciphers
|
||||
// kSrtpAes128CmSha1_32 will be included in the list of supported ciphers
|
||||
// during negotiation. It will only be used if both peers support it and no
|
||||
// other ciphers get preferred.
|
||||
bool enable_aes128_sha1_32_crypto_cipher = false;
|
||||
|
||||
@ -27,7 +27,6 @@ namespace webrtc {
|
||||
// without it. You may assume that this interface will have the same lifetime
|
||||
// as the RTPReceiver it is attached to. It must only be attached to one
|
||||
// RTPReceiver. Additional data may be null.
|
||||
// Note: This interface is not ready for production use.
|
||||
class FrameDecryptorInterface : public rtc::RefCountInterface {
|
||||
public:
|
||||
// The Status enum represents all possible states that can be
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user