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/proxy/audio_input_resource.h" | 5 #include "ppapi/proxy/audio_input_resource.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "ipc/ipc_platform_file.h" | 9 #include "ipc/ipc_platform_file.h" |
| 10 #include "media/audio/audio_parameters.h" | 10 #include "media/audio/audio_parameters.h" |
| 11 #include "media/base/audio_bus.h" | |
| 11 #include "ppapi/c/pp_errors.h" | 12 #include "ppapi/c/pp_errors.h" |
| 12 #include "ppapi/proxy/ppapi_messages.h" | 13 #include "ppapi/proxy/ppapi_messages.h" |
| 13 #include "ppapi/proxy/resource_message_params.h" | 14 #include "ppapi/proxy/resource_message_params.h" |
| 14 #include "ppapi/proxy/serialized_handle.h" | 15 #include "ppapi/proxy/serialized_handle.h" |
| 15 #include "ppapi/shared_impl/ppapi_globals.h" | 16 #include "ppapi/shared_impl/ppapi_globals.h" |
| 16 #include "ppapi/shared_impl/ppb_audio_config_shared.h" | 17 #include "ppapi/shared_impl/ppb_audio_config_shared.h" |
| 17 #include "ppapi/shared_impl/resource_tracker.h" | 18 #include "ppapi/shared_impl/resource_tracker.h" |
| 18 #include "ppapi/shared_impl/tracked_callback.h" | 19 #include "ppapi/shared_impl/tracked_callback.h" |
| 19 #include "ppapi/thunk/enter.h" | 20 #include "ppapi/thunk/enter.h" |
| 20 #include "ppapi/thunk/ppb_audio_config_api.h" | 21 #include "ppapi/thunk/ppb_audio_config_api.h" |
| 21 | 22 |
| 22 namespace ppapi { | 23 namespace ppapi { |
| 23 namespace proxy { | 24 namespace proxy { |
| 24 | 25 |
| 25 AudioInputResource::AudioInputResource( | 26 AudioInputResource::AudioInputResource( |
| 26 Connection connection, | 27 Connection connection, |
| 27 PP_Instance instance) | 28 PP_Instance instance) |
| 28 : PluginResource(connection, instance), | 29 : PluginResource(connection, instance), |
| 29 open_state_(BEFORE_OPEN), | 30 open_state_(BEFORE_OPEN), |
| 30 capturing_(false), | 31 capturing_(false), |
| 31 shared_memory_size_(0), | 32 shared_memory_size_(0), |
| 32 audio_input_callback_0_3_(NULL), | 33 audio_input_callback_0_3_(NULL), |
| 33 audio_input_callback_(NULL), | 34 audio_input_callback_(NULL), |
| 34 user_data_(NULL), | 35 user_data_(NULL), |
| 35 enumeration_helper_(this), | 36 enumeration_helper_(this), |
| 36 bytes_per_second_(0) { | 37 bytes_per_second_(0), |
| 38 sample_frame_count_(0), | |
| 39 client_buffer_size_bytes_(0) { | |
| 37 SendCreate(RENDERER, PpapiHostMsg_AudioInput_Create()); | 40 SendCreate(RENDERER, PpapiHostMsg_AudioInput_Create()); |
| 38 } | 41 } |
| 39 | 42 |
| 40 AudioInputResource::~AudioInputResource() { | 43 AudioInputResource::~AudioInputResource() { |
| 41 Close(); | 44 Close(); |
| 42 } | 45 } |
| 43 | 46 |
| 44 thunk::PPB_AudioInput_API* AudioInputResource::AsPPB_AudioInput_API() { | 47 thunk::PPB_AudioInput_API* AudioInputResource::AsPPB_AudioInput_API() { |
| 45 return this; | 48 return this; |
| 46 } | 49 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 } | 178 } |
| 176 | 179 |
| 177 void AudioInputResource::SetStreamInfo( | 180 void AudioInputResource::SetStreamInfo( |
| 178 base::SharedMemoryHandle shared_memory_handle, | 181 base::SharedMemoryHandle shared_memory_handle, |
| 179 size_t shared_memory_size, | 182 size_t shared_memory_size, |
| 180 base::SyncSocket::Handle socket_handle) { | 183 base::SyncSocket::Handle socket_handle) { |
| 181 socket_.reset(new base::CancelableSyncSocket(socket_handle)); | 184 socket_.reset(new base::CancelableSyncSocket(socket_handle)); |
| 182 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); | 185 shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); |
| 183 shared_memory_size_ = shared_memory_size; | 186 shared_memory_size_ = shared_memory_size; |
| 184 | 187 |
| 185 if (!shared_memory_->Map(shared_memory_size_)) { | 188 if (!shared_memory_->Map(shared_memory_size_)) { |
|
no longer working on chromium
2014/07/08 15:33:48
The code becomes a bit hard to read with the new c
henrika (OOO until Aug 14)
2014/07/09 09:39:51
Done.
henrika (OOO until Aug 14)
2014/07/09 09:41:01
I followed the example on the output side. I will
| |
| 186 PpapiGlobals::Get()->LogWithSource( | 189 PpapiGlobals::Get()->LogWithSource( |
| 187 pp_instance(), | 190 pp_instance(), |
| 188 PP_LOGLEVEL_WARNING, | 191 PP_LOGLEVEL_WARNING, |
| 189 std::string(), | 192 std::string(), |
| 190 "Failed to map shared memory for PPB_AudioInput_Shared."); | 193 "Failed to map shared memory for PPB_AudioInput_Shared."); |
| 194 } else { | |
| 195 // Create a new audio bus and wrap the audio data section in shared memory. | |
| 196 media::AudioInputBuffer* buffer = | |
| 197 reinterpret_cast<media::AudioInputBuffer*>(shared_memory_->memory()); | |
|
piman
2014/07/08 17:48:35
I see you're sharing metadata (AudioInputBufferPar
piman
2014/07/08 17:48:35
nit: static_cast instead of reinterpret_cast.
tommi (sloooow) - chröme
2014/07/09 09:32:11
Henrik was asking me about this, so I figured I'd
henrika (OOO until Aug 14)
2014/07/09 09:39:51
Nop. I was following a pattern done in a correspon
henrika (OOO until Aug 14)
2014/07/09 09:39:51
Great comment; please allow me to come back and an
henrika (OOO until Aug 14)
2014/07/09 11:35:14
Thanks Tommi; will stick to reinterpret unless pim
piman
2014/07/09 20:36:27
Possibly, but you're exposing it in new ways (and
henrika (OOO until Aug 14)
2014/07/10 09:50:16
We are fine since the trusted process only writes
| |
| 198 audio_bus_ = media::AudioBus::WrapMemory( | |
| 199 kAudioInputChannels, sample_frame_count_, buffer->audio); | |
| 200 | |
| 201 // Create an extra integer audio buffer for user audio data callbacks. | |
| 202 // Data in shared memory will be copied to this buffer, after interleaving | |
| 203 // and truncation, before each input callback to match the format expected | |
| 204 // by the client. | |
| 205 client_buffer_size_bytes_ = audio_bus_->frames() * audio_bus_->channels() * | |
| 206 kBitsPerAudioInputSample / 8; | |
|
piman
2014/07/08 17:48:35
nit: indent (git cl format?)
henrika (OOO until Aug 14)
2014/07/09 09:39:51
I did run git cl format and it does suggest this i
piman
2014/07/09 20:36:27
It looks like a bug in git cl format.... line cont
henrika (OOO until Aug 14)
2014/07/10 09:50:16
Acknowledged.
| |
| 207 client_buffer_.reset(new uint8_t[client_buffer_size_bytes_]); | |
| 191 } | 208 } |
| 192 | 209 |
| 193 // There is a pending capture request before SetStreamInfo(). | 210 // There is a pending capture request before SetStreamInfo(). |
| 194 if (capturing_) { | 211 if (capturing_) { |
| 195 // Set |capturing_| to false so that the state looks consistent to | 212 // Set |capturing_| to false so that the state looks consistent to |
| 196 // StartCapture(), which will reset it to true. | 213 // StartCapture(), which will reset it to true. |
| 197 capturing_ = false; | 214 capturing_ = false; |
| 198 StartCapture(); | 215 StartCapture(); |
| 199 } | 216 } |
| 200 } | 217 } |
| 201 | 218 |
| 202 void AudioInputResource::StartThread() { | 219 void AudioInputResource::StartThread() { |
| 203 // Don't start the thread unless all our state is set up correctly. | 220 // Don't start the thread unless all our state is set up correctly. |
| 204 if ((!audio_input_callback_0_3_ && !audio_input_callback_) || | 221 if ((!audio_input_callback_0_3_ && !audio_input_callback_) || |
| 205 !socket_.get() || !capturing_ || !shared_memory_->memory()) { | 222 !socket_.get() || !capturing_ || !shared_memory_->memory() || |
| 223 !audio_bus_.get() || !client_buffer_.get()) { | |
| 206 return; | 224 return; |
| 207 } | 225 } |
| 208 DCHECK(!audio_input_thread_.get()); | 226 DCHECK(!audio_input_thread_.get()); |
| 209 audio_input_thread_.reset(new base::DelegateSimpleThread( | 227 audio_input_thread_.reset(new base::DelegateSimpleThread( |
| 210 this, "plugin_audio_input_thread")); | 228 this, "plugin_audio_input_thread")); |
| 211 audio_input_thread_->Start(); | 229 audio_input_thread_->Start(); |
| 212 } | 230 } |
| 213 | 231 |
| 214 void AudioInputResource::StopThread() { | 232 void AudioInputResource::StopThread() { |
| 215 // Shut down the socket to escape any hanging |Receive|s. | 233 // Shut down the socket to escape any hanging |Receive|s. |
| 216 if (socket_.get()) | 234 if (socket_.get()) |
| 217 socket_->Shutdown(); | 235 socket_->Shutdown(); |
| 218 if (audio_input_thread_.get()) { | 236 if (audio_input_thread_.get()) { |
| 219 audio_input_thread_->Join(); | 237 audio_input_thread_->Join(); |
| 220 audio_input_thread_.reset(); | 238 audio_input_thread_.reset(); |
| 221 } | 239 } |
| 222 } | 240 } |
| 223 | 241 |
| 224 void AudioInputResource::Run() { | 242 void AudioInputResource::Run() { |
| 225 // The shared memory represents AudioInputBufferParameters and the actual data | 243 // The shared memory represents AudioInputBufferParameters and the actual data |
| 226 // buffer. | 244 // buffer stored as an audio bus. |
| 227 media::AudioInputBuffer* buffer = | 245 media::AudioInputBuffer* buffer = |
| 228 static_cast<media::AudioInputBuffer*>(shared_memory_->memory()); | 246 static_cast<media::AudioInputBuffer*>(shared_memory_->memory()); |
| 229 uint32_t data_buffer_size = | 247 uint32_t data_buffer_size = |
| 230 shared_memory_size_ - sizeof(media::AudioInputBufferParameters); | 248 shared_memory_size_ - sizeof(media::AudioInputBufferParameters); |
| 231 int pending_data; | |
| 232 | 249 |
|
no longer working on chromium
2014/07/08 15:33:48
if you move the audio_wrapper_ setup code here, wi
henrika (OOO until Aug 14)
2014/07/09 09:39:51
Thanks for the suggestion but, as stated before, I
| |
| 233 while (sizeof(pending_data) == socket_->Receive(&pending_data, | 250 while (true) { |
|
no longer working on chromium
2014/07/08 15:33:48
may I ask why you changed the condition? It looks
| |
| 234 sizeof(pending_data)) && | 251 int pending_data = 0; |
| 235 pending_data >= 0) { | 252 size_t bytes_read = socket_->Receive(&pending_data, sizeof(pending_data)); |
| 253 if (bytes_read != sizeof(pending_data)) { | |
| 254 DCHECK_EQ(bytes_read, 0U); | |
| 255 break; | |
| 256 } | |
| 257 if (pending_data < 0) | |
| 258 break; | |
| 259 | |
| 260 // Convert an AudioBus from deinterleaved float to interleaved integer data. | |
| 261 // Store the result in a preallocated |client_buffer_|. | |
| 262 audio_bus_->ToInterleaved(audio_bus_->frames(), | |
| 263 kBitsPerAudioInputSample / 8, | |
| 264 client_buffer_.get()); | |
| 265 | |
| 236 // While closing the stream, we may receive buffers whose size is different | 266 // While closing the stream, we may receive buffers whose size is different |
| 237 // from |data_buffer_size|. | 267 // from |data_buffer_size|. |
| 238 CHECK_LE(buffer->params.size, data_buffer_size); | 268 CHECK_LE(buffer->params.size, data_buffer_size); |
| 239 if (buffer->params.size > 0) { | 269 if (buffer->params.size > 0) { |
| 240 if (audio_input_callback_) { | 270 if (audio_input_callback_) { |
| 241 PP_TimeDelta latency = | 271 PP_TimeDelta latency = |
| 242 static_cast<double>(pending_data) / bytes_per_second_; | 272 static_cast<double>(pending_data) / bytes_per_second_; |
| 243 audio_input_callback_(&buffer->audio[0], buffer->params.size, latency, | 273 audio_input_callback_(client_buffer_.get(), |
| 274 client_buffer_size_bytes_, | |
|
no longer working on chromium
2014/07/08 15:33:48
client_buffer_size_bytes_ should be the same as bu
henrika (OOO until Aug 14)
2014/07/09 09:39:51
Actually that is not the case since params.size re
| |
| 275 latency, | |
| 244 user_data_); | 276 user_data_); |
| 245 } else { | 277 } else { |
| 246 audio_input_callback_0_3_(&buffer->audio[0], buffer->params.size, | 278 audio_input_callback_0_3_( |
| 247 user_data_); | 279 client_buffer_.get(), client_buffer_size_bytes_, user_data_); |
| 248 } | 280 } |
| 249 } | 281 } |
| 250 } | 282 } |
| 251 } | 283 } |
| 252 | 284 |
| 253 int32_t AudioInputResource::CommonOpen( | 285 int32_t AudioInputResource::CommonOpen( |
| 254 PP_Resource device_ref, | 286 PP_Resource device_ref, |
| 255 PP_Resource config, | 287 PP_Resource config, |
| 256 PPB_AudioInput_Callback_0_3 audio_input_callback_0_3, | 288 PPB_AudioInput_Callback_0_3 audio_input_callback_0_3, |
| 257 PPB_AudioInput_Callback audio_input_callback, | 289 PPB_AudioInput_Callback audio_input_callback, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 280 if (enter_config.failed()) | 312 if (enter_config.failed()) |
| 281 return PP_ERROR_BADARGUMENT; | 313 return PP_ERROR_BADARGUMENT; |
| 282 | 314 |
| 283 config_ = config; | 315 config_ = config; |
| 284 audio_input_callback_0_3_ = audio_input_callback_0_3; | 316 audio_input_callback_0_3_ = audio_input_callback_0_3; |
| 285 audio_input_callback_ = audio_input_callback; | 317 audio_input_callback_ = audio_input_callback; |
| 286 user_data_ = user_data; | 318 user_data_ = user_data; |
| 287 open_callback_ = callback; | 319 open_callback_ = callback; |
| 288 bytes_per_second_ = kAudioInputChannels * (kBitsPerAudioInputSample / 8) * | 320 bytes_per_second_ = kAudioInputChannels * (kBitsPerAudioInputSample / 8) * |
| 289 enter_config.object()->GetSampleRate(); | 321 enter_config.object()->GetSampleRate(); |
| 322 sample_frame_count_ = enter_config.object()->GetSampleFrameCount(); | |
| 290 | 323 |
| 291 PpapiHostMsg_AudioInput_Open msg( | 324 PpapiHostMsg_AudioInput_Open msg( |
| 292 device_id, enter_config.object()->GetSampleRate(), | 325 device_id, enter_config.object()->GetSampleRate(), |
| 293 enter_config.object()->GetSampleFrameCount()); | 326 enter_config.object()->GetSampleFrameCount()); |
| 294 Call<PpapiPluginMsg_AudioInput_OpenReply>( | 327 Call<PpapiPluginMsg_AudioInput_OpenReply>( |
| 295 RENDERER, msg, | 328 RENDERER, msg, |
| 296 base::Bind(&AudioInputResource::OnPluginMsgOpenReply, | 329 base::Bind(&AudioInputResource::OnPluginMsgOpenReply, |
| 297 base::Unretained(this))); | 330 base::Unretained(this))); |
| 298 return PP_OK_COMPLETIONPENDING; | 331 return PP_OK_COMPLETIONPENDING; |
| 299 } | 332 } |
| 300 } // namespace proxy | 333 } // namespace proxy |
| 301 } // namespace ppapi | 334 } // namespace ppapi |
| OLD | NEW |