summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/media/audio_input_sync_writer.cc1
-rw-r--r--ppapi/proxy/DEPS1
-rw-r--r--ppapi/proxy/audio_input_resource.cc81
-rw-r--r--ppapi/proxy/audio_input_resource.h12
4 files changed, 73 insertions, 22 deletions
diff --git a/content/browser/renderer_host/media/audio_input_sync_writer.cc b/content/browser/renderer_host/media/audio_input_sync_writer.cc
index a043500..117fbe8 100644
--- a/content/browser/renderer_host/media/audio_input_sync_writer.cc
+++ b/content/browser/renderer_host/media/audio_input_sync_writer.cc
@@ -28,6 +28,7 @@ AudioInputSyncWriter::AudioInputSyncWriter(base::SharedMemory* shared_memory,
DVLOG(1) << "SharedMemory::requested_size: "
<< shared_memory->requested_size();
DVLOG(1) << "shared_memory_segment_count: " << shared_memory_segment_count;
+ DVLOG(1) << "audio_bus_memory_size: " << audio_bus_memory_size_;
// Create vector of audio buses by wrapping existing blocks of memory.
uint8* ptr = static_cast<uint8*>(shared_memory_->memory());
diff --git a/ppapi/proxy/DEPS b/ppapi/proxy/DEPS
index 1d723b4..6183b60 100644
--- a/ppapi/proxy/DEPS
+++ b/ppapi/proxy/DEPS
@@ -3,6 +3,7 @@ include_rules = [
"+gpu",
"+ipc",
"+media/audio",
+ "+media/base",
"+skia",
"+ui/surface",
"+ui/events",
diff --git a/ppapi/proxy/audio_input_resource.cc b/ppapi/proxy/audio_input_resource.cc
index 0ae1831..7f1f819 100644
--- a/ppapi/proxy/audio_input_resource.cc
+++ b/ppapi/proxy/audio_input_resource.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "ipc/ipc_platform_file.h"
#include "media/audio/audio_parameters.h"
+#include "media/base/audio_bus.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
@@ -22,9 +23,8 @@
namespace ppapi {
namespace proxy {
-AudioInputResource::AudioInputResource(
- Connection connection,
- PP_Instance instance)
+AudioInputResource::AudioInputResource(Connection connection,
+ PP_Instance instance)
: PluginResource(connection, instance),
open_state_(BEFORE_OPEN),
capturing_(false),
@@ -33,7 +33,9 @@ AudioInputResource::AudioInputResource(
audio_input_callback_(NULL),
user_data_(NULL),
enumeration_helper_(this),
- bytes_per_second_(0) {
+ bytes_per_second_(0),
+ sample_frame_count_(0),
+ client_buffer_size_bytes_(0) {
SendCreate(RENDERER, PpapiHostMsg_AudioInput_Create());
}
@@ -181,14 +183,33 @@ void AudioInputResource::SetStreamInfo(
socket_.reset(new base::CancelableSyncSocket(socket_handle));
shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
shared_memory_size_ = shared_memory_size;
+ DCHECK(!shared_memory_->memory());
- if (!shared_memory_->Map(shared_memory_size_)) {
- PpapiGlobals::Get()->LogWithSource(
- pp_instance(),
- PP_LOGLEVEL_WARNING,
- std::string(),
- "Failed to map shared memory for PPB_AudioInput_Shared.");
- }
+ // If we fail to map the shared memory into the caller's address space we
+ // might as well fail here since nothing will work if this is the case.
+ CHECK(shared_memory_->Map(shared_memory_size_));
+
+ // Create a new audio bus and wrap the audio data section in shared memory.
+ media::AudioInputBuffer* buffer =
+ static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
+ audio_bus_ = media::AudioBus::WrapMemory(
+ kAudioInputChannels, sample_frame_count_, buffer->audio);
+
+ // Ensure that the size of the created audio bus matches the allocated
+ // size in shared memory.
+ // Example: DCHECK_EQ(8208 - 16, 8192) for |sample_frame_count_| = 2048.
+ const uint32_t audio_bus_size_bytes = media::AudioBus::CalculateMemorySize(
+ audio_bus_->channels(), audio_bus_->frames());
+ DCHECK_EQ(shared_memory_size_ - sizeof(media::AudioInputBufferParameters),
+ audio_bus_size_bytes);
+
+ // Create an extra integer audio buffer for user audio data callbacks.
+ // Data in shared memory will be copied to this buffer, after interleaving
+ // and truncation, before each input callback to match the format expected
+ // by the client.
+ client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() *
+ kBitsPerAudioInputSample / 8;
+ client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]);
// There is a pending capture request before SetStreamInfo().
if (capturing_) {
@@ -202,7 +223,8 @@ void AudioInputResource::SetStreamInfo(
void AudioInputResource::StartThread() {
// Don't start the thread unless all our state is set up correctly.
if ((!audio_input_callback_0_3_ && !audio_input_callback_) ||
- !socket_.get() || !capturing_ || !shared_memory_->memory()) {
+ !socket_.get() || !capturing_ || !shared_memory_->memory() ||
+ !audio_bus_.get() || !client_buffer_.get()) {
return;
}
DCHECK(!audio_input_thread_.get());
@@ -223,28 +245,42 @@ void AudioInputResource::StopThread() {
void AudioInputResource::Run() {
// The shared memory represents AudioInputBufferParameters and the actual data
- // buffer.
+ // buffer stored as an audio bus.
media::AudioInputBuffer* buffer =
static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
- uint32_t data_buffer_size =
+ const uint32_t audio_bus_size_bytes =
shared_memory_size_ - sizeof(media::AudioInputBufferParameters);
- int pending_data;
- while (sizeof(pending_data) == socket_->Receive(&pending_data,
- sizeof(pending_data)) &&
- pending_data >= 0) {
+ while (true) {
+ int pending_data = 0;
+ size_t bytes_read = socket_->Receive(&pending_data, sizeof(pending_data));
+ if (bytes_read != sizeof(pending_data)) {
+ DCHECK_EQ(bytes_read, 0U);
+ break;
+ }
+ if (pending_data < 0)
+ break;
+
+ // Convert an AudioBus from deinterleaved float to interleaved integer data.
+ // Store the result in a preallocated |client_buffer_|.
+ audio_bus_->ToInterleaved(audio_bus_->frames(),
+ kBitsPerAudioInputSample / 8,
+ client_buffer_.get());
+
// While closing the stream, we may receive buffers whose size is different
// from |data_buffer_size|.
- CHECK_LE(buffer->params.size, data_buffer_size);
+ CHECK_LE(buffer->params.size, audio_bus_size_bytes);
if (buffer->params.size > 0) {
if (audio_input_callback_) {
PP_TimeDelta latency =
static_cast<double>(pending_data) / bytes_per_second_;
- audio_input_callback_(&buffer->audio[0], buffer->params.size, latency,
+ audio_input_callback_(client_buffer_.get(),
+ client_buffer_size_bytes_,
+ latency,
user_data_);
} else {
- audio_input_callback_0_3_(&buffer->audio[0], buffer->params.size,
- user_data_);
+ audio_input_callback_0_3_(
+ client_buffer_.get(), client_buffer_size_bytes_, user_data_);
}
}
}
@@ -287,6 +323,7 @@ int32_t AudioInputResource::CommonOpen(
open_callback_ = callback;
bytes_per_second_ = kAudioInputChannels * (kBitsPerAudioInputSample / 8) *
enter_config.object()->GetSampleRate();
+ sample_frame_count_ = enter_config.object()->GetSampleFrameCount();
PpapiHostMsg_AudioInput_Open msg(
device_id, enter_config.object()->GetSampleRate(),
diff --git a/ppapi/proxy/audio_input_resource.h b/ppapi/proxy/audio_input_resource.h
index e4d0e73..0184260 100644
--- a/ppapi/proxy/audio_input_resource.h
+++ b/ppapi/proxy/audio_input_resource.h
@@ -17,6 +17,10 @@
#include "ppapi/shared_impl/scoped_pp_resource.h"
#include "ppapi/thunk/ppb_audio_input_api.h"
+namespace media {
+class AudioBus;
+}
+
namespace ppapi {
namespace proxy {
@@ -133,6 +137,14 @@ class AudioInputResource : public PluginResource,
// latency.
size_t bytes_per_second_;
+ // AudioBus for shuttling data across the shared memory.
+ scoped_ptr<media::AudioBus> audio_bus_;
+ int sample_frame_count_;
+
+ // Internal buffer for client's integer audio data.
+ int client_buffer_size_bytes_;
+ scoped_ptr<uint8_t[]> client_buffer_;
+
DISALLOW_COPY_AND_ASSIGN(AudioInputResource);
};