summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorajm <ajm@chromium.org>2015-09-14 11:41:13 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-14 18:42:13 +0000
commit42979149ac67727de85b1e5fc5cf874cf709eb36 (patch)
tree23c9f13e413db3258ac667fbcbe9e32250ac6a7d /media
parent4528b0df09b22145b71e3d04836319aab5a47920 (diff)
downloadchromium_src-42979149ac67727de85b1e5fc5cf874cf709eb36.zip
chromium_src-42979149ac67727de85b1e5fc5cf874cf709eb36.tar.gz
chromium_src-42979149ac67727de85b1e5fc5cf874cf709eb36.tar.bz2
Add a virtual beamforming audio device on ChromeOS.
AudioManagerCras checks with CrasAudioHandler for an internal mic device with a valid positions field. If present, it adds a virtual beamforming device. When this device is selected by a web app, the mic positions are plumbed up to MediaStreamAudioProcessor via AudioParameters. MSAP will enable beamforming when it sees valid mic positions. See the design doc for background: go/virtual-beamforming-device BUG=497001 TEST=Selecting the beamforming device on a swanky indeed enables beamforming for the internal mic and continues to work fine for an external USB mic. Selecting the non-beamforming device disables beamforming for the internal mic. Review URL: https://codereview.chromium.org/1275783003 Cr-Commit-Position: refs/heads/master@{#348668}
Diffstat (limited to 'media')
-rw-r--r--media/BUILD.gn3
-rw-r--r--media/audio/BUILD.gn7
-rw-r--r--media/audio/audio_parameters.cc14
-rw-r--r--media/audio/audio_parameters.h25
-rw-r--r--media/audio/audio_parameters_unittest.cc5
-rw-r--r--media/audio/cras/audio_manager_cras.cc87
-rw-r--r--media/audio/cras/audio_manager_cras.h7
-rw-r--r--media/audio/openbsd/audio_manager_openbsd.cc160
-rw-r--r--media/audio/openbsd/audio_manager_openbsd.h55
-rw-r--r--media/audio/point.cc61
-rw-r--r--media/audio/point.h31
-rw-r--r--media/audio/point_unittest.cc41
-rw-r--r--media/audio/pulse/audio_manager_pulse.cc6
-rw-r--r--media/base/audio_buffer_unittest.cc9
-rw-r--r--media/media.gyp11
-rw-r--r--media/shared_memory_support.gypi2
16 files changed, 261 insertions, 263 deletions
diff --git a/media/BUILD.gn b/media/BUILD.gn
index 51fb153..78c5310 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -793,6 +793,8 @@ component("shared_memory_support") {
sources = [
"audio/audio_parameters.cc",
"audio/audio_parameters.h",
+ "audio/point.cc",
+ "audio/point.h",
"base/audio_bus.cc",
"base/audio_bus.h",
"base/channel_layout.cc",
@@ -808,6 +810,7 @@ component("shared_memory_support") {
]
deps = [
"//base",
+ "//ui/gfx/geometry",
]
}
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 24ef1efe..369d7d0 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -185,13 +185,6 @@ source_set("audio") {
deps += [ "//media/base/android:media_jni_headers" ]
}
- if (is_openbsd) {
- sources += [
- "openbsd/audio_manager_openbsd.cc",
- "openbsd/audio_manager_openbsd.h",
- ]
- }
-
if (is_linux) {
sources += [ "linux/audio_manager_linux.cc" ]
}
diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc
index a78eb84..14c3214 100644
--- a/media/audio/audio_parameters.cc
+++ b/media/audio/audio_parameters.cc
@@ -21,6 +21,11 @@ AudioParameters::AudioParameters(Format format,
frames_per_buffer);
}
+AudioParameters::~AudioParameters() {}
+
+AudioParameters::AudioParameters(const AudioParameters&) = default;
+AudioParameters& AudioParameters::operator=(const AudioParameters&) = default;
+
void AudioParameters::Reset(Format format,
ChannelLayout channel_layout,
int sample_rate,
@@ -33,6 +38,7 @@ void AudioParameters::Reset(Format format,
bits_per_sample_ = bits_per_sample;
frames_per_buffer_ = frames_per_buffer;
effects_ = NO_EFFECTS;
+ mic_positions_.clear();
}
bool AudioParameters::IsValid() const {
@@ -54,7 +60,8 @@ std::string AudioParameters::AsHumanReadableString() const {
<< " channels: " << channels() << " sample_rate: " << sample_rate()
<< " bits_per_sample: " << bits_per_sample()
<< " frames_per_buffer: " << frames_per_buffer()
- << " effects: " << effects();
+ << " effects: " << effects()
+ << " mic_positions: " << PointsToString(mic_positions_);
return s.str();
}
@@ -77,13 +84,12 @@ base::TimeDelta AudioParameters::GetBufferDuration() const {
}
bool AudioParameters::Equals(const AudioParameters& other) const {
- return format_ == other.format() &&
- sample_rate_ == other.sample_rate() &&
+ return format_ == other.format() && sample_rate_ == other.sample_rate() &&
channel_layout_ == other.channel_layout() &&
channels_ == other.channels() &&
bits_per_sample_ == other.bits_per_sample() &&
frames_per_buffer_ == other.frames_per_buffer() &&
- effects_ == other.effects();
+ effects_ == other.effects() && mic_positions_ == other.mic_positions_;
}
} // namespace media
diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h
index 57fb960..61ca812 100644
--- a/media/audio/audio_parameters.h
+++ b/media/audio/audio_parameters.h
@@ -11,6 +11,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/time/time.h"
+#include "media/audio/point.h"
#include "media/base/audio_bus.h"
#include "media/base/channel_layout.h"
#include "media/base/media_export.h"
@@ -86,6 +87,8 @@ class MEDIA_EXPORT AudioParameters {
int bits_per_sample,
int frames_per_buffer);
+ ~AudioParameters();
+
// Re-initializes all members.
void Reset(Format format,
ChannelLayout channel_layout,
@@ -148,8 +151,13 @@ class MEDIA_EXPORT AudioParameters {
void set_effects(int effects) { effects_ = effects; }
int effects() const { return effects_; }
- AudioParameters(const AudioParameters&) = default;
- AudioParameters& operator=(const AudioParameters&) = default;
+ void set_mic_positions(const std::vector<Point>& mic_positions) {
+ mic_positions_ = mic_positions;
+ }
+ const std::vector<Point>& mic_positions() const { return mic_positions_; }
+
+ AudioParameters(const AudioParameters&);
+ AudioParameters& operator=(const AudioParameters&);
private:
Format format_; // Format of the stream.
@@ -160,6 +168,19 @@ class MEDIA_EXPORT AudioParameters {
int bits_per_sample_; // Number of bits per sample.
int frames_per_buffer_; // Number of frames in a buffer.
int effects_; // Bitmask using PlatformEffectsMask.
+
+ // Microphone positions using Cartesian coordinates:
+ // x: the horizontal dimension, with positive to the right from the camera's
+ // perspective.
+ // y: the depth dimension, with positive forward from the camera's
+ // perspective.
+ // z: the vertical dimension, with positive upwards.
+ //
+ // Usually, the center of the microphone array will be treated as the origin
+ // (often the position of the camera).
+ //
+ // An empty vector indicates unknown positions.
+ std::vector<Point> mic_positions_;
};
// Comparison is useful when AudioParameters is used with std structures.
diff --git a/media/audio/audio_parameters_unittest.cc b/media/audio/audio_parameters_unittest.cc
index 2cf541d..c39e8d4 100644
--- a/media/audio/audio_parameters_unittest.cc
+++ b/media/audio/audio_parameters_unittest.cc
@@ -16,6 +16,9 @@ TEST(AudioParameters, Constructor_Default) {
ChannelLayout expected_channel_layout = CHANNEL_LAYOUT_NONE;
int expected_rate = 0;
int expected_samples = 0;
+ AudioParameters::PlatformEffectsMask expected_effects =
+ AudioParameters::NO_EFFECTS;
+ std::vector<Point> expected_mic_positions;
AudioParameters params;
@@ -25,6 +28,8 @@ TEST(AudioParameters, Constructor_Default) {
EXPECT_EQ(expected_channel_layout, params.channel_layout());
EXPECT_EQ(expected_rate, params.sample_rate());
EXPECT_EQ(expected_samples, params.frames_per_buffer());
+ EXPECT_EQ(expected_effects, params.effects());
+ EXPECT_EQ(expected_mic_positions, params.mic_positions());
}
TEST(AudioParameters, Constructor_ParameterValues) {
diff --git a/media/audio/cras/audio_manager_cras.cc b/media/audio/cras/audio_manager_cras.cc
index 31a1780..2b47de4 100644
--- a/media/audio/cras/audio_manager_cras.cc
+++ b/media/audio/cras/audio_manager_cras.cc
@@ -23,28 +23,66 @@
#undef max
namespace media {
+namespace {
-static void AddDefaultDevice(AudioDeviceNames* device_names) {
- DCHECK(device_names->empty());
+// Maximum number of output streams that can be open simultaneously.
+const int kMaxOutputStreams = 50;
+
+// Default sample rate for input and output streams.
+const int kDefaultSampleRate = 48000;
+// Define bounds for the output buffer size.
+const int kMinimumOutputBufferSize = 512;
+const int kMaximumOutputBufferSize = 8192;
+
+// Default input buffer size.
+const int kDefaultInputBufferSize = 1024;
+
+void AddDefaultDevice(AudioDeviceNames* device_names) {
// Cras will route audio from a proper physical device automatically.
device_names->push_back(
AudioDeviceName(AudioManagerBase::kDefaultDeviceName,
AudioManagerBase::kDefaultDeviceId));
}
-// Maximum number of output streams that can be open simultaneously.
-static const int kMaxOutputStreams = 50;
+// Returns the AudioDeviceName of the virtual device with beamforming on.
+AudioDeviceName BeamformingOnDeviceName() {
+ // TODO(ajm): Replace these strings with properly localized ones.
+ // (crbug.com/497001)
+ static const char kBeamformingOnNameSuffix[] = " (pick up just one person)";
+ static const char kBeamformingOnIdSuffix[] = "-beamforming";
-// Default sample rate for input and output streams.
-static const int kDefaultSampleRate = 48000;
+ return AudioDeviceName(
+ std::string(AudioManagerBase::kDefaultDeviceName) +
+ kBeamformingOnNameSuffix,
+ std::string(AudioManagerBase::kDefaultDeviceId) + kBeamformingOnIdSuffix);
+}
-// Define bounds for the output buffer size.
-static const int kMinimumOutputBufferSize = 512;
-static const int kMaximumOutputBufferSize = 8192;
+// Returns the AudioDeviceName of the virtual device with beamforming off.
+AudioDeviceName BeamformingOffDeviceName() {
+ static const char kBeamformingOffNameSuffix[] = " (pick up everything)";
+ return AudioDeviceName(std::string(AudioManagerBase::kDefaultDeviceName) +
+ kBeamformingOffNameSuffix,
+ AudioManagerBase::kDefaultDeviceId);
+}
-// Default input buffer size.
-static const int kDefaultInputBufferSize = 1024;
+// Returns a mic positions string if the machine has a beamforming capable
+// internal mic and otherwise an empty string.
+std::string MicPositions() {
+ // Get the list of devices from CRAS. An internal mic with a non-empty
+ // positions field indicates the machine has a beamforming capable mic array.
+ chromeos::AudioDeviceList devices;
+ chromeos::CrasAudioHandler::Get()->GetAudioDevices(&devices);
+ for (const auto& device : devices) {
+ if (device.type == chromeos::AUDIO_TYPE_INTERNAL_MIC) {
+ // There should be only one internal mic device.
+ return device.mic_positions;
+ }
+ }
+ return "";
+}
+
+} // namespace
bool AudioManagerCras::HasAudioOutputDevices() {
return true;
@@ -62,7 +100,9 @@ bool AudioManagerCras::HasAudioInputDevices() {
AudioManagerCras::AudioManagerCras(AudioLogFactory* audio_log_factory)
: AudioManagerBase(audio_log_factory),
- has_keyboard_mic_(false) {
+ has_keyboard_mic_(false),
+ beamforming_on_device_name_(BeamformingOnDeviceName()),
+ beamforming_off_device_name_(BeamformingOffDeviceName()) {
SetMaxOutputStreamsAllowed(kMaxOutputStreams);
}
@@ -76,11 +116,24 @@ void AudioManagerCras::ShowAudioInputSettings() {
void AudioManagerCras::GetAudioInputDeviceNames(
AudioDeviceNames* device_names) {
- AddDefaultDevice(device_names);
+ DCHECK(device_names->empty());
+
+ mic_positions_ = ParsePointsFromString(MicPositions());
+ // At least two mic positions indicates we have a beamforming capable mic
+ // array. Add the virtual beamforming device to the list. When this device is
+ // queried through GetInputStreamParameters, provide the cached mic positions.
+ if (mic_positions_.size() > 1) {
+ device_names->push_back(beamforming_on_device_name_);
+ device_names->push_back(beamforming_off_device_name_);
+ } else {
+ AddDefaultDevice(device_names);
+ }
}
void AudioManagerCras::GetAudioOutputDeviceNames(
AudioDeviceNames* device_names) {
+ DCHECK(device_names->empty());
+
AddDefaultDevice(device_names);
}
@@ -91,16 +144,16 @@ AudioParameters AudioManagerCras::GetInputStreamParameters(
int user_buffer_size = GetUserBufferSize();
int buffer_size = user_buffer_size ?
user_buffer_size : kDefaultInputBufferSize;
- AudioParameters::PlatformEffectsMask effects =
- has_keyboard_mic_ ? AudioParameters::KEYBOARD_MIC
- : AudioParameters::NO_EFFECTS;
// TODO(hshi): Fine-tune audio parameters based on |device_id|. The optimal
// parameters for the loopback stream may differ from the default.
AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
CHANNEL_LAYOUT_STEREO, kDefaultSampleRate, 16,
buffer_size);
- params.set_effects(effects);
+ if (has_keyboard_mic_)
+ params.set_effects(AudioParameters::KEYBOARD_MIC);
+ if (device_id == beamforming_on_device_name_.unique_id)
+ params.set_mic_positions(mic_positions_);
return params;
}
diff --git a/media/audio/cras/audio_manager_cras.h b/media/audio/cras/audio_manager_cras.h
index 4c8f992..d55756d 100644
--- a/media/audio/cras/audio_manager_cras.h
+++ b/media/audio/cras/audio_manager_cras.h
@@ -61,6 +61,13 @@ class MEDIA_EXPORT AudioManagerCras : public AudioManagerBase {
bool has_keyboard_mic_;
+ // Holds the name and ID of the virtual beamforming devices.
+ const AudioDeviceName beamforming_on_device_name_;
+ const AudioDeviceName beamforming_off_device_name_;
+
+ // Stores the mic positions field from the device.
+ std::vector<Point> mic_positions_;
+
DISALLOW_COPY_AND_ASSIGN(AudioManagerCras);
};
diff --git a/media/audio/openbsd/audio_manager_openbsd.cc b/media/audio/openbsd/audio_manager_openbsd.cc
deleted file mode 100644
index 618fb0c..0000000
--- a/media/audio/openbsd/audio_manager_openbsd.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// 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.
-
-#include "media/audio/openbsd/audio_manager_openbsd.h"
-
-#include <fcntl.h>
-
-#include "base/command_line.h"
-#include "base/file_path.h"
-#include "base/stl_util.h"
-#include "media/audio/audio_output_dispatcher.h"
-#include "media/audio/audio_parameters.h"
-#include "media/audio/pulse/pulse_output.h"
-#include "media/audio/pulse/pulse_stubs.h"
-#include "media/base/channel_layout.h"
-#include "media/base/limits.h"
-#include "media/base/media_switches.h"
-
-using media_audio_pulse::kModulePulse;
-using media_audio_pulse::InitializeStubs;
-using media_audio_pulse::StubPathMap;
-
-namespace media {
-
-// Maximum number of output streams that can be open simultaneously.
-static const int kMaxOutputStreams = 50;
-
-// Default sample rate for input and output streams.
-static const int kDefaultSampleRate = 48000;
-
-static const base::FilePath::CharType kPulseLib[] =
- FILE_PATH_LITERAL("libpulse.so.0");
-
-// Implementation of AudioManager.
-static bool HasAudioHardware() {
- int fd;
- const char *file;
-
- if ((file = getenv("AUDIOCTLDEVICE")) == 0 || *file == '\0')
- file = "/dev/audioctl";
-
- if ((fd = open(file, O_RDONLY)) < 0)
- return false;
-
- close(fd);
- return true;
-}
-
-bool AudioManagerOpenBSD::HasAudioOutputDevices() {
- return HasAudioHardware();
-}
-
-bool AudioManagerOpenBSD::HasAudioInputDevices() {
- return HasAudioHardware();
-}
-
-AudioParameters AudioManagerOpenBSD::GetInputStreamParameters(
- const std::string& device_id) {
- static const int kDefaultInputBufferSize = 1024;
-
- int user_buffer_size = GetUserBufferSize();
- int buffer_size = user_buffer_size ?
- user_buffer_size : kDefaultInputBufferSize;
-
- return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
- kDefaultSampleRate, 16, buffer_size);
-}
-
-AudioManagerOpenBSD::AudioManagerOpenBSD(AudioLogFactory* audio_log_factory)
- : AudioManagerBase(audio_log_factory),
- pulse_library_is_initialized_(false) {
- SetMaxOutputStreamsAllowed(kMaxOutputStreams);
- StubPathMap paths;
-
- // Check if the pulse library is avialbale.
- paths[kModulePulse].push_back(kPulseLib);
- if (!InitializeStubs(paths)) {
- DLOG(WARNING) << "Failed on loading the Pulse library and symbols";
- return;
- }
-
- pulse_library_is_initialized_ = true;
-}
-
-AudioManagerOpenBSD::~AudioManagerOpenBSD() {
- Shutdown();
-}
-
-AudioOutputStream* AudioManagerOpenBSD::MakeLinearOutputStream(
- const AudioParameters& params) {
- DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
- return MakeOutputStream(params);
-}
-
-AudioOutputStream* AudioManagerOpenBSD::MakeLowLatencyOutputStream(
- const AudioParameters& params,
- const std::string& device_id) {
- DLOG_IF(ERROR, !device_id.empty()) << "Not implemented!";
- DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
- return MakeOutputStream(params);
-}
-
-AudioInputStream* AudioManagerOpenBSD::MakeLinearInputStream(
- const AudioParameters& params, const std::string& device_id) {
- DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
- NOTIMPLEMENTED();
- return NULL;
-}
-
-AudioInputStream* AudioManagerOpenBSD::MakeLowLatencyInputStream(
- const AudioParameters& params, const std::string& device_id) {
- DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
- NOTIMPLEMENTED();
- return NULL;
-}
-
-AudioParameters AudioManagerOpenBSD::GetPreferredOutputStreamParameters(
- const std::string& output_device_id,
- const AudioParameters& input_params) {
- // TODO(tommi): Support |output_device_id|.
- DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!";
- static const int kDefaultOutputBufferSize = 512;
-
- ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO;
- int sample_rate = kDefaultSampleRate;
- int buffer_size = kDefaultOutputBufferSize;
- int bits_per_sample = 16;
- if (input_params.IsValid()) {
- sample_rate = input_params.sample_rate();
- bits_per_sample = input_params.bits_per_sample();
- channel_layout = input_params.channel_layout();
- buffer_size = std::min(buffer_size, input_params.frames_per_buffer());
- }
-
- int user_buffer_size = GetUserBufferSize();
- if (user_buffer_size)
- buffer_size = user_buffer_size;
-
- return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
- sample_rate, bits_per_sample, buffer_size, AudioParameters::NO_EFFECTS);
-}
-
-AudioOutputStream* AudioManagerOpenBSD::MakeOutputStream(
- const AudioParameters& params) {
- if (pulse_library_is_initialized_)
- return new PulseAudioOutputStream(params, this);
-
- return NULL;
-}
-
-// TODO(xians): Merge AudioManagerOpenBSD with AudioManagerPulse;
-// static
-AudioManager* CreateAudioManager(AudioLogFactory* audio_log_factory) {
- return new AudioManagerOpenBSD(audio_log_factory);
-}
-
-} // namespace media
diff --git a/media/audio/openbsd/audio_manager_openbsd.h b/media/audio/openbsd/audio_manager_openbsd.h
deleted file mode 100644
index 3326952..0000000
--- a/media/audio/openbsd/audio_manager_openbsd.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-
-#ifndef MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_
-#define MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_
-
-#include <set>
-
-#include "base/compiler_specific.h"
-#include "media/audio/audio_manager_base.h"
-
-namespace media {
-
-class MEDIA_EXPORT AudioManagerOpenBSD : public AudioManagerBase {
- public:
- AudioManagerOpenBSD(AudioLogFactory* audio_log_factory);
-
- // Implementation of AudioManager.
- bool HasAudioOutputDevices() override;
- bool HasAudioInputDevices() override;
- AudioParameters GetInputStreamParameters(
- const std::string& device_id) override;
-
- // Implementation of AudioManagerBase.
- AudioOutputStream* MakeLinearOutputStream(
- const AudioParameters& params) override;
- AudioOutputStream* MakeLowLatencyOutputStream(
- const AudioParameters& params,
- const std::string& device_id) override;
- AudioInputStream* MakeLinearInputStream(
- const AudioParameters& params, const std::string& device_id) override;
- AudioInputStream* MakeLowLatencyInputStream(
- const AudioParameters& params, const std::string& device_id) override;
-
- protected:
- ~AudioManagerOpenBSD() override;
-
- AudioParameters GetPreferredOutputStreamParameters(
- const std::string& output_device_id,
- const AudioParameters& input_params) override;
-
- private:
- // Called by MakeLinearOutputStream and MakeLowLatencyOutputStream.
- AudioOutputStream* MakeOutputStream(const AudioParameters& params);
-
- // Flag to indicate whether the pulse library has been initialized or not.
- bool pulse_library_is_initialized_;
-
- DISALLOW_COPY_AND_ASSIGN(AudioManagerOpenBSD);
-};
-
-} // namespace media
-
-#endif // MEDIA_AUDIO_OPENBSD_AUDIO_MANAGER_OPENBSD_H_
diff --git a/media/audio/point.cc b/media/audio/point.cc
new file mode 100644
index 0000000..3246089
--- /dev/null
+++ b/media/audio/point.cc
@@ -0,0 +1,61 @@
+// Copyright 2015 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.
+
+#include "media/audio/point.h"
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+
+namespace media {
+
+std::string PointsToString(const std::vector<Point>& points) {
+ std::string points_string;
+ if (!points.empty()) {
+ for (size_t i = 0; i < points.size() - 1; ++i) {
+ points_string.append(points[i].ToString());
+ points_string.append(", ");
+ }
+ points_string.append(points.back().ToString());
+ }
+ return points_string;
+}
+
+std::vector<Point> ParsePointsFromString(const std::string& points_string) {
+ std::vector<Point> points;
+ if (points_string.empty())
+ return points;
+
+ const auto& tokens =
+ base::SplitString(points_string, base::kWhitespaceASCII,
+ base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (tokens.size() < 3 || tokens.size() % 3 != 0) {
+ LOG(ERROR) << "Malformed points string: " << points_string;
+ return points;
+ }
+
+ std::vector<float> float_tokens;
+ float_tokens.reserve(tokens.size());
+ for (const auto& token : tokens) {
+ double float_token;
+ if (!base::StringToDouble(token, &float_token)) {
+ LOG(ERROR) << "Unable to convert token=" << token
+ << " to double from points string: " << points_string;
+ return points;
+ }
+ float_tokens.push_back(float_token);
+ }
+
+ points.reserve(float_tokens.size() / 3);
+ for (size_t i = 0; i < float_tokens.size(); i += 3) {
+ points.push_back(
+ Point(float_tokens[i + 0], float_tokens[i + 1], float_tokens[i + 2]));
+ }
+
+ return points;
+}
+
+} // namespace media
diff --git a/media/audio/point.h b/media/audio/point.h
new file mode 100644
index 0000000..d215a59
--- /dev/null
+++ b/media/audio/point.h
@@ -0,0 +1,31 @@
+// Copyright 2015 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.
+
+#ifndef MEDIA_AUDIO_POINT_H_
+#define MEDIA_AUDIO_POINT_H_
+
+#include <string>
+#include <vector>
+
+#include "media/base/media_export.h"
+#include "ui/gfx/geometry/point3_f.h"
+
+namespace media {
+
+using Point = gfx::Point3F;
+
+// Returns a vector of points parsed from a whitespace-separated string
+// formatted as: "x1 y1 z1 ... zn yn zn" for n points.
+//
+// Returns an empty vector if |points_string| is empty or isn't parseable.
+MEDIA_EXPORT std::vector<Point> ParsePointsFromString(
+ const std::string& points_string);
+
+// Returns |points| as a human-readable string. (Not necessarily in the format
+// required by ParsePointsFromString).
+MEDIA_EXPORT std::string PointsToString(const std::vector<Point>& points);
+
+} // namespace media
+
+#endif // MEDIA_AUDIO_POINT_H_
diff --git a/media/audio/point_unittest.cc b/media/audio/point_unittest.cc
new file mode 100644
index 0000000..98aec64
--- /dev/null
+++ b/media/audio/point_unittest.cc
@@ -0,0 +1,41 @@
+// Copyright (c) 2015 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.
+
+#include <cmath>
+
+#include "media/audio/point.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+namespace {
+
+TEST(PointTest, PointsToString) {
+ std::vector<Point> points(1, Point(1, 0, 0.01f));
+ points.push_back(Point(0, 2, 0.02f));
+ EXPECT_EQ("1.000000,0.000000,0.010000, 0.000000,2.000000,0.020000",
+ PointsToString(points));
+
+ EXPECT_EQ("", PointsToString(std::vector<Point>()));
+}
+
+TEST(PointTest, ParsePointString) {
+ const std::vector<Point> expected_empty;
+ EXPECT_EQ(expected_empty, ParsePointsFromString(""));
+ EXPECT_EQ(expected_empty, ParsePointsFromString("0 0 a"));
+ EXPECT_EQ(expected_empty, ParsePointsFromString("1 2"));
+ EXPECT_EQ(expected_empty, ParsePointsFromString("1 2 3 4"));
+
+ {
+ std::vector<Point> expected(1, Point(-0.02f, 0, 0));
+ expected.push_back(Point(0.02f, 0, 0));
+ EXPECT_EQ(expected, ParsePointsFromString("-0.02 0 0 0.02 0 0"));
+ }
+ {
+ std::vector<Point> expected(1, Point(1, 2, 3));
+ EXPECT_EQ(expected, ParsePointsFromString("1 2 3"));
+ }
+}
+
+} // namespace
+} // namespace media
diff --git a/media/audio/pulse/audio_manager_pulse.cc b/media/audio/pulse/audio_manager_pulse.cc
index 3044f3c..f3d8832 100644
--- a/media/audio/pulse/audio_manager_pulse.cc
+++ b/media/audio/pulse/audio_manager_pulse.cc
@@ -135,9 +135,9 @@ AudioParameters AudioManagerPulse::GetInputStreamParameters(
user_buffer_size : kDefaultInputBufferSize;
// TODO(xians): add support for querying native channel layout for pulse.
- return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
- GetNativeSampleRate(), 16, buffer_size);
+ return AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ CHANNEL_LAYOUT_STEREO, GetNativeSampleRate(), 16,
+ buffer_size);
}
AudioOutputStream* AudioManagerPulse::MakeLinearOutputStream(
diff --git a/media/base/audio_buffer_unittest.cc b/media/base/audio_buffer_unittest.cc
index 43c763e..b48220d 100644
--- a/media/base/audio_buffer_unittest.cc
+++ b/media/base/audio_buffer_unittest.cc
@@ -202,13 +202,8 @@ TEST(AudioBufferTest, FrameSize) {
kTimestamp);
EXPECT_EQ(16, buffer->frame_count()); // 2 channels of 8-bit data
- buffer = AudioBuffer::CopyFrom(kSampleFormatF32,
- CHANNEL_LAYOUT_4_0,
- 4,
- kSampleRate,
- 2,
- data,
- kTimestamp);
+ buffer = AudioBuffer::CopyFrom(kSampleFormatF32, CHANNEL_LAYOUT_4_0, 4,
+ kSampleRate, 2, data, kTimestamp);
EXPECT_EQ(2, buffer->frame_count()); // now 4 channels of 32-bit data
}
diff --git a/media/media.gyp b/media/media.gyp
index 102117e..21b9ece 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -161,8 +161,6 @@
'audio/mac/audio_manager_mac.h',
'audio/null_audio_sink.cc',
'audio/null_audio_sink.h',
- 'audio/openbsd/audio_manager_openbsd.cc',
- 'audio/openbsd/audio_manager_openbsd.h',
'audio/pulse/audio_manager_pulse.cc',
'audio/pulse/audio_manager_pulse.h',
'audio/pulse/pulse_input.cc',
@@ -780,12 +778,7 @@
['exclude', '_alsa\\.(h|cc)$'],
],
}],
- ['OS!="openbsd"', {
- 'sources!': [
- 'audio/openbsd/audio_manager_openbsd.cc',
- 'audio/openbsd/audio_manager_openbsd.h',
- ],
- }, { # else: openbsd==1
+ ['OS=="openbsd"', {
'sources!': [
'capture/video/linux/v4l2_capture_delegate_multi_plane.cc',
'capture/video/linux/v4l2_capture_delegate_multi_plane.h',
@@ -1502,6 +1495,7 @@
'audio/audio_parameters_unittest.cc',
'audio/audio_power_monitor_unittest.cc',
'audio/fake_audio_worker_unittest.cc',
+ 'audio/point_unittest.cc',
'audio/simple_sources_unittest.cc',
'audio/virtual_audio_input_stream_unittest.cc',
'audio/virtual_audio_output_stream_unittest.cc',
@@ -1651,6 +1645,7 @@
'type': '<(component)',
'dependencies': [
'../base/base.gyp:base',
+ '../ui/gfx/gfx.gyp:gfx_geometry',
],
'defines': [
'MEDIA_IMPLEMENTATION',
diff --git a/media/shared_memory_support.gypi b/media/shared_memory_support.gypi
index 65403f7..721f6aa 100644
--- a/media/shared_memory_support.gypi
+++ b/media/shared_memory_support.gypi
@@ -10,6 +10,8 @@
'shared_memory_support_sources': [
'audio/audio_parameters.cc',
'audio/audio_parameters.h',
+ 'audio/point.cc',
+ 'audio/point.h',
'base/audio_bus.cc',
'base/audio_bus.h',
'base/channel_layout.cc',