| Index: media/base/sinc_resampler_unittest.cc
|
| diff --git a/media/base/sinc_resampler_unittest.cc b/media/base/sinc_resampler_unittest.cc
|
| index 9bf7ba4409b97d0ffbdbfbc267f900535df96073..fa358e13045c82a2035070557fb0c2d793b35499 100644
|
| --- a/media/base/sinc_resampler_unittest.cc
|
| +++ b/media/base/sinc_resampler_unittest.cc
|
| @@ -9,9 +9,10 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/bind_helpers.h"
|
| +#include "base/command_line.h"
|
| #include "base/logging.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/stringprintf.h"
|
| +#include "base/string_number_conversions.h"
|
| +#include "base/time.h"
|
| #include "media/base/sinc_resampler.h"
|
| #include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -20,6 +21,12 @@ using testing::_;
|
|
|
| namespace media {
|
|
|
| +static const double kSampleRateRatio = 192000.0 / 44100.0;
|
| +static const double kKernelInterpolationFactor = 0.5;
|
| +
|
| +// Command line switch for runtime adjustment of ConvolveBenchmark iterations.
|
| +static const char kConvolveIterations[] = "convolve-iterations";
|
| +
|
| // Helper class to ensure ChunkedResample() functions properly.
|
| class MockSource {
|
| public:
|
| @@ -33,7 +40,6 @@ TEST(SincResamplerTest, ChunkedResample) {
|
|
|
| // Choose a high ratio of input to output samples which will result in quick
|
| // exhaustion of SincResampler's internal buffers.
|
| - static const double kSampleRateRatio = 192000.0 / 44100.0;
|
| SincResampler resampler(
|
| kSampleRateRatio,
|
| base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
|
| @@ -52,6 +58,102 @@ TEST(SincResamplerTest, ChunkedResample) {
|
| resampler.Resample(resampled_destination.get(), max_chunk_size);
|
| }
|
|
|
| +// Ensure various optimized Convolve() methods return the same value. Only run
|
| +// this test if other optimized methods exist, otherwise the default Convolve()
|
| +// will be tested by the parameterized SincResampler tests below.
|
| +#if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__)
|
| +TEST(SincResamplerTest, Convolve) {
|
| + // Initialize a dummy resampler.
|
| + MockSource mock_source;
|
| + SincResampler resampler(
|
| + kSampleRateRatio,
|
| + base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
|
| +
|
| + // Convolve_SSE() is slightly more precise than Convolve_C(), so comparison
|
| + // must be done using an epsilon.
|
| + static const double kEpsilon = 0.00000005;
|
| +
|
| + // Use a kernel from SincResampler as input and kernel data, this has the
|
| + // benefit of already being properly sized and aligned for Convolve_SSE().
|
| + double result = resampler.Convolve_C(
|
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + double result2 = resampler.Convolve_SSE(
|
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + EXPECT_NEAR(result2, result, kEpsilon);
|
| +
|
| + // Test Convolve_SSE() w/ unaligned input pointer.
|
| + result = resampler.Convolve_C(
|
| + resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + result2 = resampler.Convolve_SSE(
|
| + resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + EXPECT_NEAR(result2, result, kEpsilon);
|
| +}
|
| +#endif
|
| +
|
| +// Benchmark for the various Convolve() methods. Make sure to build with
|
| +// branding=Chrome so that DCHECKs are compiled out when benchmarking. Original
|
| +// benchmarks were run with --convolve-iterations=50000000.
|
| +TEST(SincResamplerTest, ConvolveBenchmark) {
|
| + // Initialize a dummy resampler.
|
| + MockSource mock_source;
|
| + SincResampler resampler(
|
| + kSampleRateRatio,
|
| + base::Bind(&MockSource::ProvideInput, base::Unretained(&mock_source)));
|
| +
|
| + // Retrieve benchmark iterations from command line.
|
| + int convolve_iterations = 10;
|
| + std::string iterations(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
|
| + kConvolveIterations));
|
| + if (!iterations.empty())
|
| + base::StringToInt(iterations, &convolve_iterations);
|
| +
|
| + printf("Benchmarking %d iterations:\n", convolve_iterations);
|
| +
|
| + // Benchmark Convolve_C().
|
| + base::TimeTicks start = base::TimeTicks::HighResNow();
|
| + for (int i = 0; i < convolve_iterations; ++i) {
|
| + resampler.Convolve_C(
|
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + }
|
| + double total_time_c_ms =
|
| + (base::TimeTicks::HighResNow() - start).InMillisecondsF();
|
| + printf("Convolve_C took %.2fms.\n", total_time_c_ms);
|
| +
|
| +#if defined(ARCH_CPU_X86_FAMILY) && defined(__SSE__)
|
| + // Benchmark Convolve_SSE() with unaligned input pointer.
|
| + start = base::TimeTicks::HighResNow();
|
| + for (int j = 0; j < convolve_iterations; ++j) {
|
| + resampler.Convolve_SSE(
|
| + resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + }
|
| + double total_time_sse_unaligned_ms =
|
| + (base::TimeTicks::HighResNow() - start).InMillisecondsF();
|
| + printf("Convolve_SSE (unaligned) took %.2fms; which is %.2fx faster than"
|
| + " Convolve_C.\n", total_time_sse_unaligned_ms,
|
| + total_time_c_ms / total_time_sse_unaligned_ms);
|
| +
|
| + // Benchmark Convolve_SSE() with aligned input pointer.
|
| + start = base::TimeTicks::HighResNow();
|
| + for (int j = 0; j < convolve_iterations; ++j) {
|
| + resampler.Convolve_SSE(
|
| + resampler.kernel_storage_.get(), resampler.kernel_storage_.get(),
|
| + resampler.kernel_storage_.get(), kKernelInterpolationFactor);
|
| + }
|
| + double total_time_sse_aligned_ms =
|
| + (base::TimeTicks::HighResNow() - start).InMillisecondsF();
|
| + printf("Convolve_SSE (aligned) took %.2fms; which is %.2fx faster than"
|
| + " Convolve_C and %.2fx faster than Convolve_SSE (unaligned).\n",
|
| + total_time_sse_aligned_ms, total_time_c_ms / total_time_sse_aligned_ms,
|
| + total_time_sse_unaligned_ms / total_time_sse_aligned_ms);
|
| +#endif
|
| +}
|
| +
|
| // Fake audio source for testing the resampler. Generates a sinusoidal linear
|
| // chirp (http://en.wikipedia.org/wiki/Chirp) which can be tuned to stress the
|
| // resampler for the specific sample rate conversion being used.
|
|
|