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

Side by Side Diff: media/audio/audio_input_controller.cc

Issue 2390153006: Audio input debug recording refactoring to reduce thread hops and simplify object ownership (Closed)
Patch Set: Rebase Created 4 years, 2 months 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
« no previous file with comments | « media/audio/audio_input_controller.h ('k') | media/audio/audio_input_writer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 #endif // AUDIO_POWER_MONITORING 79 #endif // AUDIO_POWER_MONITORING
80 80
81 } // namespace 81 } // namespace
82 82
83 namespace media { 83 namespace media {
84 84
85 // static 85 // static
86 AudioInputController::Factory* AudioInputController::factory_ = nullptr; 86 AudioInputController::Factory* AudioInputController::factory_ = nullptr;
87 87
88 AudioInputController::AudioInputController(EventHandler* handler, 88 AudioInputController::AudioInputController(
89 SyncWriter* sync_writer, 89 EventHandler* handler,
90 UserInputMonitor* user_input_monitor, 90 SyncWriter* sync_writer,
91 const bool agc_is_enabled) 91 std::unique_ptr<AudioInputWriter> debug_writer,
92 UserInputMonitor* user_input_monitor,
93 const bool agc_is_enabled)
92 : creator_task_runner_(base::ThreadTaskRunnerHandle::Get()), 94 : creator_task_runner_(base::ThreadTaskRunnerHandle::Get()),
93 handler_(handler), 95 handler_(handler),
94 stream_(nullptr), 96 stream_(nullptr),
95 should_report_stats(0), 97 should_report_stats(0),
96 state_(CLOSED), 98 state_(CLOSED),
97 sync_writer_(sync_writer), 99 sync_writer_(sync_writer),
98 max_volume_(0.0), 100 max_volume_(0.0),
99 user_input_monitor_(user_input_monitor), 101 user_input_monitor_(user_input_monitor),
100 agc_is_enabled_(agc_is_enabled), 102 agc_is_enabled_(agc_is_enabled),
101 #if defined(AUDIO_POWER_MONITORING) 103 #if defined(AUDIO_POWER_MONITORING)
102 power_measurement_is_enabled_(false), 104 power_measurement_is_enabled_(false),
103 log_silence_state_(false), 105 log_silence_state_(false),
104 silence_state_(SILENCE_STATE_NO_MEASUREMENT), 106 silence_state_(SILENCE_STATE_NO_MEASUREMENT),
105 #endif 107 #endif
106 prev_key_down_count_(0), 108 prev_key_down_count_(0),
107 input_writer_(nullptr) { 109 debug_writer_(std::move(debug_writer)) {
108 DCHECK(creator_task_runner_.get()); 110 DCHECK(creator_task_runner_.get());
109 } 111 }
110 112
111 AudioInputController::~AudioInputController() { 113 AudioInputController::~AudioInputController() {
112 DCHECK_EQ(state_, CLOSED); 114 DCHECK_EQ(state_, CLOSED);
113 } 115 }
114 116
115 // static 117 // static
116 scoped_refptr<AudioInputController> AudioInputController::Create( 118 scoped_refptr<AudioInputController> AudioInputController::Create(
117 AudioManager* audio_manager, 119 AudioManager* audio_manager,
118 EventHandler* event_handler, 120 EventHandler* event_handler,
119 const AudioParameters& params, 121 const AudioParameters& params,
120 const std::string& device_id, 122 const std::string& device_id,
121 UserInputMonitor* user_input_monitor) { 123 UserInputMonitor* user_input_monitor) {
122 DCHECK(audio_manager); 124 DCHECK(audio_manager);
123 125
124 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 126 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
125 return nullptr; 127 return nullptr;
126 128
127 if (factory_) { 129 if (factory_) {
128 return factory_->Create( 130 return factory_->Create(
129 audio_manager, event_handler, params, user_input_monitor); 131 audio_manager, event_handler, params, user_input_monitor);
130 } 132 }
131 scoped_refptr<AudioInputController> controller(new AudioInputController( 133 scoped_refptr<AudioInputController> controller(new AudioInputController(
132 event_handler, nullptr, user_input_monitor, false)); 134 event_handler, nullptr, nullptr, user_input_monitor, false));
133 135
134 controller->task_runner_ = audio_manager->GetTaskRunner(); 136 controller->task_runner_ = audio_manager->GetTaskRunner();
135 137
136 // Create and open a new audio input stream from the existing 138 // Create and open a new audio input stream from the existing
137 // audio-device thread. 139 // audio-device thread.
138 if (!controller->task_runner_->PostTask( 140 if (!controller->task_runner_->PostTask(
139 FROM_HERE, 141 FROM_HERE,
140 base::Bind(&AudioInputController::DoCreate, 142 base::Bind(&AudioInputController::DoCreate,
141 controller, 143 controller,
142 base::Unretained(audio_manager), 144 base::Unretained(audio_manager),
143 params, 145 params,
144 device_id))) { 146 device_id))) {
145 controller = nullptr; 147 controller = nullptr;
146 } 148 }
147 149
148 return controller; 150 return controller;
149 } 151 }
150 152
151 // static 153 // static
152 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency( 154 scoped_refptr<AudioInputController> AudioInputController::CreateLowLatency(
153 AudioManager* audio_manager, 155 AudioManager* audio_manager,
154 EventHandler* event_handler, 156 EventHandler* event_handler,
155 const AudioParameters& params, 157 const AudioParameters& params,
156 const std::string& device_id, 158 const std::string& device_id,
157 SyncWriter* sync_writer, 159 SyncWriter* sync_writer,
160 std::unique_ptr<AudioInputWriter> debug_writer,
158 UserInputMonitor* user_input_monitor, 161 UserInputMonitor* user_input_monitor,
159 const bool agc_is_enabled) { 162 const bool agc_is_enabled) {
160 DCHECK(audio_manager); 163 DCHECK(audio_manager);
161 DCHECK(sync_writer); 164 DCHECK(sync_writer);
162 165
163 if (!params.IsValid() || (params.channels() > kMaxInputChannels)) 166 if (!params.IsValid() || (params.channels() > kMaxInputChannels))
164 return nullptr; 167 return nullptr;
165 168
166 // Create the AudioInputController object and ensure that it runs on 169 // Create the AudioInputController object and ensure that it runs on
167 // the audio-manager thread. 170 // the audio-manager thread.
168 scoped_refptr<AudioInputController> controller(new AudioInputController( 171 scoped_refptr<AudioInputController> controller(new AudioInputController(
169 event_handler, sync_writer, user_input_monitor, agc_is_enabled)); 172 event_handler, sync_writer, std::move(debug_writer), user_input_monitor,
173 agc_is_enabled));
170 controller->task_runner_ = audio_manager->GetTaskRunner(); 174 controller->task_runner_ = audio_manager->GetTaskRunner();
171 175
172 // Create and open a new audio input stream from the existing 176 // Create and open a new audio input stream from the existing
173 // audio-device thread. Use the provided audio-input device. 177 // audio-device thread. Use the provided audio-input device.
174 if (!controller->task_runner_->PostTask( 178 if (!controller->task_runner_->PostTask(
175 FROM_HERE, 179 FROM_HERE,
176 base::Bind(&AudioInputController::DoCreateForLowLatency, 180 base::Bind(&AudioInputController::DoCreateForLowLatency,
177 controller, 181 controller,
178 base::Unretained(audio_manager), 182 base::Unretained(audio_manager),
179 params, 183 params,
180 device_id))) { 184 device_id))) {
181 controller = nullptr; 185 controller = nullptr;
182 } 186 }
183 187
184 return controller; 188 return controller;
185 } 189 }
186 190
187 // static 191 // static
188 scoped_refptr<AudioInputController> AudioInputController::CreateForStream( 192 scoped_refptr<AudioInputController> AudioInputController::CreateForStream(
189 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 193 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
190 EventHandler* event_handler, 194 EventHandler* event_handler,
191 AudioInputStream* stream, 195 AudioInputStream* stream,
192 SyncWriter* sync_writer, 196 SyncWriter* sync_writer,
197 std::unique_ptr<AudioInputWriter> debug_writer,
193 UserInputMonitor* user_input_monitor) { 198 UserInputMonitor* user_input_monitor) {
194 DCHECK(sync_writer); 199 DCHECK(sync_writer);
195 DCHECK(stream); 200 DCHECK(stream);
196 201
197 // Create the AudioInputController object and ensure that it runs on 202 // Create the AudioInputController object and ensure that it runs on
198 // the audio-manager thread. 203 // the audio-manager thread.
199 scoped_refptr<AudioInputController> controller(new AudioInputController( 204 scoped_refptr<AudioInputController> controller(new AudioInputController(
200 event_handler, sync_writer, user_input_monitor, false)); 205 event_handler, sync_writer, std::move(debug_writer), user_input_monitor,
206 false));
201 controller->task_runner_ = task_runner; 207 controller->task_runner_ = task_runner;
202 208
203 if (!controller->task_runner_->PostTask( 209 if (!controller->task_runner_->PostTask(
204 FROM_HERE, 210 FROM_HERE,
205 base::Bind(&AudioInputController::DoCreateForStream, 211 base::Bind(&AudioInputController::DoCreateForStream,
206 controller, 212 controller,
207 stream))) { 213 stream))) {
208 controller = nullptr; 214 controller = nullptr;
209 } 215 }
210 216
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 if (user_input_monitor_) 373 if (user_input_monitor_)
368 user_input_monitor_->DisableKeyPressMonitoring(); 374 user_input_monitor_->DisableKeyPressMonitoring();
369 375
370 #if defined(AUDIO_POWER_MONITORING) 376 #if defined(AUDIO_POWER_MONITORING)
371 // Send UMA stats if enabled. 377 // Send UMA stats if enabled.
372 if (log_silence_state_) 378 if (log_silence_state_)
373 LogSilenceState(silence_state_); 379 LogSilenceState(silence_state_);
374 log_silence_state_ = false; 380 log_silence_state_ = false;
375 #endif 381 #endif
376 382
377 input_writer_ = nullptr; 383 if (debug_writer_)
384 debug_writer_->Stop();
378 385
379 state_ = CLOSED; 386 state_ = CLOSED;
380 } 387 }
381 388
382 void AudioInputController::DoReportError() { 389 void AudioInputController::DoReportError() {
383 DCHECK(task_runner_->BelongsToCurrentThread()); 390 DCHECK(task_runner_->BelongsToCurrentThread());
384 if (handler_) 391 if (handler_)
385 handler_->OnError(this, STREAM_ERROR); 392 handler_->OnError(this, STREAM_ERROR);
386 } 393 }
387 394
(...skipping 17 matching lines...) Expand all
405 } 412 }
406 413
407 // Set the stream volume and scale to a range matched to the platform. 414 // Set the stream volume and scale to a range matched to the platform.
408 stream_->SetVolume(max_volume_ * volume); 415 stream_->SetVolume(max_volume_ * volume);
409 } 416 }
410 417
411 void AudioInputController::OnData(AudioInputStream* stream, 418 void AudioInputController::OnData(AudioInputStream* stream,
412 const AudioBus* source, 419 const AudioBus* source,
413 uint32_t hardware_delay_bytes, 420 uint32_t hardware_delay_bytes,
414 double volume) { 421 double volume) {
415 // |input_writer_| should only be accessed on the audio thread, but as a means 422 if (debug_writer_ && debug_writer_->WillWrite()) {
416 // to avoid copying data and posting on the audio thread, we just check for
417 // non-null here.
418 if (input_writer_) {
419 std::unique_ptr<AudioBus> source_copy = 423 std::unique_ptr<AudioBus> source_copy =
420 AudioBus::Create(source->channels(), source->frames()); 424 AudioBus::Create(source->channels(), source->frames());
421 source->CopyTo(source_copy.get()); 425 source->CopyTo(source_copy.get());
422 task_runner_->PostTask( 426 task_runner_->PostTask(
423 FROM_HERE, 427 FROM_HERE,
424 base::Bind( 428 base::Bind(
425 &AudioInputController::WriteInputDataForDebugging, 429 &AudioInputController::WriteInputDataForDebugging,
426 this, 430 this,
427 base::Passed(&source_copy))); 431 base::Passed(&source_copy)));
428 } 432 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 #endif 541 #endif
538 } 542 }
539 543
540 void AudioInputController::OnError(AudioInputStream* stream) { 544 void AudioInputController::OnError(AudioInputStream* stream) {
541 // Handle error on the audio-manager thread. 545 // Handle error on the audio-manager thread.
542 task_runner_->PostTask(FROM_HERE, base::Bind( 546 task_runner_->PostTask(FROM_HERE, base::Bind(
543 &AudioInputController::DoReportError, this)); 547 &AudioInputController::DoReportError, this));
544 } 548 }
545 549
546 void AudioInputController::EnableDebugRecording( 550 void AudioInputController::EnableDebugRecording(
547 AudioInputWriter* input_writer) { 551 const base::FilePath& file_name) {
548 task_runner_->PostTask(FROM_HERE, base::Bind( 552 task_runner_->PostTask(
549 &AudioInputController::DoEnableDebugRecording, 553 FROM_HERE, base::Bind(&AudioInputController::DoEnableDebugRecording, this,
550 this, 554 file_name));
551 input_writer));
552 } 555 }
553 556
554 void AudioInputController::DisableDebugRecording( 557 void AudioInputController::DisableDebugRecording() {
555 const base::Closure& callback) {
556 DCHECK(creator_task_runner_->BelongsToCurrentThread()); 558 DCHECK(creator_task_runner_->BelongsToCurrentThread());
557 DCHECK(!callback.is_null()); 559 task_runner_->PostTask(
558
559 task_runner_->PostTaskAndReply(
560 FROM_HERE, 560 FROM_HERE,
561 base::Bind(&AudioInputController::DoDisableDebugRecording, 561 base::Bind(&AudioInputController::DoDisableDebugRecording, this));
562 this),
563 callback);
564 } 562 }
565 563
566 void AudioInputController::DoStopCloseAndClearStream() { 564 void AudioInputController::DoStopCloseAndClearStream() {
567 DCHECK(task_runner_->BelongsToCurrentThread()); 565 DCHECK(task_runner_->BelongsToCurrentThread());
568 566
569 // Allow calling unconditionally and bail if we don't have a stream to close. 567 // Allow calling unconditionally and bail if we don't have a stream to close.
570 if (stream_ != nullptr) { 568 if (stream_ != nullptr) {
571 stream_->Stop(); 569 stream_->Stop();
572 stream_->Close(); 570 stream_->Close();
573 stream_ = nullptr; 571 stream_ = nullptr;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 // after initialization. To avoid underflow, we 612 // after initialization. To avoid underflow, we
615 // also check if should_report_stats is one before decrementing. 613 // also check if should_report_stats is one before decrementing.
616 if (base::AtomicRefCountIsOne(&should_report_stats) && 614 if (base::AtomicRefCountIsOne(&should_report_stats) &&
617 !base::AtomicRefCountDec(&should_report_stats)) { 615 !base::AtomicRefCountDec(&should_report_stats)) {
618 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerCaptureStartupSuccess", 616 UMA_HISTOGRAM_ENUMERATION("Media.AudioInputControllerCaptureStartupSuccess",
619 result, CAPTURE_STARTUP_RESULT_MAX + 1); 617 result, CAPTURE_STARTUP_RESULT_MAX + 1);
620 } 618 }
621 } 619 }
622 620
623 void AudioInputController::DoEnableDebugRecording( 621 void AudioInputController::DoEnableDebugRecording(
624 AudioInputWriter* input_writer) { 622 const base::FilePath& file_name) {
625 DCHECK(task_runner_->BelongsToCurrentThread()); 623 DCHECK(task_runner_->BelongsToCurrentThread());
626 DCHECK(!input_writer_); 624 if (debug_writer_)
627 input_writer_ = input_writer; 625 debug_writer_->Start(file_name);
628 } 626 }
629 627
630 void AudioInputController::DoDisableDebugRecording() { 628 void AudioInputController::DoDisableDebugRecording() {
631 DCHECK(task_runner_->BelongsToCurrentThread()); 629 DCHECK(task_runner_->BelongsToCurrentThread());
632 input_writer_ = nullptr; 630 if (debug_writer_)
631 debug_writer_->Stop();
633 } 632 }
634 633
635 void AudioInputController::WriteInputDataForDebugging( 634 void AudioInputController::WriteInputDataForDebugging(
636 std::unique_ptr<AudioBus> data) { 635 std::unique_ptr<AudioBus> data) {
637 DCHECK(task_runner_->BelongsToCurrentThread()); 636 DCHECK(task_runner_->BelongsToCurrentThread());
638 if (input_writer_) 637 if (debug_writer_)
639 input_writer_->Write(std::move(data)); 638 debug_writer_->Write(std::move(data));
640 } 639 }
641 640
642 void AudioInputController::LogMessage(const std::string& message) { 641 void AudioInputController::LogMessage(const std::string& message) {
643 DCHECK(task_runner_->BelongsToCurrentThread()); 642 DCHECK(task_runner_->BelongsToCurrentThread());
644 handler_->OnLog(this, message); 643 handler_->OnLog(this, message);
645 } 644 }
646 645
647 } // namespace media 646 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_input_controller.h ('k') | media/audio/audio_input_writer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698