Revert of Reland "Move smoothing filter to common audio". (patchset #5 id:100001 of https://codereview.webrtc.org/2520003005/ )
Reason for revert:
Internal bots failed.
Original issue's description:
> Reland "Move smoothing filter to common audio".
>
> The original CL was this https://codereview.webrtc.org/2484153002/
>
> Due to failure with internal trial servers, it was reverted. This CL tries to reland it.
>
> BUG=webrtc:6443
>
> Committed: https://crrev.com/223641f1b903e41e77d88f03199b4cdb65255ec8
> Cr-Commit-Position: refs/heads/master@{#15227}
TBR=tommi@webrtc.org,solenberg@webrtc.org,terelius@webrtc.org,kjellander@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6443
Review-Url: https://codereview.webrtc.org/2529943002
Cr-Commit-Position: refs/heads/master@{#15228}
diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn
index 0dd4162..0e78abf 100644
--- a/webrtc/modules/audio_coding/BUILD.gn
+++ b/webrtc/modules/audio_coding/BUILD.gn
@@ -709,7 +709,6 @@
":audio_encoder_interface",
":audio_network_adaptor",
"../../base:rtc_base_approved",
- "../../base/analytics:rtc_analytics",
]
defines = []
@@ -765,6 +764,8 @@
"audio_network_adaptor/frame_length_controller.cc",
"audio_network_adaptor/frame_length_controller.h",
"audio_network_adaptor/include/audio_network_adaptor.h",
+ "audio_network_adaptor/smoothing_filter.cc",
+ "audio_network_adaptor/smoothing_filter.h",
]
deps = [
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h
index 62a3533..0c2388b 100644
--- a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h
@@ -14,8 +14,8 @@
#include <memory>
#include "webrtc/base/constructormagic.h"
-#include "webrtc/common_audio/smoothing_filter.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/controller.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
namespace webrtc {
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc
index 823763f..9bbec26 100644
--- a/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_unittest.cc
@@ -10,8 +10,8 @@
#include <utility>
-#include "webrtc/common_audio/mocks/mock_smoothing_filter.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h"
+#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_smoothing_filter.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
@@ -55,6 +55,7 @@
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
new NiceMock<MockSmoothingFilter>());
states.packet_loss_smoothed = mock_smoothing_filter.get();
+ EXPECT_CALL(*states.packet_loss_smoothed, Die());
using Threshold = FecController::Config::Threshold;
states.controller.reset(new FecController(
FecController::Config(
@@ -261,6 +262,7 @@
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
new NiceMock<MockSmoothingFilter>());
states.packet_loss_smoothed = mock_smoothing_filter.get();
+ EXPECT_CALL(*states.packet_loss_smoothed, Die());
using Threshold = FecController::Config::Threshold;
states.controller.reset(new FecController(
FecController::Config(
@@ -291,6 +293,7 @@
std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
new NiceMock<MockSmoothingFilter>());
states.packet_loss_smoothed = mock_smoothing_filter.get();
+ EXPECT_CALL(*states.packet_loss_smoothed, Die());
using Threshold = FecController::Config::Threshold;
EXPECT_DEATH(
states.controller.reset(new FecController(
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_smoothing_filter.h b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_smoothing_filter.h
new file mode 100644
index 0000000..745ca98
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_smoothing_filter.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_SMOOTHING_FILTER_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_SMOOTHING_FILTER_H_
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
+#include "webrtc/test/gmock.h"
+
+namespace webrtc {
+
+class MockSmoothingFilter : public SmoothingFilter {
+ public:
+ virtual ~MockSmoothingFilter() { Die(); }
+ MOCK_METHOD0(Die, void());
+ MOCK_METHOD1(AddSample, void(float));
+ MOCK_CONST_METHOD0(GetAverage, rtc::Optional<float>());
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_MOCK_MOCK_SMOOTHING_FILTER_H_
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.cc b/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.cc
new file mode 100644
index 0000000..8a81069
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.cc
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <cmath>
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
+
+namespace webrtc {
+
+SmoothingFilterImpl::SmoothingFilterImpl(int time_constant_ms,
+ const Clock* clock)
+ : time_constant_ms_(time_constant_ms),
+ clock_(clock),
+ first_sample_received_(false),
+ initialized_(false),
+ first_sample_time_ms_(0),
+ last_sample_time_ms_(0),
+ filter_(0.0) {}
+
+void SmoothingFilterImpl::AddSample(float sample) {
+ if (!first_sample_received_) {
+ last_sample_time_ms_ = first_sample_time_ms_ = clock_->TimeInMilliseconds();
+ first_sample_received_ = true;
+ RTC_DCHECK_EQ(rtc::ExpFilter::kValueUndefined, filter_.filtered());
+
+ // Since this is first sample, any value for argument 1 should work.
+ filter_.Apply(0.0f, sample);
+ return;
+ }
+
+ int64_t now_ms = clock_->TimeInMilliseconds();
+ if (!initialized_) {
+ float duration = now_ms - first_sample_time_ms_;
+ if (duration < static_cast<int64_t>(time_constant_ms_)) {
+ filter_.UpdateBase(exp(1.0f / duration));
+ } else {
+ initialized_ = true;
+ filter_.UpdateBase(exp(1.0f / time_constant_ms_));
+ }
+ }
+
+ // The filter will do the following:
+ // float alpha = pow(base, last_update_time_ms_ - now_ms);
+ // filtered_ = alpha * filtered_ + (1 - alpha) * sample;
+ filter_.Apply(static_cast<float>(last_sample_time_ms_ - now_ms), sample);
+ last_sample_time_ms_ = now_ms;
+}
+
+rtc::Optional<float> SmoothingFilterImpl::GetAverage() const {
+ float value = filter_.filtered();
+ return value == rtc::ExpFilter::kValueUndefined ? rtc::Optional<float>()
+ : rtc::Optional<float>(value);
+}
+
+} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h b/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h
new file mode 100644
index 0000000..c4de7b5
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_SMOOTHING_FILTER_H_
+#define WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_SMOOTHING_FILTER_H_
+
+#include "webrtc/base/constructormagic.h"
+#include "webrtc/base/exp_filter.h"
+#include "webrtc/base/optional.h"
+#include "webrtc/system_wrappers/include/clock.h"
+
+namespace webrtc {
+
+class SmoothingFilter {
+ public:
+ virtual ~SmoothingFilter() = default;
+ virtual void AddSample(float sample) = 0;
+ virtual rtc::Optional<float> GetAverage() const = 0;
+};
+
+// SmoothingFilterImpl applies an exponential filter
+// alpha = exp(-sample_interval / time_constant);
+// y[t] = alpha * y[t-1] + (1 - alpha) * sample;
+class SmoothingFilterImpl final : public SmoothingFilter {
+ public:
+ // |time_constant_ms| is the time constant for the exponential filter.
+ SmoothingFilterImpl(int time_constant_ms, const Clock* clock);
+
+ void AddSample(float sample) override;
+ rtc::Optional<float> GetAverage() const override;
+
+ private:
+ const int time_constant_ms_;
+ const Clock* const clock_;
+
+ bool first_sample_received_;
+ bool initialized_;
+ int64_t first_sample_time_ms_;
+ int64_t last_sample_time_ms_;
+ rtc::ExpFilter filter_;
+
+ RTC_DISALLOW_COPY_AND_ASSIGN(SmoothingFilterImpl);
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_AUDIO_CODING_AUDIO_NETWORK_ADAPTOR_SMOOTHING_FILTER_H_
diff --git a/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter_unittest.cc b/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter_unittest.cc
new file mode 100644
index 0000000..af4e8d9
--- /dev/null
+++ b/webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter_unittest.cc
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <memory>
+
+#include "webrtc/modules/audio_coding/audio_network_adaptor/smoothing_filter.h"
+#include "webrtc/test/gtest.h"
+
+namespace webrtc {
+
+namespace {
+
+constexpr int kTimeConstantMs = 1000;
+constexpr float kMaxAbsError = 0.0001f;
+constexpr int64_t kClockInitialTime = 123456;
+
+struct SmoothingFilterStates {
+ std::unique_ptr<SimulatedClock> simulated_clock;
+ std::unique_ptr<SmoothingFilter> smoothing_filter;
+};
+
+SmoothingFilterStates CreateSmoothingFilter() {
+ SmoothingFilterStates states;
+ states.simulated_clock.reset(new SimulatedClock(kClockInitialTime));
+ states.smoothing_filter.reset(
+ new SmoothingFilterImpl(kTimeConstantMs, states.simulated_clock.get()));
+ return states;
+}
+
+void CheckOutput(SmoothingFilterStates* states,
+ int advance_time_ms,
+ float sample,
+ float expected_ouput) {
+ states->simulated_clock->AdvanceTimeMilliseconds(advance_time_ms);
+ states->smoothing_filter->AddSample(sample);
+ auto output = states->smoothing_filter->GetAverage();
+ EXPECT_TRUE(output);
+ EXPECT_NEAR(expected_ouput, *output, kMaxAbsError);
+}
+
+} // namespace
+
+TEST(SmoothingFilterTest, NoOutputWhenNoSampleAdded) {
+ auto states = CreateSmoothingFilter();
+ EXPECT_FALSE(states.smoothing_filter->GetAverage());
+}
+
+// Python script to calculate the reference values used in this test.
+// import math
+//
+// class ExpFilter:
+// alpha = 0.0
+// old_value = 0.0
+// def calc(self, new_value):
+// self.old_value = self.old_value * self.alpha
+// + (1.0 - self.alpha) * new_value
+// return self.old_value
+//
+// delta_t = 100.0
+// filter = ExpFilter()
+// total_t = 100.0
+// filter.alpha = math.exp(-delta_t/ total_t)
+// print filter.calc(1.0)
+// total_t = 200.0
+// filter.alpha = math.exp(-delta_t/ total_t)
+// print filter.calc(0.0)
+// total_t = 300.0
+// filter.alpha = math.exp(-delta_t/ total_t)
+// print filter.calc(1.0)
+TEST(SmoothingFilterTest, CheckBehaviorBeforeInitialized) {
+ // Adding three samples, all added before |kTimeConstantMs| is reached.
+ constexpr int kTimeIntervalMs = 100;
+ auto states = CreateSmoothingFilter();
+ states.smoothing_filter->AddSample(0.0);
+ CheckOutput(&states, kTimeIntervalMs, 1.0, 0.63212f);
+ CheckOutput(&states, kTimeIntervalMs, 0.0, 0.38340f);
+ CheckOutput(&states, kTimeIntervalMs, 1.0, 0.55818f);
+}
+
+// Python script to calculate the reference value used in this test.
+// (after defining ExpFilter as for CheckBehaviorBeforeInitialized)
+// time_constant_ms = 1000.0
+// filter = ExpFilter()
+// delta_t = 1100.0
+// filter.alpha = math.exp(-delta_t/ time_constant_ms)
+// print filter.calc(1.0)
+// delta_t = 100.0
+// filter.alpha = math.exp(-delta_t/ time_constant_ms)
+// print filter.calc(0.0)
+// print filter.calc(1.0)
+TEST(SmoothingFilterTest, CheckBehaviorAfterInitialized) {
+ constexpr int kTimeIntervalMs = 100;
+ auto states = CreateSmoothingFilter();
+ states.smoothing_filter->AddSample(0.0);
+ states.simulated_clock->AdvanceTimeMilliseconds(kTimeConstantMs);
+ CheckOutput(&states, kTimeIntervalMs, 1.0, 0.66713f);
+ CheckOutput(&states, kTimeIntervalMs, 0.0, 0.60364f);
+ CheckOutput(&states, kTimeIntervalMs, 1.0, 0.64136f);
+}
+
+} // namespace webrtc
diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
index e9772f6..0f0958c 100644
--- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
+++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc
@@ -13,8 +13,8 @@
#include <algorithm>
#include <iterator>
-#include "webrtc/base/analytics/exp_filter.h"
#include "webrtc/base/checks.h"
+#include "webrtc/base/exp_filter.h"
#include "webrtc/base/safe_conversions.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_impl.h"