Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/renderer/media/audio_input_device.h" | 5 #include "content/renderer/media/audio_input_device.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "content/common/child_process.h" | 10 #include "content/common/child_process.h" |
| 11 #include "content/common/media/audio_messages.h" | 11 #include "content/common/media/audio_messages.h" |
| 12 #include "content/common/view_messages.h" | 12 #include "content/common/view_messages.h" |
| 13 #include "content/renderer/render_thread_impl.h" | 13 #include "content/renderer/render_thread_impl.h" |
| 14 #include "media/audio/audio_manager_base.h" | 14 #include "media/audio/audio_manager_base.h" |
| 15 #include "media/audio/audio_util.h" | 15 #include "media/audio/audio_util.h" |
| 16 | 16 |
| 17 AudioInputDevice::AudioInputDevice(size_t buffer_size, | 17 AudioInputDevice::AudioInputDevice(size_t buffer_size, |
| 18 int channels, | 18 int channels, |
| 19 double sample_rate, | 19 double sample_rate, |
| 20 CaptureCallback* callback, | 20 CaptureCallback* callback, |
| 21 CaptureEventHandler* event_handler) | 21 CaptureEventHandler* event_handler) |
| 22 : callback_(callback), | 22 : callback_(callback), |
| 23 event_handler_(event_handler), | 23 event_handler_(event_handler), |
| 24 audio_delay_milliseconds_(0), | 24 audio_delay_milliseconds_(0), |
| 25 volume_(1.0), | 25 volume_(1.0), |
| 26 stream_id_(0), | 26 stream_id_(0), |
| 27 session_id_(0), | 27 session_id_(0), |
| 28 pending_device_ready_(false) { | 28 pending_device_ready_(false), |
| 29 audio_event_(true, false) { | |
| 29 filter_ = RenderThreadImpl::current()->audio_input_message_filter(); | 30 filter_ = RenderThreadImpl::current()->audio_input_message_filter(); |
| 30 audio_data_.reserve(channels); | 31 audio_data_.reserve(channels); |
| 31 #if defined(OS_MACOSX) | 32 #if defined(OS_MACOSX) |
| 32 VLOG(1) << "Using AUDIO_PCM_LOW_LATENCY as input mode on Mac OS X."; | 33 VLOG(1) << "Using AUDIO_PCM_LOW_LATENCY as input mode on Mac OS X."; |
| 33 audio_parameters_.format = AudioParameters::AUDIO_PCM_LOW_LATENCY; | 34 audio_parameters_.format = AudioParameters::AUDIO_PCM_LOW_LATENCY; |
| 34 #elif defined(OS_WIN) | 35 #elif defined(OS_WIN) |
| 35 VLOG(1) << "Using AUDIO_PCM_LOW_LATENCY as input mode on Windows."; | 36 VLOG(1) << "Using AUDIO_PCM_LOW_LATENCY as input mode on Windows."; |
| 36 audio_parameters_.format = AudioParameters::AUDIO_PCM_LOW_LATENCY; | 37 audio_parameters_.format = AudioParameters::AUDIO_PCM_LOW_LATENCY; |
| 37 #else | 38 #else |
| 38 // TODO(henrika): add support for AUDIO_PCM_LOW_LATENCY on Linux as well. | 39 // TODO(henrika): add support for AUDIO_PCM_LOW_LATENCY on Linux as well. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 ChildProcess::current()->io_message_loop()->PostTask( | 84 ChildProcess::current()->io_message_loop()->PostTask( |
| 84 FROM_HERE, | 85 FROM_HERE, |
| 85 base::Bind(&AudioInputDevice::ShutDownOnIOThread, this, | 86 base::Bind(&AudioInputDevice::ShutDownOnIOThread, this, |
| 86 &completion)); | 87 &completion)); |
| 87 | 88 |
| 88 // We wait here for the IO task to be completed to remove race conflicts | 89 // We wait here for the IO task to be completed to remove race conflicts |
| 89 // with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous | 90 // with OnLowLatencyCreated() and to ensure that Stop() acts as a synchronous |
| 90 // function call. | 91 // function call. |
| 91 if (completion.TimedWait(kMaxTimeOut)) { | 92 if (completion.TimedWait(kMaxTimeOut)) { |
| 92 if (audio_thread_.get()) { | 93 if (audio_thread_.get()) { |
| 93 // Terminate the main thread function in the audio thread. | 94 // Signal the |audio_event_| to terminate the main thread function. |
| 94 socket_->Close(); | 95 audio_event_.Signal(); |
| 95 // Wait for the audio thread to exit. | 96 // Wait for the audio thread to exit. |
| 96 audio_thread_->Join(); | 97 audio_thread_->Join(); |
| 97 // Ensures that we can call Stop() multiple times. | 98 // Ensures that we can call Stop() multiple times. |
| 98 audio_thread_.reset(NULL); | 99 audio_thread_.reset(NULL); |
| 99 } | 100 } |
| 100 } else { | 101 } else { |
| 101 LOG(ERROR) << "Failed to shut down audio input on IO thread"; | 102 LOG(ERROR) << "Failed to shut down audio input on IO thread"; |
|
Ami GONE FROM CHROMIUM
2011/11/29 20:38:16
This is incorrect code - quoting WaitableEvent::Ti
| |
| 102 return false; | 103 return false; |
| 103 } | 104 } |
| 104 | 105 |
| 105 return true; | 106 return true; |
| 106 } | 107 } |
| 107 | 108 |
| 108 bool AudioInputDevice::SetVolume(double volume) { | 109 bool AudioInputDevice::SetVolume(double volume) { |
| 109 NOTIMPLEMENTED(); | 110 NOTIMPLEMENTED(); |
| 110 return false; | 111 return false; |
| 111 } | 112 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 // Close the socket handler. | 193 // Close the socket handler. |
| 193 base::SyncSocket socket(socket_handle); | 194 base::SyncSocket socket(socket_handle); |
| 194 return; | 195 return; |
| 195 } | 196 } |
| 196 | 197 |
| 197 shared_memory_.reset(new base::SharedMemory(handle, false)); | 198 shared_memory_.reset(new base::SharedMemory(handle, false)); |
| 198 shared_memory_->Map(length); | 199 shared_memory_->Map(length); |
| 199 | 200 |
| 200 socket_.reset(new base::SyncSocket(socket_handle)); | 201 socket_.reset(new base::SyncSocket(socket_handle)); |
| 201 | 202 |
| 203 audio_event_.Reset(); | |
| 202 audio_thread_.reset( | 204 audio_thread_.reset( |
| 203 new base::DelegateSimpleThread(this, "RendererAudioInputThread")); | 205 new base::DelegateSimpleThread(this, "RendererAudioInputThread")); |
| 204 audio_thread_->Start(); | 206 audio_thread_->Start(); |
| 205 | 207 |
| 206 MessageLoop::current()->PostTask( | 208 MessageLoop::current()->PostTask( |
| 207 FROM_HERE, | 209 FROM_HERE, |
| 208 base::Bind(&AudioInputDevice::StartOnIOThread, this)); | 210 base::Bind(&AudioInputDevice::StartOnIOThread, this)); |
| 209 } | 211 } |
| 210 | 212 |
| 211 void AudioInputDevice::OnVolume(double volume) { | 213 void AudioInputDevice::OnVolume(double volume) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 // this thread. | 282 // this thread. |
| 281 void AudioInputDevice::Run() { | 283 void AudioInputDevice::Run() { |
| 282 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); | 284 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); |
| 283 | 285 |
| 284 int pending_data; | 286 int pending_data; |
| 285 const int samples_per_ms = | 287 const int samples_per_ms = |
| 286 static_cast<int>(audio_parameters_.sample_rate) / 1000; | 288 static_cast<int>(audio_parameters_.sample_rate) / 1000; |
| 287 const int bytes_per_ms = audio_parameters_.channels * | 289 const int bytes_per_ms = audio_parameters_.channels * |
| 288 (audio_parameters_.bits_per_sample / 8) * samples_per_ms; | 290 (audio_parameters_.bits_per_sample / 8) * samples_per_ms; |
| 289 | 291 |
| 290 while (sizeof(pending_data) == socket_->Receive(&pending_data, | 292 while (!audio_event_.IsSignaled() && |
|
Ami GONE FROM CHROMIUM
2011/11/29 17:48:32
I'm not super-familiar with the audio codebase, bu
tommi (sloooow) - chröme
2011/11/29 20:11:32
Hey Ami,
A couple of questions inline:
On 2011/1
Ami GONE FROM CHROMIUM
2011/11/29 20:38:16
The problem is with the other case; IsSignaled() m
no longer working on chromium
2011/11/30 17:02:55
Event is thread safe. In the case you mentioned ab
| |
| 293 sizeof(pending_data) == socket_->Receive(&pending_data, | |
| 291 sizeof(pending_data)) && | 294 sizeof(pending_data)) && |
| 292 pending_data >= 0) { | 295 pending_data >= 0) { |
| 293 // TODO(henrika): investigate the provided |pending_data| value | 296 // TODO(henrika): investigate the provided |pending_data| value |
| 294 // and ensure that it is actually an accurate delay estimation. | 297 // and ensure that it is actually an accurate delay estimation. |
| 295 | 298 |
| 296 // Convert the number of pending bytes in the capture buffer | 299 // Convert the number of pending bytes in the capture buffer |
| 297 // into milliseconds. | 300 // into milliseconds. |
| 298 audio_delay_milliseconds_ = pending_data / bytes_per_ms; | 301 audio_delay_milliseconds_ = pending_data / bytes_per_ms; |
| 299 | 302 |
| 300 FireCaptureCallback(); | 303 FireCaptureCallback(); |
| 301 } | 304 } |
| 305 | |
| 306 // Close the socket. | |
| 307 socket_->Close(); | |
| 302 } | 308 } |
| 303 | 309 |
| 304 void AudioInputDevice::FireCaptureCallback() { | 310 void AudioInputDevice::FireCaptureCallback() { |
| 305 if (!callback_) | 311 if (!callback_) |
| 306 return; | 312 return; |
| 307 | 313 |
| 308 const size_t number_of_frames = audio_parameters_.samples_per_packet; | 314 const size_t number_of_frames = audio_parameters_.samples_per_packet; |
| 309 | 315 |
| 310 // Read 16-bit samples from shared memory (browser writes to it). | 316 // Read 16-bit samples from shared memory (browser writes to it). |
| 311 int16* input_audio = static_cast<int16*>(shared_memory_data()); | 317 int16* input_audio = static_cast<int16*>(shared_memory_data()); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 322 bytes_per_sample, | 328 bytes_per_sample, |
| 323 number_of_frames); | 329 number_of_frames); |
| 324 } | 330 } |
| 325 | 331 |
| 326 // Deliver captured data to the client in floating point format | 332 // Deliver captured data to the client in floating point format |
| 327 // and update the audio-delay measurement. | 333 // and update the audio-delay measurement. |
| 328 callback_->Capture(audio_data_, | 334 callback_->Capture(audio_data_, |
| 329 number_of_frames, | 335 number_of_frames, |
| 330 audio_delay_milliseconds_); | 336 audio_delay_milliseconds_); |
| 331 } | 337 } |
| OLD | NEW |