OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "webkit/glue/plugins/pepper_audio.h" | 5 #include "webkit/glue/plugins/pepper_audio.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "ppapi/c/dev/ppb_audio_dev.h" | 8 #include "third_party/ppapi/c/dev/ppb_audio_dev.h" |
9 #include "ppapi/c/dev/ppb_audio_trusted_dev.h" | 9 #include "third_party/ppapi/c/dev/ppb_audio_trusted_dev.h" |
10 #include "webkit/glue/plugins/pepper_common.h" | 10 #include "webkit/glue/plugins/pepper_common.h" |
11 | 11 |
12 namespace pepper { | 12 namespace pepper { |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 // PPB_AudioConfig ------------------------------------------------------------- | 16 // PPB_AudioConfig ------------------------------------------------------------- |
17 | 17 |
18 uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count); | 18 uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count); |
19 | 19 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 &CreateStereo16bit, | 70 &CreateStereo16bit, |
71 &RecommendSampleFrameCount, | 71 &RecommendSampleFrameCount, |
72 &IsAudioConfig, | 72 &IsAudioConfig, |
73 &GetSampleRate, | 73 &GetSampleRate, |
74 &GetSampleFrameCount | 74 &GetSampleFrameCount |
75 }; | 75 }; |
76 | 76 |
77 // PPB_Audio ------------------------------------------------------------------- | 77 // PPB_Audio ------------------------------------------------------------------- |
78 | 78 |
79 PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, | 79 PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, |
80 PPB_Audio_Callback callback, void* user_data) { | 80 PPB_Audio_Callback user_callback, void* user_data) { |
81 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); | 81 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
82 if (!instance) | 82 if (!instance) |
83 return 0; | 83 return 0; |
84 // TODO(neb): Require callback to be present for untrusted plugins. | 84 // TODO(neb): Require callback to be present for untrusted plugins. |
85 scoped_refptr<Audio> audio(new Audio(instance->module())); | 85 scoped_refptr<Audio> audio(new Audio(instance->module())); |
86 if (!audio->Init(instance->delegate(), config_id, callback, user_data)) | 86 if (!audio->Init(instance->delegate(), instance_id, config_id, |
87 user_callback, user_data, NULL)) | |
87 return 0; | 88 return 0; |
88 return audio->GetReference(); | 89 return audio->GetReference(); |
89 } | 90 } |
90 | 91 |
91 PP_Bool IsAudio(PP_Resource resource) { | 92 PP_Bool IsAudio(PP_Resource resource) { |
92 scoped_refptr<Audio> audio = Resource::GetAs<Audio>(resource); | 93 scoped_refptr<Audio> audio = Resource::GetAs<Audio>(resource); |
93 return BoolToPPBool(!!audio); | 94 return BoolToPPBool(!!audio); |
94 } | 95 } |
95 | 96 |
96 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { | 97 PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { |
(...skipping 14 matching lines...) Expand all Loading... | |
111 const PPB_Audio_Dev ppb_audio = { | 112 const PPB_Audio_Dev ppb_audio = { |
112 &Create, | 113 &Create, |
113 &IsAudio, | 114 &IsAudio, |
114 &GetCurrentConfiguration, | 115 &GetCurrentConfiguration, |
115 &StartPlayback, | 116 &StartPlayback, |
116 &StopPlayback, | 117 &StopPlayback, |
117 }; | 118 }; |
118 | 119 |
119 // PPB_AudioTrusted ------------------------------------------------------------ | 120 // PPB_AudioTrusted ------------------------------------------------------------ |
120 | 121 |
121 PP_Resource GetBuffer(PP_Resource audio_id) { | 122 PP_Resource CreateTrusted(PP_Instance instance_id, PP_Resource config_id, |
122 // TODO(neb): Implement me! | 123 PPB_AudioTrusted_Callback created) { |
123 return 0; | 124 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
124 } | 125 if (!instance) |
125 | 126 return 0; |
126 int GetOSDescriptor(PP_Resource audio_id) { | 127 scoped_refptr<Audio> audio(new Audio(instance->module())); |
127 // TODO(neb): Implement me! | 128 if (!audio->Init(instance->delegate(), instance_id, config_id, |
128 return -1; | 129 NULL, NULL, created)) |
darin (slow to review)
2010/11/19 17:45:39
nit: please indent so the start of the arguments a
| |
130 return 0; | |
131 return audio->GetReference(); | |
129 } | 132 } |
130 | 133 |
131 const PPB_AudioTrusted_Dev ppb_audiotrusted = { | 134 const PPB_AudioTrusted_Dev ppb_audiotrusted = { |
132 &GetBuffer, | 135 &CreateTrusted |
133 &GetOSDescriptor | |
134 }; | 136 }; |
135 | 137 |
136 } // namespace | 138 } // namespace |
137 | 139 |
138 // AudioConfig ----------------------------------------------------------------- | 140 // AudioConfig ----------------------------------------------------------------- |
139 | 141 |
140 AudioConfig::AudioConfig(PluginModule* module, | 142 AudioConfig::AudioConfig(PluginModule* module, |
141 PP_AudioSampleRate_Dev sample_rate, | 143 PP_AudioSampleRate_Dev sample_rate, |
142 uint32_t sample_frame_count) | 144 uint32_t sample_frame_count) |
143 : Resource(module), | 145 : Resource(module), |
(...skipping 17 matching lines...) Expand all Loading... | |
161 | 163 |
162 AudioConfig* AudioConfig::AsAudioConfig() { | 164 AudioConfig* AudioConfig::AsAudioConfig() { |
163 return this; | 165 return this; |
164 } | 166 } |
165 | 167 |
166 // Audio ----------------------------------------------------------------------- | 168 // Audio ----------------------------------------------------------------------- |
167 | 169 |
168 Audio::Audio(PluginModule* module) | 170 Audio::Audio(PluginModule* module) |
169 : Resource(module), | 171 : Resource(module), |
170 playing_(false), | 172 playing_(false), |
173 pp_instance_(0), | |
174 audio_(NULL), | |
171 socket_(NULL), | 175 socket_(NULL), |
172 shared_memory_(NULL), | 176 shared_memory_(NULL), |
173 shared_memory_size_(0), | 177 shared_memory_size_(0), |
174 callback_(NULL), | 178 callback_(NULL), |
175 user_data_(NULL) { | 179 user_data_(NULL), |
180 create_callback_(NULL) { | |
176 } | 181 } |
177 | 182 |
178 Audio::~Audio() { | 183 Audio::~Audio() { |
179 // Calling ShutDown() makes sure StreamCreated cannot be called anymore. | 184 // Calling ShutDown() makes sure StreamCreated cannot be called anymore. |
180 audio_->ShutDown(); | 185 audio_->ShutDown(); |
186 audio_ = NULL; | |
181 // Closing the socket causes the thread to exit - wait for it. | 187 // Closing the socket causes the thread to exit - wait for it. |
182 socket_->Close(); | 188 socket_->Close(); |
183 if (audio_thread_.get()) { | 189 if (audio_thread_.get()) { |
184 audio_thread_->Join(); | 190 audio_thread_->Join(); |
185 audio_thread_.reset(); | 191 audio_thread_.reset(); |
186 } | 192 } |
187 // Shared memory destructor will unmap the memory automatically. | 193 // Shared memory destructor will unmap the memory automatically. |
188 } | 194 } |
189 | 195 |
190 const PPB_Audio_Dev* Audio::GetInterface() { | 196 const PPB_Audio_Dev* Audio::GetInterface() { |
191 return &ppb_audio; | 197 return &ppb_audio; |
192 } | 198 } |
193 | 199 |
194 const PPB_AudioTrusted_Dev* Audio::GetTrustedInterface() { | 200 const PPB_AudioTrusted_Dev* Audio::GetTrustedInterface() { |
195 return &ppb_audiotrusted; | 201 return &ppb_audiotrusted; |
196 } | 202 } |
197 | 203 |
198 Audio* Audio::AsAudio() { | 204 Audio* Audio::AsAudio() { |
199 return this; | 205 return this; |
200 } | 206 } |
201 | 207 |
202 bool Audio::Init(PluginDelegate* plugin_delegate, PP_Resource config_id, | 208 bool Audio::Init(PluginDelegate* plugin_delegate, |
203 PPB_Audio_Callback callback, void* user_data) { | 209 PP_Instance instance_id, |
204 CHECK(!audio_.get()); | 210 PP_Resource config_id, |
211 PPB_Audio_Callback callback, void* user_data, | |
212 PPB_AudioTrusted_Callback create_callback) { | |
213 CHECK(!audio_); | |
205 config_ = Resource::GetAs<AudioConfig>(config_id); | 214 config_ = Resource::GetAs<AudioConfig>(config_id); |
206 if (!config_) | 215 if (!config_) |
207 return false; | 216 return false; |
217 pp_instance_ = instance_id; | |
208 callback_ = callback; | 218 callback_ = callback; |
209 user_data_ = user_data; | 219 user_data_ = user_data; |
210 // When the stream is created, we'll get called back in StreamCreated(). | 220 create_callback_ = create_callback; |
211 audio_.reset(plugin_delegate->CreateAudio(config_->sample_rate(), | 221 // When the stream is created, we'll get called back on StreamCreated(). |
212 config_->sample_frame_count(), | 222 audio_ = plugin_delegate->CreateAudio(config_->sample_rate(), |
213 this)); | 223 config_->sample_frame_count(), |
214 return audio_.get() != NULL; | 224 this); |
225 return audio_ != NULL; | |
215 } | 226 } |
216 | 227 |
217 bool Audio::StartPlayback() { | 228 bool Audio::StartPlayback() { |
218 if (playing_) | 229 if (playing_) |
219 return true; | 230 return true; |
220 | 231 |
221 CHECK(!audio_thread_.get()); | 232 CHECK(!audio_thread_.get()); |
222 if (callback_ && socket_.get()) { | 233 if (callback_ && socket_.get()) { |
223 audio_thread_.reset(new base::DelegateSimpleThread(this, | 234 audio_thread_.reset(new base::DelegateSimpleThread(this, |
224 "plugin_audio_thread")); | 235 "plugin_audio_thread")); |
(...skipping 17 matching lines...) Expand all Loading... | |
242 playing_ = false; | 253 playing_ = false; |
243 return true; | 254 return true; |
244 } | 255 } |
245 | 256 |
246 void Audio::StreamCreated(base::SharedMemoryHandle shared_memory_handle, | 257 void Audio::StreamCreated(base::SharedMemoryHandle shared_memory_handle, |
247 size_t shared_memory_size, | 258 size_t shared_memory_size, |
248 base::SyncSocket::Handle socket_handle) { | 259 base::SyncSocket::Handle socket_handle) { |
249 socket_.reset(new base::SyncSocket(socket_handle)); | 260 socket_.reset(new base::SyncSocket(socket_handle)); |
250 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); | 261 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); |
251 shared_memory_size_ = shared_memory_size; | 262 shared_memory_size_ = shared_memory_size; |
252 | 263 // Trusted side of proxy can specify a callback to recieve handles on. |
264 if (create_callback_) { | |
265 #if OS_LINUX || OS_MAC | |
266 int64_t shm_handle = static_cast<int64_t>(shared_memory_handle.fd); | |
267 #elif OS_WIN | |
268 int64_T shm_handle = static_cast<int64_t>(shared_memory_handle); | |
269 #else | |
270 #error "Unknown OS" | |
darin (slow to review)
2010/11/19 17:45:39
nit: indent by 4 spaces like the other branches?
| |
271 #endif | |
272 create_callback_(pp_instance_, GetReference(), shm_handle, | |
273 shared_memory_size, static_cast<int64_t>(socket_handle)); | |
darin (slow to review)
2010/11/19 17:45:39
nit: align the arguments so they all start at the
| |
274 } | |
275 // Recurring callback to fill audio buffers. | |
253 if (callback_) { | 276 if (callback_) { |
254 shared_memory_->Map(shared_memory_size_); | 277 shared_memory_->Map(shared_memory_size_); |
255 // In common case StartPlayback() was called before StreamCreated(). | 278 // In common case StartPlayback() was called before StreamCreated(). |
256 if (playing_) { | 279 if (playing_) { |
257 audio_thread_.reset(new base::DelegateSimpleThread(this, | 280 audio_thread_.reset(new base::DelegateSimpleThread(this, |
258 "plugin_audio_thread")); | 281 "plugin_audio_thread")); |
259 audio_thread_->Start(); | 282 audio_thread_->Start(); |
260 } | 283 } |
261 } | 284 } |
262 } | 285 } |
263 | 286 |
264 void Audio::Run() { | 287 void Audio::Run() { |
265 int pending_data; | 288 int pending_data; |
266 void* buffer = shared_memory_->memory(); | 289 void* buffer = shared_memory_->memory(); |
267 size_t buffer_size_in_bytes = config_->BufferSize(); | 290 size_t buffer_size_in_bytes = config_->BufferSize(); |
268 | 291 |
269 while (sizeof(pending_data) == | 292 while (sizeof(pending_data) == |
270 socket_->Receive(&pending_data, sizeof(pending_data)) && | 293 socket_->Receive(&pending_data, sizeof(pending_data)) && |
271 pending_data >= 0) { | 294 pending_data >= 0) { |
272 // Exit the thread on pause. | 295 // Exit the thread on pause. |
273 if (pending_data < 0) | 296 if (pending_data < 0) |
274 return; | 297 return; |
275 callback_(buffer, buffer_size_in_bytes, user_data_); | 298 callback_(buffer, buffer_size_in_bytes, user_data_); |
276 } | 299 } |
277 } | 300 } |
278 | 301 |
279 } // namespace pepper | 302 } // namespace pepper |
280 | 303 |
OLD | NEW |