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 #include "ppapi/shared_impl/ppb_audio_config_shared.h" | 9 #include "ppapi/shared_impl/ppb_audio_config_shared.h" |
10 #include "ppapi/shared_impl/proxy_lock.h" | 10 #include "ppapi/shared_impl/proxy_lock.h" |
11 | 11 |
12 namespace ppapi { | 12 namespace ppapi { |
13 | 13 |
14 #if defined(OS_NACL) | 14 #if defined(OS_NACL) |
15 namespace { | 15 namespace { |
16 // Because this is static, the function pointers will be NULL initially. | 16 // Because this is static, the function pointers will be NULL initially. |
17 PP_ThreadFunctions thread_functions; | 17 PP_ThreadFunctions thread_functions; |
18 } | 18 } |
19 #endif // defined(OS_NACL) | 19 #endif // defined(OS_NACL) |
20 | 20 |
21 AudioCallbackCombined::AudioCallbackCombined() : callback_1_0_(NULL), | 21 AudioCallbackCombined::AudioCallbackCombined() |
22 callback_(NULL) { | 22 : callback_1_0_(NULL), callback_(NULL) {} |
23 } | |
24 | 23 |
25 AudioCallbackCombined::AudioCallbackCombined( | 24 AudioCallbackCombined::AudioCallbackCombined( |
26 PPB_Audio_Callback_1_0 callback_1_0) | 25 PPB_Audio_Callback_1_0 callback_1_0) |
27 : callback_1_0_(callback_1_0), | 26 : callback_1_0_(callback_1_0), callback_(NULL) {} |
28 callback_(NULL) { | |
29 } | |
30 | 27 |
31 AudioCallbackCombined::AudioCallbackCombined(PPB_Audio_Callback callback) | 28 AudioCallbackCombined::AudioCallbackCombined(PPB_Audio_Callback callback) |
32 : callback_1_0_(NULL), | 29 : callback_1_0_(NULL), callback_(callback) {} |
33 callback_(callback) { | |
34 } | |
35 | 30 |
36 AudioCallbackCombined::~AudioCallbackCombined() { | 31 AudioCallbackCombined::~AudioCallbackCombined() {} |
37 } | |
38 | 32 |
39 bool AudioCallbackCombined::IsValid() const { | 33 bool AudioCallbackCombined::IsValid() const { |
40 return callback_1_0_ || callback_; | 34 return callback_1_0_ || callback_; |
41 } | 35 } |
42 | 36 |
43 void AudioCallbackCombined::Run(void* sample_buffer, | 37 void AudioCallbackCombined::Run(void* sample_buffer, |
44 uint32_t buffer_size_in_bytes, | 38 uint32_t buffer_size_in_bytes, |
45 PP_TimeDelta latency, | 39 PP_TimeDelta latency, |
46 void* user_data) const { | 40 void* user_data) const { |
47 if (callback_) { | 41 if (callback_) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 void PPB_Audio_Shared::SetStreamInfo( | 98 void PPB_Audio_Shared::SetStreamInfo( |
105 PP_Instance instance, | 99 PP_Instance instance, |
106 base::SharedMemoryHandle shared_memory_handle, | 100 base::SharedMemoryHandle shared_memory_handle, |
107 size_t shared_memory_size, | 101 size_t shared_memory_size, |
108 base::SyncSocket::Handle socket_handle, | 102 base::SyncSocket::Handle socket_handle, |
109 PP_AudioSampleRate sample_rate, | 103 PP_AudioSampleRate sample_rate, |
110 int sample_frame_count) { | 104 int sample_frame_count) { |
111 socket_.reset(new base::CancelableSyncSocket(socket_handle)); | 105 socket_.reset(new base::CancelableSyncSocket(socket_handle)); |
112 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); | 106 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); |
113 shared_memory_size_ = shared_memory_size; | 107 shared_memory_size_ = shared_memory_size; |
114 bytes_per_second_ = kAudioOutputChannels * (kBitsPerAudioOutputSample / 8) * | 108 bytes_per_second_ = |
115 sample_rate; | 109 kAudioOutputChannels * (kBitsPerAudioOutputSample / 8) * sample_rate; |
116 buffer_index_ = 0; | 110 buffer_index_ = 0; |
117 | 111 |
118 if (!shared_memory_->Map(shared_memory_size_)) { | 112 if (!shared_memory_->Map(shared_memory_size_)) { |
119 PpapiGlobals::Get()->LogWithSource( | 113 PpapiGlobals::Get()->LogWithSource( |
120 instance, | 114 instance, |
121 PP_LOGLEVEL_WARNING, | 115 PP_LOGLEVEL_WARNING, |
122 std::string(), | 116 std::string(), |
123 "Failed to map shared memory for PPB_Audio_Shared."); | 117 "Failed to map shared memory for PPB_Audio_Shared."); |
124 } else { | 118 } else { |
125 audio_bus_ = media::AudioBus::WrapMemory( | 119 audio_bus_ = media::AudioBus::WrapMemory( |
126 kAudioOutputChannels, sample_frame_count, shared_memory_->memory()); | 120 kAudioOutputChannels, sample_frame_count, shared_memory_->memory()); |
127 // Setup integer audio buffer for user audio data. | 121 // Setup integer audio buffer for user audio data. |
128 client_buffer_size_bytes_ = | 122 client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() * |
129 audio_bus_->frames() * audio_bus_->channels() * | 123 kBitsPerAudioOutputSample / 8; |
130 kBitsPerAudioOutputSample / 8; | |
131 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); | 124 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); |
132 } | 125 } |
133 | 126 |
134 StartThread(); | 127 StartThread(); |
135 } | 128 } |
136 | 129 |
137 void PPB_Audio_Shared::StartThread() { | 130 void PPB_Audio_Shared::StartThread() { |
138 // Don't start the thread unless all our state is set up correctly. | 131 // Don't start the thread unless all our state is set up correctly. |
139 if (!playing_ || !callback_.IsValid() || !socket_.get() || | 132 if (!playing_ || !callback_.IsValid() || !socket_.get() || |
140 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || | 133 !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() || |
141 bytes_per_second_ == 0) | 134 bytes_per_second_ == 0) |
142 return; | 135 return; |
143 // Clear contents of shm buffer before starting audio thread. This will | 136 // Clear contents of shm buffer before starting audio thread. This will |
144 // prevent a burst of static if for some reason the audio thread doesn't | 137 // prevent a burst of static if for some reason the audio thread doesn't |
145 // start up quickly enough. | 138 // start up quickly enough. |
146 memset(shared_memory_->memory(), 0, shared_memory_size_); | 139 memset(shared_memory_->memory(), 0, shared_memory_size_); |
147 memset(client_buffer_.get(), 0, client_buffer_size_bytes_); | 140 memset(client_buffer_.get(), 0, client_buffer_size_bytes_); |
148 #if !defined(OS_NACL) | 141 #if !defined(OS_NACL) |
149 DCHECK(!audio_thread_.get()); | 142 DCHECK(!audio_thread_.get()); |
150 audio_thread_.reset(new base::DelegateSimpleThread( | 143 audio_thread_.reset( |
151 this, "plugin_audio_thread")); | 144 new base::DelegateSimpleThread(this, "plugin_audio_thread")); |
152 audio_thread_->Start(); | 145 audio_thread_->Start(); |
153 #else | 146 #else |
154 // Use NaCl's special API for IRT code that creates threads that call back | 147 // Use NaCl's special API for IRT code that creates threads that call back |
155 // into user code. | 148 // into user code. |
156 if (NULL == thread_functions.thread_create || | 149 if (NULL == thread_functions.thread_create || |
157 NULL == thread_functions.thread_join) | 150 NULL == thread_functions.thread_join) |
158 return; | 151 return; |
159 | 152 |
160 int result = thread_functions.thread_create(&thread_id_, CallRun, this); | 153 int result = thread_functions.thread_create(&thread_id_, CallRun, this); |
161 DCHECK_EQ(result, 0); | 154 DCHECK_EQ(result, 0); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 while (sizeof(pending_data) == | 200 while (sizeof(pending_data) == |
208 socket_->Receive(&pending_data, sizeof(pending_data))) { | 201 socket_->Receive(&pending_data, sizeof(pending_data))) { |
209 // |buffer_index_| must track the number of Receive() calls. See the Send() | 202 // |buffer_index_| must track the number of Receive() calls. See the Send() |
210 // call below for why this is important. | 203 // call below for why this is important. |
211 ++buffer_index_; | 204 ++buffer_index_; |
212 if (pending_data < 0) | 205 if (pending_data < 0) |
213 break; | 206 break; |
214 | 207 |
215 PP_TimeDelta latency = | 208 PP_TimeDelta latency = |
216 static_cast<double>(pending_data) / bytes_per_second_; | 209 static_cast<double>(pending_data) / bytes_per_second_; |
217 callback_.Run(client_buffer_.get(), client_buffer_size_bytes_, latency, | 210 callback_.Run( |
218 user_data_); | 211 client_buffer_.get(), client_buffer_size_bytes_, latency, user_data_); |
219 | 212 |
220 // Deinterleave the audio data into the shared memory as floats. | 213 // Deinterleave the audio data into the shared memory as floats. |
221 audio_bus_->FromInterleaved( | 214 audio_bus_->FromInterleaved(client_buffer_.get(), |
222 client_buffer_.get(), audio_bus_->frames(), | 215 audio_bus_->frames(), |
223 kBitsPerAudioOutputSample / 8); | 216 kBitsPerAudioOutputSample / 8); |
224 | 217 |
225 // Let the other end know which buffer we just filled. The buffer index is | 218 // Let the other end know which buffer we just filled. The buffer index is |
226 // used to ensure the other end is getting the buffer it expects. For more | 219 // used to ensure the other end is getting the buffer it expects. For more |
227 // details on how this works see AudioSyncReader::WaitUntilDataIsReady(). | 220 // details on how this works see AudioSyncReader::WaitUntilDataIsReady(). |
228 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_)); | 221 size_t bytes_sent = socket_->Send(&buffer_index_, sizeof(buffer_index_)); |
229 if (bytes_sent != sizeof(buffer_index_)) | 222 if (bytes_sent != sizeof(buffer_index_)) |
230 break; | 223 break; |
231 } | 224 } |
232 } | 225 } |
233 | 226 |
234 } // namespace ppapi | 227 } // namespace ppapi |
OLD | NEW |