diff options
author | enal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-01 18:49:00 +0000 |
---|---|---|
committer | enal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-01 18:49:00 +0000 |
commit | bba8669ac315e0710b9b544c93d3e4ab6734911b (patch) | |
tree | da768293faed8e59d7efb7ca00d631cb491f8ff5 /ppapi/shared_impl | |
parent | d1a149dab6387603f81a60760214ed7dd2ebcd6e (diff) | |
download | chromium_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.cc | 54 |
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; + } } } |