diff options
-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; + } } } |