Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/shared_impl/ppb_audio_shared.h" | 5 #include "ppapi/shared_impl/ppb_audio_shared.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "ppapi/shared_impl/ppapi_globals.h" | 8 #include "ppapi/shared_impl/ppapi_globals.h" |
| 9 | 9 |
| 10 using base::subtle::Atomic32; | 10 using base::subtle::Atomic32; |
| 11 | 11 |
| 12 namespace ppapi { | 12 namespace ppapi { |
| 13 | 13 |
| 14 #if defined(OS_NACL) | |
| 15 namespace { | |
| 16 PP_ThreadFunctions thread_functions; | |
|
dmichael (off chromium)
2012/07/24 20:55:21
Later on, you're relying on it getting zero initia
bbudge
2012/07/24 21:15:44
I'll add a comment. Done.
| |
| 17 } | |
| 18 #endif // defined(OS_NACL) | |
| 19 | |
| 14 // FIXME: The following two functions (TotalSharedMemorySizeInBytes, | 20 // FIXME: The following two functions (TotalSharedMemorySizeInBytes, |
| 15 // SetActualDataSizeInBytes) are copied from audio_util.cc. | 21 // SetActualDataSizeInBytes) are copied from audio_util.cc. |
| 16 // Remove these functions once a minimal media library is provided for them. | 22 // Remove these functions once a minimal media library is provided for them. |
| 17 // code.google.com/p/chromium/issues/detail?id=123203 | 23 // code.google.com/p/chromium/issues/detail?id=123203 |
| 18 | 24 |
| 19 uint32 TotalSharedMemorySizeInBytes(uint32 packet_size) { | 25 uint32 TotalSharedMemorySizeInBytes(uint32 packet_size) { |
| 20 // Need to reserve extra 4 bytes for size of data. | 26 // Need to reserve extra 4 bytes for size of data. |
| 21 return packet_size + sizeof(Atomic32); | 27 return packet_size + sizeof(Atomic32); |
| 22 } | 28 } |
| 23 | 29 |
| 24 void SetActualDataSizeInBytes(base::SharedMemory* shared_memory, | 30 void SetActualDataSizeInBytes(base::SharedMemory* shared_memory, |
| 25 uint32 shared_memory_size, | 31 uint32 shared_memory_size, |
| 26 uint32 actual_data_size) { | 32 uint32 actual_data_size) { |
| 27 char* ptr = static_cast<char*>(shared_memory->memory()) + shared_memory_size; | 33 char* ptr = static_cast<char*>(shared_memory->memory()) + shared_memory_size; |
| 28 DCHECK_EQ(0u, reinterpret_cast<size_t>(ptr) & 3); | 34 DCHECK_EQ(0u, reinterpret_cast<size_t>(ptr) & 3); |
| 29 | 35 |
| 30 // Set actual data size at the end of the buffer. | 36 // Set actual data size at the end of the buffer. |
| 31 base::subtle::Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), | 37 base::subtle::Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), |
| 32 actual_data_size); | 38 actual_data_size); |
| 33 } | 39 } |
| 34 | 40 |
| 35 const int PPB_Audio_Shared::kPauseMark = -1; | 41 const int PPB_Audio_Shared::kPauseMark = -1; |
| 36 | 42 |
| 37 PPB_Audio_Shared::PPB_Audio_Shared() | 43 PPB_Audio_Shared::PPB_Audio_Shared() |
| 38 : playing_(false), | 44 : playing_(false), |
| 39 shared_memory_size_(0), | 45 shared_memory_size_(0), |
| 46 #if defined(OS_NACL) | |
| 47 thread_id_(), | |
| 48 thread_active_(false), | |
| 49 #endif | |
| 40 callback_(NULL), | 50 callback_(NULL), |
| 41 user_data_(NULL) { | 51 user_data_(NULL) { |
| 42 } | 52 } |
| 43 | 53 |
| 44 PPB_Audio_Shared::~PPB_Audio_Shared() { | 54 PPB_Audio_Shared::~PPB_Audio_Shared() { |
| 45 StopThread(); | 55 StopThread(); |
| 46 } | 56 } |
| 47 | 57 |
| 48 void PPB_Audio_Shared::SetCallback(PPB_Audio_Callback callback, | 58 void PPB_Audio_Shared::SetCallback(PPB_Audio_Callback callback, |
| 49 void* user_data) { | 59 void* user_data) { |
| 50 callback_ = callback; | 60 callback_ = callback; |
| 51 user_data_ = user_data; | 61 user_data_ = user_data; |
| 52 } | 62 } |
| 53 | 63 |
| 54 void PPB_Audio_Shared::SetStartPlaybackState() { | 64 void PPB_Audio_Shared::SetStartPlaybackState() { |
| 55 DCHECK(!playing_); | 65 DCHECK(!playing_); |
| 66 #if !defined(OS_NACL) | |
| 56 DCHECK(!audio_thread_.get()); | 67 DCHECK(!audio_thread_.get()); |
| 57 | 68 #else |
| 69 DCHECK(!thread_active_); | |
| 70 #endif | |
| 58 // If the socket doesn't exist, that means that the plugin has started before | 71 // If the socket doesn't exist, that means that the plugin has started before |
| 59 // the browser has had a chance to create all the shared memory info and | 72 // the browser has had a chance to create all the shared memory info and |
| 60 // notify us. This is a common case. In this case, we just set the playing_ | 73 // notify us. This is a common case. In this case, we just set the playing_ |
| 61 // flag and the playback will automatically start when that data is available | 74 // flag and the playback will automatically start when that data is available |
| 62 // in SetStreamInfo. | 75 // in SetStreamInfo. |
| 63 playing_ = true; | 76 playing_ = true; |
| 64 StartThread(); | 77 StartThread(); |
| 65 } | 78 } |
| 66 | 79 |
| 67 void PPB_Audio_Shared::SetStopPlaybackState() { | 80 void PPB_Audio_Shared::SetStopPlaybackState() { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 84 "Failed to map shared memory for PPB_Audio_Shared."); | 97 "Failed to map shared memory for PPB_Audio_Shared."); |
| 85 } | 98 } |
| 86 | 99 |
| 87 StartThread(); | 100 StartThread(); |
| 88 } | 101 } |
| 89 | 102 |
| 90 void PPB_Audio_Shared::StartThread() { | 103 void PPB_Audio_Shared::StartThread() { |
| 91 // Don't start the thread unless all our state is set up correctly. | 104 // Don't start the thread unless all our state is set up correctly. |
| 92 if (!playing_ || !callback_ || !socket_.get() || !shared_memory_->memory()) | 105 if (!playing_ || !callback_ || !socket_.get() || !shared_memory_->memory()) |
| 93 return; | 106 return; |
| 107 #if !defined(OS_NACL) | |
| 94 DCHECK(!audio_thread_.get()); | 108 DCHECK(!audio_thread_.get()); |
| 95 audio_thread_.reset(new base::DelegateSimpleThread( | 109 audio_thread_.reset(new base::DelegateSimpleThread( |
| 96 this, "plugin_audio_thread")); | 110 this, "plugin_audio_thread")); |
| 97 audio_thread_->Start(); | 111 audio_thread_->Start(); |
| 112 #else | |
| 113 // Clear contents of shm buffer before starting audio thread. | |
| 114 memset(shared_memory_->memory(), 0, shared_memory_size_); | |
|
dmichael (off chromium)
2012/07/24 20:55:21
I'd rather the comment said why we're doing this.
bbudge
2012/07/24 21:15:44
I copied this from the SRPC proxy code. I agree, i
| |
| 115 // Use NaCl's special API for IRT code that creates threads that call back | |
| 116 // into user code. | |
| 117 if (NULL == thread_functions.thread_create || | |
| 118 NULL == thread_functions.thread_join) | |
| 119 return; | |
| 120 | |
| 121 int result = thread_functions.thread_create(&thread_id_, CallRun, this); | |
| 122 DCHECK(result == 0); | |
| 123 thread_active_ = true; | |
| 124 #endif | |
| 98 } | 125 } |
| 99 | 126 |
| 100 void PPB_Audio_Shared::StopThread() { | 127 void PPB_Audio_Shared::StopThread() { |
| 101 // Shut down the socket to escape any hanging |Receive|s. | 128 // Shut down the socket to escape any hanging |Receive|s. |
| 102 if (socket_.get()) | 129 if (socket_.get()) |
| 103 socket_->Shutdown(); | 130 socket_->Shutdown(); |
| 131 #if !defined(OS_NACL) | |
| 104 if (audio_thread_.get()) { | 132 if (audio_thread_.get()) { |
| 105 audio_thread_->Join(); | 133 audio_thread_->Join(); |
| 106 audio_thread_.reset(); | 134 audio_thread_.reset(); |
| 107 } | 135 } |
| 136 #else | |
| 137 if (thread_active_) { | |
| 138 int result = thread_functions.thread_join(thread_id_); | |
| 139 DCHECK(0 == result); | |
| 140 thread_active_ = false; | |
| 141 } | |
| 142 #endif | |
| 108 } | 143 } |
| 109 | 144 |
| 145 #if defined(OS_NACL) | |
| 146 // static | |
| 147 void PPB_Audio_Shared::SetThreadFunctions( | |
| 148 const struct PP_ThreadFunctions* functions) { | |
| 149 DCHECK(thread_functions.thread_create == NULL); | |
| 150 DCHECK(thread_functions.thread_join == NULL); | |
| 151 thread_functions = *functions; | |
| 152 } | |
| 153 | |
| 154 // static | |
| 155 void PPB_Audio_Shared::CallRun(void* self) { | |
| 156 PPB_Audio_Shared* audio = static_cast<PPB_Audio_Shared*>(self); | |
| 157 audio->Run(); | |
| 158 } | |
| 159 #endif | |
| 160 | |
| 110 void PPB_Audio_Shared::Run() { | 161 void PPB_Audio_Shared::Run() { |
| 111 int pending_data; | 162 int pending_data; |
| 112 void* buffer = shared_memory_->memory(); | 163 void* buffer = shared_memory_->memory(); |
| 113 | 164 |
| 114 while (sizeof(pending_data) == | 165 while (sizeof(pending_data) == |
| 115 socket_->Receive(&pending_data, sizeof(pending_data)) && | 166 socket_->Receive(&pending_data, sizeof(pending_data)) && |
| 116 pending_data != kPauseMark) { | 167 pending_data != kPauseMark) { |
| 117 callback_(buffer, shared_memory_size_, user_data_); | 168 callback_(buffer, shared_memory_size_, user_data_); |
| 118 | 169 |
| 119 // Let the host know we are done. | 170 // Let the host know we are done. |
| 120 SetActualDataSizeInBytes(shared_memory_.get(), shared_memory_size_, | 171 SetActualDataSizeInBytes(shared_memory_.get(), shared_memory_size_, |
| 121 shared_memory_size_); | 172 shared_memory_size_); |
| 122 } | 173 } |
| 123 } | 174 } |
| 124 | 175 |
| 125 } // namespace ppapi | 176 } // namespace ppapi |
| OLD | NEW |