Chromium Code Reviews| Index: ppapi/shared_impl/ppb_audio_shared.cc |
| diff --git a/ppapi/shared_impl/ppb_audio_shared.cc b/ppapi/shared_impl/ppb_audio_shared.cc |
| index c52ea555848b9fd2d9f25ce021e0ad3bdfe7aa07..7dfb8a60cad2abd7e1be6f8e575ba48a1edaf4ee 100644 |
| --- a/ppapi/shared_impl/ppb_audio_shared.cc |
| +++ b/ppapi/shared_impl/ppb_audio_shared.cc |
| @@ -7,12 +7,9 @@ |
| #include "base/logging.h" |
| #include "media/audio/shared_memory_util.h" |
| #include "ppapi/shared_impl/ppapi_globals.h" |
| +#include "ppapi/shared_impl/ppb_audio_config_shared.h" |
| #include "ppapi/shared_impl/proxy_lock.h" |
| -// Hard coded values from PepperPlatformAudioOutputImpl. |
| -// TODO(dalecurtis): PPAPI shouldn't hard code these values for all clients. |
| -enum { kChannels = 2, kBytesPerSample = 2 }; |
| - |
| namespace ppapi { |
| #if defined(OS_NACL) |
| @@ -22,6 +19,37 @@ PP_ThreadFunctions thread_functions; |
| } |
| #endif // defined(OS_NACL) |
| +AudioCallback::AudioCallback() : callback_1_0_(NULL), callback_(NULL) { |
| +} |
| + |
| +AudioCallback::AudioCallback(PPB_Audio_Callback_1_0 callback_1_0) |
| + : callback_1_0_(callback_1_0), |
| + callback_(NULL) { |
| +} |
| + |
| +AudioCallback::AudioCallback(PPB_Audio_Callback callback) |
| + : callback_1_0_(NULL), |
| + callback_(callback) { |
| +} |
| + |
| +AudioCallback::~AudioCallback() { |
| +} |
| + |
| +bool AudioCallback::IsValid() const { |
| + return callback_1_0_ || callback_; |
| +} |
| + |
| +void AudioCallback::Run(void* sample_buffer, |
| + uint32_t buffer_size_in_bytes, |
| + PP_TimeDelta latency, |
| + void* user_data) const { |
|
dmichael (off chromium)
2013/08/06 19:43:25
Should we DCHECK(callback_ || callback_1_0_)? Or e
yzshen1
2013/08/07 20:51:06
Done.
|
| + if (callback_) { |
| + callback_(sample_buffer, buffer_size_in_bytes, latency, user_data); |
| + } else if (callback_1_0_) { |
| + callback_1_0_(sample_buffer, buffer_size_in_bytes, user_data); |
| + } |
| +} |
| + |
| PPB_Audio_Shared::PPB_Audio_Shared() |
| : playing_(false), |
| shared_memory_size_(0), |
| @@ -29,9 +57,9 @@ PPB_Audio_Shared::PPB_Audio_Shared() |
| thread_id_(0), |
| thread_active_(false), |
| #endif |
| - callback_(NULL), |
| user_data_(NULL), |
| - client_buffer_size_bytes_(0) { |
| + client_buffer_size_bytes_(0), |
| + bytes_per_second_(0) { |
| } |
| PPB_Audio_Shared::~PPB_Audio_Shared() { |
| @@ -41,7 +69,7 @@ PPB_Audio_Shared::~PPB_Audio_Shared() { |
| StopThread(); |
| } |
| -void PPB_Audio_Shared::SetCallback(PPB_Audio_Callback callback, |
| +void PPB_Audio_Shared::SetCallback(const AudioCallback& callback, |
| void* user_data) { |
| callback_ = callback; |
| user_data_ = user_data; |
| @@ -74,10 +102,13 @@ void PPB_Audio_Shared::SetStreamInfo( |
| base::SharedMemoryHandle shared_memory_handle, |
| size_t shared_memory_size, |
| base::SyncSocket::Handle socket_handle, |
| + PP_AudioSampleRate sample_rate, |
| int sample_frame_count) { |
| socket_.reset(new base::CancelableSyncSocket(socket_handle)); |
| shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); |
| shared_memory_size_ = shared_memory_size; |
| + bytes_per_second_ = kAudioOutputChannels * (kBitsPerAudioOutputSample / 8) * |
| + sample_rate; |
| if (!shared_memory_->Map( |
| media::TotalSharedMemorySizeInBytes(shared_memory_size_))) { |
| @@ -88,10 +119,11 @@ void PPB_Audio_Shared::SetStreamInfo( |
| "Failed to map shared memory for PPB_Audio_Shared."); |
| } else { |
| audio_bus_ = media::AudioBus::WrapMemory( |
| - kChannels, sample_frame_count, shared_memory_->memory()); |
| + kAudioOutputChannels, sample_frame_count, shared_memory_->memory()); |
| // Setup integer audio buffer for user audio data. |
| client_buffer_size_bytes_ = |
| - audio_bus_->frames() * audio_bus_->channels() * kBytesPerSample; |
| + audio_bus_->frames() * audio_bus_->channels() * |
| + kBitsPerAudioOutputSample / 8; |
| client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); |
| } |
| @@ -100,8 +132,9 @@ void PPB_Audio_Shared::SetStreamInfo( |
| void PPB_Audio_Shared::StartThread() { |
| // Don't start the thread unless all our state is set up correctly. |
| - if (!playing_ || !callback_ || !socket_.get() || !shared_memory_->memory() || |
| - !audio_bus_.get() || !client_buffer_.get()) |
| + if (!playing_ || !callback_.IsValid() || !socket_.get() || |
| + !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || |
| + bytes_per_second_ == 0) |
| return; |
| // Clear contents of shm buffer before starting audio thread. This will |
| // prevent a burst of static if for some reason the audio thread doesn't |
| @@ -173,11 +206,15 @@ void PPB_Audio_Shared::Run() { |
| while (sizeof(pending_data) == |
| socket_->Receive(&pending_data, sizeof(pending_data)) && |
| pending_data != media::kPauseMark) { |
| - callback_(client_buffer_.get(), client_buffer_size_bytes_, user_data_); |
| + PP_TimeDelta latency = |
| + static_cast<double>(pending_data) / bytes_per_second_; |
| + callback_.Run(client_buffer_.get(), client_buffer_size_bytes_, latency, |
| + user_data_); |
| // Deinterleave the audio data into the shared memory as float. |
| audio_bus_->FromInterleaved( |
| - client_buffer_.get(), audio_bus_->frames(), kBytesPerSample); |
| + client_buffer_.get(), audio_bus_->frames(), |
| + kBitsPerAudioOutputSample / 8); |
| // Let the host know we are done. |
| // TODO(dalecurtis): Technically this is not the exact size. Due to channel |