| 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 "media/audio/audio_input_controller.h" | 5 #include "media/audio/audio_input_controller.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/threading/thread_restrictions.h" | 8 #include "base/threading/thread_restrictions.h" |
| 9 #include "media/base/limits.h" | 9 #include "media/base/limits.h" |
| 10 #include "media/base/scoped_histogram_timer.h" | 10 #include "media/base/scoped_histogram_timer.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 } | 26 } |
| 27 | 27 |
| 28 namespace media { | 28 namespace media { |
| 29 | 29 |
| 30 // static | 30 // static |
| 31 AudioInputController::Factory* AudioInputController::factory_ = NULL; | 31 AudioInputController::Factory* AudioInputController::factory_ = NULL; |
| 32 | 32 |
| 33 AudioInputController::AudioInputController(EventHandler* handler, | 33 AudioInputController::AudioInputController(EventHandler* handler, |
| 34 SyncWriter* sync_writer, | 34 SyncWriter* sync_writer, |
| 35 UserInputMonitor* user_input_monitor) | 35 UserInputMonitor* user_input_monitor) |
| 36 : creator_loop_(base::MessageLoopProxy::current()), | 36 : creator_task_runner_(base::MessageLoopProxy::current()), |
| 37 handler_(handler), | 37 handler_(handler), |
| 38 stream_(NULL), | 38 stream_(NULL), |
| 39 data_is_active_(false), | 39 data_is_active_(false), |
| 40 state_(kEmpty), | 40 state_(kEmpty), |
| 41 sync_writer_(sync_writer), | 41 sync_writer_(sync_writer), |
| 42 max_volume_(0.0), | 42 max_volume_(0.0), |
| 43 user_input_monitor_(user_input_monitor), | 43 user_input_monitor_(user_input_monitor), |
| 44 prev_key_down_count_(0) { | 44 prev_key_down_count_(0) { |
| 45 DCHECK(creator_loop_.get()); | 45 DCHECK(creator_task_runner_.get()); |
| 46 } | 46 } |
| 47 | 47 |
| 48 AudioInputController::~AudioInputController() { | 48 AudioInputController::~AudioInputController() { |
| 49 DCHECK(kClosed == state_ || kCreated == state_ || kEmpty == state_); | 49 DCHECK(kClosed == state_ || kCreated == state_ || kEmpty == state_); |
| 50 } | 50 } |
| 51 | 51 |
| 52 // static | 52 // static |
| 53 scoped_refptr<AudioInputController> AudioInputController::Create( | 53 scoped_refptr<AudioInputController> AudioInputController::Create( |
| 54 AudioManager* audio_manager, | 54 AudioManager* audio_manager, |
| 55 EventHandler* event_handler, | 55 EventHandler* event_handler, |
| 56 const AudioParameters& params, | 56 const AudioParameters& params, |
| 57 const std::string& device_id, | 57 const std::string& device_id, |
| 58 UserInputMonitor* user_input_monitor) { | 58 UserInputMonitor* user_input_monitor) { |
| 59 DCHECK(audio_manager); | 59 DCHECK(audio_manager); |
| 60 | 60 |
| 61 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) | 61 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) |
| 62 return NULL; | 62 return NULL; |
| 63 | 63 |
| 64 if (factory_) { | 64 if (factory_) { |
| 65 return factory_->Create( | 65 return factory_->Create( |
| 66 audio_manager, event_handler, params, user_input_monitor); | 66 audio_manager, event_handler, params, user_input_monitor); |
| 67 } | 67 } |
| 68 scoped_refptr<AudioInputController> controller( | 68 scoped_refptr<AudioInputController> controller( |
| 69 new AudioInputController(event_handler, NULL, user_input_monitor)); | 69 new AudioInputController(event_handler, NULL, user_input_monitor)); |
| 70 | 70 |
| 71 controller->message_loop_ = audio_manager->GetMessageLoop(); | 71 controller->task_runner_ = audio_manager->GetTaskRunner(); |
| 72 | 72 |
| 73 // Create and open a new audio input stream from the existing | 73 // Create and open a new audio input stream from the existing |
| 74 // audio-device thread. | 74 // audio-device thread. |
| 75 if (!controller->message_loop_->PostTask(FROM_HERE, | 75 if (!controller->task_runner_->PostTask(FROM_HERE, |
| 76 base::Bind(&AudioInputController::DoCreate, controller, | 76 base::Bind(&AudioInputController::DoCreate, controller, |
| 77 base::Unretained(audio_manager), params, device_id))) { | 77 base::Unretained(audio_manager), params, device_id))) { |
| 78 controller = NULL; | 78 controller = NULL; |
| 79 } | 79 } |
| 80 | 80 |
| 81 return controller; | 81 return controller; |
| 82 } | 82 } |
| 83 | 83 |
| 84 // static | 84 // static |
| 85 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( | 85 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( |
| 86 AudioManager* audio_manager, | 86 AudioManager* audio_manager, |
| 87 EventHandler* event_handler, | 87 EventHandler* event_handler, |
| 88 const AudioParameters& params, | 88 const AudioParameters& params, |
| 89 const std::string& device_id, | 89 const std::string& device_id, |
| 90 SyncWriter* sync_writer, | 90 SyncWriter* sync_writer, |
| 91 UserInputMonitor* user_input_monitor) { | 91 UserInputMonitor* user_input_monitor) { |
| 92 DCHECK(audio_manager); | 92 DCHECK(audio_manager); |
| 93 DCHECK(sync_writer); | 93 DCHECK(sync_writer); |
| 94 | 94 |
| 95 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) | 95 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) |
| 96 return NULL; | 96 return NULL; |
| 97 | 97 |
| 98 // Create the AudioInputController object and ensure that it runs on | 98 // Create the AudioInputController object and ensure that it runs on |
| 99 // the audio-manager thread. | 99 // the audio-manager thread. |
| 100 scoped_refptr<AudioInputController> controller( | 100 scoped_refptr<AudioInputController> controller( |
| 101 new AudioInputController(event_handler, sync_writer, user_input_monitor)); | 101 new AudioInputController(event_handler, sync_writer, user_input_monitor)); |
| 102 controller->message_loop_ = audio_manager->GetMessageLoop(); | 102 controller->task_runner_ = audio_manager->GetTaskRunner(); |
| 103 | 103 |
| 104 // Create and open a new audio input stream from the existing | 104 // Create and open a new audio input stream from the existing |
| 105 // audio-device thread. Use the provided audio-input device. | 105 // audio-device thread. Use the provided audio-input device. |
| 106 if (!controller->message_loop_->PostTask(FROM_HERE, | 106 if (!controller->task_runner_->PostTask(FROM_HERE, |
| 107 base::Bind(&AudioInputController::DoCreate, controller, | 107 base::Bind(&AudioInputController::DoCreate, controller, |
| 108 base::Unretained(audio_manager), params, device_id))) { | 108 base::Unretained(audio_manager), params, device_id))) { |
| 109 controller = NULL; | 109 controller = NULL; |
| 110 } | 110 } |
| 111 | 111 |
| 112 return controller; | 112 return controller; |
| 113 } | 113 } |
| 114 | 114 |
| 115 // static | 115 // static |
| 116 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( | 116 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( |
| 117 const scoped_refptr<base::MessageLoopProxy>& message_loop, | 117 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 118 EventHandler* event_handler, | 118 EventHandler* event_handler, |
| 119 AudioInputStream* stream, | 119 AudioInputStream* stream, |
| 120 SyncWriter* sync_writer, | 120 SyncWriter* sync_writer, |
| 121 UserInputMonitor* user_input_monitor) { | 121 UserInputMonitor* user_input_monitor) { |
| 122 DCHECK(sync_writer); | 122 DCHECK(sync_writer); |
| 123 DCHECK(stream); | 123 DCHECK(stream); |
| 124 | 124 |
| 125 // Create the AudioInputController object and ensure that it runs on | 125 // Create the AudioInputController object and ensure that it runs on |
| 126 // the audio-manager thread. | 126 // the audio-manager thread. |
| 127 scoped_refptr<AudioInputController> controller( | 127 scoped_refptr<AudioInputController> controller( |
| 128 new AudioInputController(event_handler, sync_writer, user_input_monitor)); | 128 new AudioInputController(event_handler, sync_writer, user_input_monitor)); |
| 129 controller->message_loop_ = message_loop; | 129 controller->task_runner_ = task_runner; |
| 130 | 130 |
| 131 // TODO(miu): See TODO at top of file. Until that's resolved, we need to | 131 // TODO(miu): See TODO at top of file. Until that's resolved, we need to |
| 132 // disable the error auto-detection here (since the audio mirroring | 132 // disable the error auto-detection here (since the audio mirroring |
| 133 // implementation will reliably report error and close events). Note, of | 133 // implementation will reliably report error and close events). Note, of |
| 134 // course, that we're assuming CreateForStream() has been called for the audio | 134 // course, that we're assuming CreateForStream() has been called for the audio |
| 135 // mirroring use case only. | 135 // mirroring use case only. |
| 136 if (!controller->message_loop_->PostTask( | 136 if (!controller->task_runner_->PostTask( |
| 137 FROM_HERE, | 137 FROM_HERE, |
| 138 base::Bind(&AudioInputController::DoCreateForStream, controller, | 138 base::Bind(&AudioInputController::DoCreateForStream, controller, |
| 139 stream, false))) { | 139 stream, false))) { |
| 140 controller = NULL; | 140 controller = NULL; |
| 141 } | 141 } |
| 142 | 142 |
| 143 return controller; | 143 return controller; |
| 144 } | 144 } |
| 145 | 145 |
| 146 void AudioInputController::Record() { | 146 void AudioInputController::Record() { |
| 147 message_loop_->PostTask(FROM_HERE, base::Bind( | 147 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 148 &AudioInputController::DoRecord, this)); | 148 &AudioInputController::DoRecord, this)); |
| 149 } | 149 } |
| 150 | 150 |
| 151 void AudioInputController::Close(const base::Closure& closed_task) { | 151 void AudioInputController::Close(const base::Closure& closed_task) { |
| 152 DCHECK(!closed_task.is_null()); | 152 DCHECK(!closed_task.is_null()); |
| 153 DCHECK(creator_loop_->BelongsToCurrentThread()); | 153 DCHECK(creator_task_runner_->BelongsToCurrentThread()); |
| 154 | 154 |
| 155 message_loop_->PostTaskAndReply( | 155 task_runner_->PostTaskAndReply( |
| 156 FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task); | 156 FROM_HERE, base::Bind(&AudioInputController::DoClose, this), closed_task); |
| 157 } | 157 } |
| 158 | 158 |
| 159 void AudioInputController::SetVolume(double volume) { | 159 void AudioInputController::SetVolume(double volume) { |
| 160 message_loop_->PostTask(FROM_HERE, base::Bind( | 160 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 161 &AudioInputController::DoSetVolume, this, volume)); | 161 &AudioInputController::DoSetVolume, this, volume)); |
| 162 } | 162 } |
| 163 | 163 |
| 164 void AudioInputController::SetAutomaticGainControl(bool enabled) { | 164 void AudioInputController::SetAutomaticGainControl(bool enabled) { |
| 165 message_loop_->PostTask(FROM_HERE, base::Bind( | 165 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 166 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); | 166 &AudioInputController::DoSetAutomaticGainControl, this, enabled)); |
| 167 } | 167 } |
| 168 | 168 |
| 169 void AudioInputController::DoCreate(AudioManager* audio_manager, | 169 void AudioInputController::DoCreate(AudioManager* audio_manager, |
| 170 const AudioParameters& params, | 170 const AudioParameters& params, |
| 171 const std::string& device_id) { | 171 const std::string& device_id) { |
| 172 DCHECK(message_loop_->BelongsToCurrentThread()); | 172 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 173 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); | 173 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CreateTime"); |
| 174 // TODO(miu): See TODO at top of file. Until that's resolved, assume all | 174 // TODO(miu): See TODO at top of file. Until that's resolved, assume all |
| 175 // platform audio input requires the |no_data_timer_| be used to auto-detect | 175 // platform audio input requires the |no_data_timer_| be used to auto-detect |
| 176 // errors. In reality, probably only Windows needs to be treated as | 176 // errors. In reality, probably only Windows needs to be treated as |
| 177 // unreliable here. | 177 // unreliable here. |
| 178 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id), | 178 DoCreateForStream(audio_manager->MakeAudioInputStream(params, device_id), |
| 179 true); | 179 true); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void AudioInputController::DoCreateForStream( | 182 void AudioInputController::DoCreateForStream( |
| 183 AudioInputStream* stream_to_control, bool enable_nodata_timer) { | 183 AudioInputStream* stream_to_control, bool enable_nodata_timer) { |
| 184 DCHECK(message_loop_->BelongsToCurrentThread()); | 184 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 185 | 185 |
| 186 DCHECK(!stream_); | 186 DCHECK(!stream_); |
| 187 stream_ = stream_to_control; | 187 stream_ = stream_to_control; |
| 188 | 188 |
| 189 if (!stream_) { | 189 if (!stream_) { |
| 190 handler_->OnError(this); | 190 handler_->OnError(this); |
| 191 return; | 191 return; |
| 192 } | 192 } |
| 193 | 193 |
| 194 if (stream_ && !stream_->Open()) { | 194 if (stream_ && !stream_->Open()) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 214 state_ = kCreated; | 214 state_ = kCreated; |
| 215 handler_->OnCreated(this); | 215 handler_->OnCreated(this); |
| 216 | 216 |
| 217 if (user_input_monitor_) { | 217 if (user_input_monitor_) { |
| 218 user_input_monitor_->EnableKeyPressMonitoring(); | 218 user_input_monitor_->EnableKeyPressMonitoring(); |
| 219 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); | 219 prev_key_down_count_ = user_input_monitor_->GetKeyPressCount(); |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 | 222 |
| 223 void AudioInputController::DoRecord() { | 223 void AudioInputController::DoRecord() { |
| 224 DCHECK(message_loop_->BelongsToCurrentThread()); | 224 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 225 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); | 225 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.RecordTime"); |
| 226 | 226 |
| 227 if (state_ != kCreated) | 227 if (state_ != kCreated) |
| 228 return; | 228 return; |
| 229 | 229 |
| 230 { | 230 { |
| 231 base::AutoLock auto_lock(lock_); | 231 base::AutoLock auto_lock(lock_); |
| 232 state_ = kRecording; | 232 state_ = kRecording; |
| 233 } | 233 } |
| 234 | 234 |
| 235 if (no_data_timer_) { | 235 if (no_data_timer_) { |
| 236 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, | 236 // Start the data timer. Once |kTimerResetIntervalSeconds| have passed, |
| 237 // a callback to DoCheckForNoData() is made. | 237 // a callback to DoCheckForNoData() is made. |
| 238 no_data_timer_->Reset(); | 238 no_data_timer_->Reset(); |
| 239 } | 239 } |
| 240 | 240 |
| 241 stream_->Start(this); | 241 stream_->Start(this); |
| 242 handler_->OnRecording(this); | 242 handler_->OnRecording(this); |
| 243 } | 243 } |
| 244 | 244 |
| 245 void AudioInputController::DoClose() { | 245 void AudioInputController::DoClose() { |
| 246 DCHECK(message_loop_->BelongsToCurrentThread()); | 246 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 247 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); | 247 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioInputController.CloseTime"); |
| 248 | 248 |
| 249 // Delete the timer on the same thread that created it. | 249 // Delete the timer on the same thread that created it. |
| 250 no_data_timer_.reset(); | 250 no_data_timer_.reset(); |
| 251 | 251 |
| 252 if (state_ != kClosed) { | 252 if (state_ != kClosed) { |
| 253 DoStopCloseAndClearStream(NULL); | 253 DoStopCloseAndClearStream(NULL); |
| 254 SetDataIsActive(false); | 254 SetDataIsActive(false); |
| 255 | 255 |
| 256 if (LowLatencyMode()) { | 256 if (LowLatencyMode()) { |
| 257 sync_writer_->Close(); | 257 sync_writer_->Close(); |
| 258 } | 258 } |
| 259 | 259 |
| 260 state_ = kClosed; | 260 state_ = kClosed; |
| 261 | 261 |
| 262 if (user_input_monitor_) | 262 if (user_input_monitor_) |
| 263 user_input_monitor_->DisableKeyPressMonitoring(); | 263 user_input_monitor_->DisableKeyPressMonitoring(); |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| 267 void AudioInputController::DoReportError() { | 267 void AudioInputController::DoReportError() { |
| 268 DCHECK(message_loop_->BelongsToCurrentThread()); | 268 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 269 handler_->OnError(this); | 269 handler_->OnError(this); |
| 270 } | 270 } |
| 271 | 271 |
| 272 void AudioInputController::DoSetVolume(double volume) { | 272 void AudioInputController::DoSetVolume(double volume) { |
| 273 DCHECK(message_loop_->BelongsToCurrentThread()); | 273 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 274 DCHECK_GE(volume, 0); | 274 DCHECK_GE(volume, 0); |
| 275 DCHECK_LE(volume, 1.0); | 275 DCHECK_LE(volume, 1.0); |
| 276 | 276 |
| 277 if (state_ != kCreated && state_ != kRecording) | 277 if (state_ != kCreated && state_ != kRecording) |
| 278 return; | 278 return; |
| 279 | 279 |
| 280 // Only ask for the maximum volume at first call and use cached value | 280 // Only ask for the maximum volume at first call and use cached value |
| 281 // for remaining function calls. | 281 // for remaining function calls. |
| 282 if (!max_volume_) { | 282 if (!max_volume_) { |
| 283 max_volume_ = stream_->GetMaxVolume(); | 283 max_volume_ = stream_->GetMaxVolume(); |
| 284 } | 284 } |
| 285 | 285 |
| 286 if (max_volume_ == 0.0) { | 286 if (max_volume_ == 0.0) { |
| 287 DLOG(WARNING) << "Failed to access input volume control"; | 287 DLOG(WARNING) << "Failed to access input volume control"; |
| 288 return; | 288 return; |
| 289 } | 289 } |
| 290 | 290 |
| 291 // Set the stream volume and scale to a range matched to the platform. | 291 // Set the stream volume and scale to a range matched to the platform. |
| 292 stream_->SetVolume(max_volume_ * volume); | 292 stream_->SetVolume(max_volume_ * volume); |
| 293 } | 293 } |
| 294 | 294 |
| 295 void AudioInputController::DoSetAutomaticGainControl(bool enabled) { | 295 void AudioInputController::DoSetAutomaticGainControl(bool enabled) { |
| 296 DCHECK(message_loop_->BelongsToCurrentThread()); | 296 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 297 DCHECK_NE(state_, kRecording); | 297 DCHECK_NE(state_, kRecording); |
| 298 | 298 |
| 299 // Ensure that the AGC state only can be modified before streaming starts. | 299 // Ensure that the AGC state only can be modified before streaming starts. |
| 300 if (state_ != kCreated || state_ == kRecording) | 300 if (state_ != kCreated || state_ == kRecording) |
| 301 return; | 301 return; |
| 302 | 302 |
| 303 stream_->SetAutomaticGainControl(enabled); | 303 stream_->SetAutomaticGainControl(enabled); |
| 304 } | 304 } |
| 305 | 305 |
| 306 void AudioInputController::DoCheckForNoData() { | 306 void AudioInputController::DoCheckForNoData() { |
| 307 DCHECK(message_loop_->BelongsToCurrentThread()); | 307 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 308 | 308 |
| 309 if (!GetDataIsActive()) { | 309 if (!GetDataIsActive()) { |
| 310 // The data-is-active marker will be false only if it has been more than | 310 // The data-is-active marker will be false only if it has been more than |
| 311 // one second since a data packet was recorded. This can happen if a | 311 // one second since a data packet was recorded. This can happen if a |
| 312 // capture device has been removed or disabled. | 312 // capture device has been removed or disabled. |
| 313 handler_->OnError(this); | 313 handler_->OnError(this); |
| 314 return; | 314 return; |
| 315 } | 315 } |
| 316 | 316 |
| 317 // Mark data as non-active. The flag will be re-enabled in OnData() each | 317 // Mark data as non-active. The flag will be re-enabled in OnData() each |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 | 362 |
| 363 void AudioInputController::OnClose(AudioInputStream* stream) { | 363 void AudioInputController::OnClose(AudioInputStream* stream) { |
| 364 DVLOG(1) << "AudioInputController::OnClose()"; | 364 DVLOG(1) << "AudioInputController::OnClose()"; |
| 365 // TODO(satish): Sometimes the device driver closes the input stream without | 365 // TODO(satish): Sometimes the device driver closes the input stream without |
| 366 // us asking for it (may be if the device was unplugged?). Check how to handle | 366 // us asking for it (may be if the device was unplugged?). Check how to handle |
| 367 // such cases here. | 367 // such cases here. |
| 368 } | 368 } |
| 369 | 369 |
| 370 void AudioInputController::OnError(AudioInputStream* stream) { | 370 void AudioInputController::OnError(AudioInputStream* stream) { |
| 371 // Handle error on the audio-manager thread. | 371 // Handle error on the audio-manager thread. |
| 372 message_loop_->PostTask(FROM_HERE, base::Bind( | 372 task_runner_->PostTask(FROM_HERE, base::Bind( |
| 373 &AudioInputController::DoReportError, this)); | 373 &AudioInputController::DoReportError, this)); |
| 374 } | 374 } |
| 375 | 375 |
| 376 void AudioInputController::DoStopCloseAndClearStream( | 376 void AudioInputController::DoStopCloseAndClearStream( |
| 377 base::WaitableEvent* done) { | 377 base::WaitableEvent* done) { |
| 378 DCHECK(message_loop_->BelongsToCurrentThread()); | 378 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 379 | 379 |
| 380 // Allow calling unconditionally and bail if we don't have a stream to close. | 380 // Allow calling unconditionally and bail if we don't have a stream to close. |
| 381 if (stream_ != NULL) { | 381 if (stream_ != NULL) { |
| 382 stream_->Stop(); | 382 stream_->Stop(); |
| 383 stream_->Close(); | 383 stream_->Close(); |
| 384 stream_ = NULL; | 384 stream_ = NULL; |
| 385 } | 385 } |
| 386 | 386 |
| 387 // Should be last in the method, do not touch "this" from here on. | 387 // Should be last in the method, do not touch "this" from here on. |
| 388 if (done != NULL) | 388 if (done != NULL) |
| 389 done->Signal(); | 389 done->Signal(); |
| 390 } | 390 } |
| 391 | 391 |
| 392 void AudioInputController::SetDataIsActive(bool enabled) { | 392 void AudioInputController::SetDataIsActive(bool enabled) { |
| 393 base::subtle::Release_Store(&data_is_active_, enabled); | 393 base::subtle::Release_Store(&data_is_active_, enabled); |
| 394 } | 394 } |
| 395 | 395 |
| 396 bool AudioInputController::GetDataIsActive() { | 396 bool AudioInputController::GetDataIsActive() { |
| 397 return (base::subtle::Acquire_Load(&data_is_active_) != false); | 397 return (base::subtle::Acquire_Load(&data_is_active_) != false); |
| 398 } | 398 } |
| 399 | 399 |
| 400 } // namespace media | 400 } // namespace media |
| OLD | NEW |