Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: content/renderer/media/audio_input_device.cc

Issue 8659040: There is a racing between SyncSocket::Receive in audio_thread_ and SyncSocket::Close in renderer ... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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 }
OLDNEW
« content/renderer/media/audio_device.cc ('K') | « content/renderer/media/audio_input_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698