summaryrefslogtreecommitdiffstats
path: root/ppapi/shared_impl
diff options
context:
space:
mode:
authorenal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-01 18:49:00 +0000
committerenal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-01 18:49:00 +0000
commitbba8669ac315e0710b9b544c93d3e4ab6734911b (patch)
treeda768293faed8e59d7efb7ca00d631cb491f8ff5 /ppapi/shared_impl
parentd1a149dab6387603f81a60760214ed7dd2ebcd6e (diff)
downloadchromium_src-bba8669ac315e0710b9b544c93d3e4ab6734911b.zip
chromium_src-bba8669ac315e0710b9b544c93d3e4ab6734911b.tar.gz
chromium_src-bba8669ac315e0710b9b544c93d3e4ab6734911b.tar.bz2
Prepare ppapi for chrome audio changes. Now chrome writes length of audio data
to buffers, thus allowing to correctly handle short audio streams (e.g. sound effects in games). Those changes allows ppapi to handle both "old" and "new" audio streams, you can find out if stream is "old" or "new" by amount of data you get when receiving request from the socket. After chrome changes would be checked in "old" code path can be safely removed. Corresponding chrome change is http://codereview.chromium.org/7328030/. BUG=http://code.google.com/p/chromium/issues/detail?id=78992. PS. After several comments I changed chrome code to make it much harder for code to get buffer overrun. I was pointed that native client can write bogus size of data into buffer, so function in chrome that reads size of data now has extra argument -- max size of buffer, and returns min(max size of buffer, size of data reported by client). This way min() is always called. Review URL: http://codereview.chromium.org/7523008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94947 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/shared_impl')
-rw-r--r--ppapi/shared_impl/audio_impl.cc54
1 files changed, 47 insertions, 7 deletions
diff --git a/ppapi/shared_impl/audio_impl.cc b/ppapi/shared_impl/audio_impl.cc
index 42254f5..0816f41 100644
--- a/ppapi/shared_impl/audio_impl.cc
+++ b/ppapi/shared_impl/audio_impl.cc
@@ -4,8 +4,11 @@
#include "ppapi/shared_impl/audio_impl.h"
+#include "base/atomicops.h"
#include "base/logging.h"
+using base::subtle::Atomic32;
+
namespace ppapi {
AudioImpl::AudioImpl()
@@ -82,14 +85,51 @@ void AudioImpl::StartThread() {
audio_thread_->Start();
}
-void AudioImpl::Run() {
- int pending_data;
- void* buffer = shared_memory_->memory();
+// PPB_AudioBuffersState defines the type of an audio buffer state structure
+// sent when requesting to fill the audio buffer with data.
+typedef struct {
+ int pending_bytes;
+ int hardware_delay_bytes;
+ uint64_t timestamp;
+} PPB_AudioBuffersState;
+PP_COMPILE_ASSERT_SIZE_IN_BYTES(PPB_AudioBuffersState, 16);
- while (sizeof(pending_data) ==
- socket_->Receive(&pending_data, sizeof(pending_data)) &&
- pending_data >= 0) {
- callback_(buffer, shared_memory_size_, user_data_);
+void AudioImpl::Run() {
+ PPB_AudioBuffersState buffer_state;
+
+ for (;;) {
+ int bytes_received = socket_->Receive(&buffer_state, sizeof(buffer_state));
+ if (bytes_received == sizeof(int)) {
+ // Accoding to C++ Standard, address of structure == address of its first
+ // member, so it is safe to use buffer_state.bytes_received when we
+ // receive just one int.
+ COMPILE_ASSERT(
+ offsetof(PPB_AudioBuffersState, pending_bytes) == 0,
+ pending_bytes_should_be_first_member_of_PPB_AudioBuffersState);
+ if (buffer_state.pending_bytes < 0)
+ break;
+ callback_(shared_memory_->memory(), shared_memory_size_, user_data_);
+ } else if (bytes_received == sizeof(buffer_state)) {
+ if (buffer_state.pending_bytes + buffer_state.hardware_delay_bytes < 0)
+ break;
+
+ // Assert that shared memory is properly aligned, so we can cast pointer
+ // to the pointer to Atomic32.
+ DCHECK_EQ(0u, reinterpret_cast<size_t>(shared_memory_->memory()) & 3);
+
+ // TODO(enal): Instead of address arithmetics use functions that
+ // encapsulate internal buffer structure. They should be moved somewhere
+ // into ppapi, right now they are defined in media/audio/audio_util.h.
+ uint32 data_size = shared_memory_size_ - sizeof(Atomic32);
+ callback_(static_cast<char*>(shared_memory_->memory()) + sizeof(Atomic32),
+ data_size,
+ user_data_);
+ base::subtle::Release_Store(
+ static_cast<volatile Atomic32*>(shared_memory_->memory()),
+ data_size);
+ } else {
+ break;
+ }
}
}