summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
+ }
}
}