| Index: ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc
 | 
| diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc
 | 
| index 18558e6370a576a8848024d31cb1264e2047642f..6a4cfd9d7bfbe0de3a887a7f808eea3e29997e4e 100644
 | 
| --- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc
 | 
| +++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_audio.cc
 | 
| @@ -30,6 +30,10 @@ size_t ceil64k(size_t n) {
 | 
|    return (n + 0xFFFF) & (~0xFFFF);
 | 
|  }
 | 
|  
 | 
| +// Hard coded values from PepperPlatformAudioOutputImpl.
 | 
| +// TODO(???): PPAPI shouldn't hard code these values for all clients.
 | 
| +enum { kChannels = 2, kBytesPerSample = 2 };
 | 
| +
 | 
|  }  // namespace
 | 
|  
 | 
|  PluginAudio::PluginAudio() :
 | 
| @@ -42,7 +46,8 @@ PluginAudio::PluginAudio() :
 | 
|      thread_id_(),
 | 
|      thread_active_(false),
 | 
|      user_callback_(NULL),
 | 
| -    user_data_(NULL) {
 | 
| +    user_data_(NULL),
 | 
| +    audio_buffer_size_(0) {
 | 
|    DebugPrintf("PluginAudio::PluginAudio\n");
 | 
|  }
 | 
|  
 | 
| @@ -53,10 +58,13 @@ PluginAudio::~PluginAudio() {
 | 
|      GetInterface()->StopPlayback(resource_);
 | 
|    // Unmap the shared memory buffer, if present.
 | 
|    if (shm_buffer_) {
 | 
| +    audio_bus_.reset();
 | 
| +    audio_buffer_.reset();
 | 
|      munmap(shm_buffer_,
 | 
|             ceil64k(media::TotalSharedMemorySizeInBytes(shm_size_)));
 | 
|      shm_buffer_ = NULL;
 | 
|      shm_size_ = 0;
 | 
| +    audio_buffer_size_ = 0;
 | 
|    }
 | 
|    // Close the handles.
 | 
|    if (shm_ != -1) {
 | 
| @@ -87,9 +95,15 @@ void PluginAudio::AudioThread(void* self) {
 | 
|      if ((sizeof(sync_value) != r) || (-1 == sync_value))
 | 
|        break;
 | 
|      // Invoke user callback, get next buffer of audio data.
 | 
| -    audio->user_callback_(audio->shm_buffer_,
 | 
| -                          audio->shm_size_,
 | 
| +    audio->user_callback_(audio->audio_buffer_.get(),
 | 
| +                          audio->audio_buffer_size_,
 | 
|                            audio->user_data_);
 | 
| +
 | 
| +    // Deinterleave the audio data into the shared memory as float.
 | 
| +    audio->audio_bus_->FromInterleaved(
 | 
| +        audio->audio_buffer_.get(), audio->audio_bus_->frames(),
 | 
| +        kBytesPerSample);
 | 
| +
 | 
|      // Signal audio backend by writing buffer length at end of buffer.
 | 
|      // (Note: NaCl applications will always write the entire buffer.)
 | 
|      media::SetActualDataSizeInBytes(audio->shm_buffer_,
 | 
| @@ -112,6 +126,14 @@ void PluginAudio::StreamCreated(NaClSrpcImcDescType socket,
 | 
|                       shm,
 | 
|                       0);
 | 
|    if (MAP_FAILED != shm_buffer_) {
 | 
| +    // Deduce the frame count from the size using hard coded channel count.
 | 
| +    audio_bus_ = media::AudioBus::WrapMemory(
 | 
| +        kChannels, shm_size_ / (sizeof(float) * kChannels), shm_buffer_);
 | 
| +    // Setup integer audio buffer for user audio data.
 | 
| +    audio_buffer_size_ =
 | 
| +        audio_bus_->frames() * audio_bus_->channels() * kBytesPerSample;
 | 
| +    audio_buffer_.reset(new uint8_t[audio_buffer_size_]);
 | 
| +
 | 
|      if (state() == AUDIO_PENDING) {
 | 
|        StartAudioThread();
 | 
|      } else {
 | 
| @@ -126,6 +148,7 @@ bool PluginAudio::StartAudioThread() {
 | 
|    // clear contents of shm buffer before spinning up audio thread
 | 
|    DebugPrintf("PluginAudio::StartAudioThread\n");
 | 
|    memset(shm_buffer_, 0, shm_size_);
 | 
| +  memset(audio_buffer_.get(), 0, audio_buffer_size_);
 | 
|    const struct PP_ThreadFunctions* thread_funcs = GetThreadCreator();
 | 
|    if (NULL == thread_funcs->thread_create ||
 | 
|        NULL == thread_funcs->thread_join) {
 | 
| 
 |