Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(561)

Unified Diff: media/base/sinc_resampler.cc

Issue 19470003: DO NOT COMMIT. Diff of downstream webrtc resampler commit for review purposes. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/base/sinc_resampler.h ('k') | media/base/sinc_resampler_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/sinc_resampler.cc
diff --git a/media/base/sinc_resampler.cc b/media/base/sinc_resampler.cc
index a2918c3f0d2e590c2eedc48ed29aa92a3e015343..b66ed345a3f13d148148ea29075216b9acca771c 100644
--- a/media/base/sinc_resampler.cc
+++ b/media/base/sinc_resampler.cc
@@ -1,7 +1,16 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
+/*
+ * Copyright (c) 2013 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.
+ */
+
+// Modified from the Chromium original:
+// src/media/base/sinc_resampler.cc
+
// Initial input buffer layout, dividing into regions r0_ to r4_ (note: r0_, r3_
// and r4_ will move after the first load):
//
@@ -76,19 +85,16 @@
// MSVC++ requires this to be set before any other includes to get M_PI.
#define _USE_MATH_DEFINES
-#include "media/base/sinc_resampler.h"
+#include "webrtc/common_audio/resampler/sinc_resampler.h"
+#include "webrtc/system_wrappers/interface/compile_assert.h"
+#include "webrtc/system_wrappers/interface/cpu_features_wrapper.h"
+#include "webrtc/typedefs.h"
#include <cmath>
+#include <cstring>
#include <limits>
-#include "base/cpu.h"
-#include "base/logging.h"
-
-#if defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
-#include <arm_neon.h>
-#endif
-
-namespace media {
+namespace webrtc {
static double SincScaleFactor(double io_ratio) {
// |sinc_scale_factor| is basically the normalized cutoff frequency of the
@@ -107,31 +113,36 @@ static double SincScaleFactor(double io_ratio) {
}
// If we know the minimum architecture at compile time, avoid CPU detection.
-// Force NaCl code to use C routines since (at present) nothing there uses these
-// methods and plumbing the -msse built library is non-trivial. iOS lies
-// about its architecture, so we also need to exclude it here.
-#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_NACL) && !defined(OS_IOS)
+// iOS lies about its architecture, so we also need to exclude it here.
+#if defined(WEBRTC_ARCH_X86_FAMILY) && !defined(WEBRTC_IOS)
#if defined(__SSE__)
#define CONVOLVE_FUNC Convolve_SSE
void SincResampler::InitializeCPUSpecificFeatures() {}
#else
-// X86 CPU detection required. Functions will be set by
+// X86 CPU detection required. Function will be set by
// InitializeCPUSpecificFeatures().
// TODO(dalecurtis): Once Chrome moves to an SSE baseline this can be removed.
-#define CONVOLVE_FUNC g_convolve_proc_
-
-typedef float (*ConvolveProc)(const float*, const float*, const float*, double);
-static ConvolveProc g_convolve_proc_ = NULL;
+#define CONVOLVE_FUNC convolve_proc_
void SincResampler::InitializeCPUSpecificFeatures() {
- CHECK(!g_convolve_proc_);
- g_convolve_proc_ = base::CPU().has_sse() ? Convolve_SSE : Convolve_C;
+ convolve_proc_ = WebRtc_GetCPUInfo(kSSE2) ? Convolve_SSE : Convolve_C;
}
#endif
-#elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
+#elif defined(WEBRTC_ARCH_ARM_V7)
+#if defined(WEBRTC_ARCH_ARM_NEON)
#define CONVOLVE_FUNC Convolve_NEON
void SincResampler::InitializeCPUSpecificFeatures() {}
#else
+// NEON CPU detection required. Function will be set by
+// InitializeCPUSpecificFeatures().
+#define CONVOLVE_FUNC convolve_proc_
+
+void SincResampler::InitializeCPUSpecificFeatures() {
+ convolve_proc_ = WebRtc_GetCPUFeaturesARM() & kCPUFeatureNEON ?
+ Convolve_NEON : Convolve_C;
+}
+#endif
+#else
// Unknown architecture.
#define CONVOLVE_FUNC Convolve_C
void SincResampler::InitializeCPUSpecificFeatures() {}
@@ -139,26 +150,32 @@ void SincResampler::InitializeCPUSpecificFeatures() {}
SincResampler::SincResampler(double io_sample_rate_ratio,
int request_frames,
- const ReadCB& read_cb)
+ SincResamplerCallback* read_cb)
: io_sample_rate_ratio_(io_sample_rate_ratio),
read_cb_(read_cb),
request_frames_(request_frames),
input_buffer_size_(request_frames_ + kKernelSize),
// Create input buffers with a 16-byte alignment for SSE optimizations.
kernel_storage_(static_cast<float*>(
- base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))),
+ AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
kernel_pre_sinc_storage_(static_cast<float*>(
- base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))),
+ AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
kernel_window_storage_(static_cast<float*>(
- base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))),
+ AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
input_buffer_(static_cast<float*>(
- base::AlignedAlloc(sizeof(float) * input_buffer_size_, 16))),
+ AlignedMalloc(sizeof(float) * input_buffer_size_, 16))),
+#if defined(WEBRTC_RESAMPLER_CPU_DETECTION)
+ convolve_proc_(NULL),
+#endif
r1_(input_buffer_.get()),
r2_(input_buffer_.get() + kKernelSize / 2) {
- CHECK_GT(request_frames_, 0);
+#if defined(WEBRTC_RESAMPLER_CPU_DETECTION)
+ InitializeCPUSpecificFeatures();
+ assert(convolve_proc_);
+#endif
+ assert(request_frames_ > 0);
Flush();
- CHECK_GT(block_size_, kKernelSize)
- << "block_size must be greater than kKernelSize!";
+ assert(block_size_ > kKernelSize);
memset(kernel_storage_.get(), 0,
sizeof(*kernel_storage_.get()) * kKernelStorageSize);
@@ -181,11 +198,11 @@ void SincResampler::UpdateRegions(bool second_load) {
block_size_ = r4_ - r2_;
// r1_ at the beginning of the buffer.
- CHECK_EQ(r1_, input_buffer_.get());
+ assert(r1_ == input_buffer_.get());
// r1_ left of r2_, r4_ left of r3_ and size correct.
- CHECK_EQ(r2_ - r1_, r4_ - r3_);
+ assert(r2_ - r1_ == r4_ - r3_);
// r2_ left of r3.
- CHECK_LT(r2_, r3_);
+ assert(r2_ < r3_);
}
void SincResampler::InitializeKernel() {
@@ -205,20 +222,20 @@ void SincResampler::InitializeKernel() {
for (int i = 0; i < kKernelSize; ++i) {
const int idx = i + offset_idx * kKernelSize;
const float pre_sinc = M_PI * (i - kKernelSize / 2 - subsample_offset);
- kernel_pre_sinc_storage_[idx] = pre_sinc;
+ kernel_pre_sinc_storage_.get()[idx] = pre_sinc;
// Compute Blackman window, matching the offset of the sinc().
const float x = (i - subsample_offset) / kKernelSize;
const float window = kA0 - kA1 * cos(2.0 * M_PI * x) + kA2
* cos(4.0 * M_PI * x);
- kernel_window_storage_[idx] = window;
+ kernel_window_storage_.get()[idx] = window;
// Compute the sinc with offset, then window the sinc() function and store
// at the correct offset.
if (pre_sinc == 0) {
- kernel_storage_[idx] = sinc_scale_factor * window;
+ kernel_storage_.get()[idx] = sinc_scale_factor * window;
} else {
- kernel_storage_[idx] =
+ kernel_storage_.get()[idx] =
window * sin(sinc_scale_factor * pre_sinc) / pre_sinc;
}
}
@@ -239,13 +256,13 @@ void SincResampler::SetRatio(double io_sample_rate_ratio) {
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
for (int i = 0; i < kKernelSize; ++i) {
const int idx = i + offset_idx * kKernelSize;
- const float window = kernel_window_storage_[idx];
- const float pre_sinc = kernel_pre_sinc_storage_[idx];
+ const float window = kernel_window_storage_.get()[idx];
+ const float pre_sinc = kernel_pre_sinc_storage_.get()[idx];
if (pre_sinc == 0) {
- kernel_storage_[idx] = sinc_scale_factor * window;
+ kernel_storage_.get()[idx] = sinc_scale_factor * window;
} else {
- kernel_storage_[idx] =
+ kernel_storage_.get()[idx] =
window * sin(sinc_scale_factor * pre_sinc) / pre_sinc;
}
}
@@ -257,7 +274,7 @@ void SincResampler::Resample(int frames, float* destination) {
// Step (1) -- Prime the input buffer at the start of the input stream.
if (!buffer_primed_ && remaining_frames) {
- read_cb_.Run(request_frames_, r0_);
+ read_cb_->Run(request_frames_, r0_);
buffer_primed_ = true;
}
@@ -273,7 +290,7 @@ void SincResampler::Resample(int frames, float* destination) {
// or when built with clang. See https://codereview.chromium.org/18566009/
for (int i = ceil((block_size_ - virtual_source_idx_) / current_io_ratio);
i > 0; --i) {
- DCHECK_LT(virtual_source_idx_, block_size_);
+ assert(virtual_source_idx_ < block_size_);
// |virtual_source_idx_| lies in between two kernel offsets so figure out
// what they are.
@@ -291,8 +308,8 @@ void SincResampler::Resample(int frames, float* destination) {
// Ensure |k1|, |k2| are 16-byte aligned for SIMD usage. Should always be
// true so long as kKernelSize is a multiple of 16.
- DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(k1) & 0x0F);
- DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(k2) & 0x0F);
+ assert(0u == (reinterpret_cast<uintptr_t>(k1) & 0x0F));
+ assert(0u == (reinterpret_cast<uintptr_t>(k2) & 0x0F));
// Initialize input pointer based on quantized |virtual_source_idx_|.
const float* const input_ptr = r1_ + source_idx;
@@ -322,7 +339,7 @@ void SincResampler::Resample(int frames, float* destination) {
UpdateRegions(true);
// Step (5) -- Refresh the buffer with more input.
- read_cb_.Run(request_frames_, r0_);
+ read_cb_->Run(request_frames_, r0_);
}
}
@@ -359,33 +376,4 @@ float SincResampler::Convolve_C(const float* input_ptr, const float* k1,
+ kernel_interpolation_factor * sum2;
}
-#if defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON)
-float SincResampler::Convolve_NEON(const float* input_ptr, const float* k1,
- const float* k2,
- double kernel_interpolation_factor) {
- float32x4_t m_input;
- float32x4_t m_sums1 = vmovq_n_f32(0);
- float32x4_t m_sums2 = vmovq_n_f32(0);
-
- const float* upper = input_ptr + kKernelSize;
- for (; input_ptr < upper; ) {
- m_input = vld1q_f32(input_ptr);
- input_ptr += 4;
- m_sums1 = vmlaq_f32(m_sums1, m_input, vld1q_f32(k1));
- k1 += 4;
- m_sums2 = vmlaq_f32(m_sums2, m_input, vld1q_f32(k2));
- k2 += 4;
- }
-
- // Linearly interpolate the two "convolutions".
- m_sums1 = vmlaq_f32(
- vmulq_f32(m_sums1, vmovq_n_f32(1.0 - kernel_interpolation_factor)),
- m_sums2, vmovq_n_f32(kernel_interpolation_factor));
-
- // Sum components together.
- float32x2_t m_half = vadd_f32(vget_high_f32(m_sums1), vget_low_f32(m_sums1));
- return vget_lane_f32(vpadd_f32(m_half, m_half), 0);
-}
-#endif
-
-} // namespace media
+} // namespace webrtc
« no previous file with comments | « media/base/sinc_resampler.h ('k') | media/base/sinc_resampler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698