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

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

Issue 2582703003: Audio output debug recording. (Closed)
Patch Set: Code review (dalecurtis@ and maxmorin@). Created 3 years, 11 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
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_manager_base.h" 5 #include "media/audio/audio_manager_base.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 dispatcher_->output_device_id == dispatcher_in->output_device_id); 71 dispatcher_->output_device_id == dispatcher_in->output_device_id);
72 } 72 }
73 73
74 private: 74 private:
75 const DispatcherParams* dispatcher_; 75 const DispatcherParams* dispatcher_;
76 }; 76 };
77 77
78 AudioManagerBase::AudioManagerBase( 78 AudioManagerBase::AudioManagerBase(
79 scoped_refptr<base::SingleThreadTaskRunner> task_runner, 79 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
80 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, 80 scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner,
81 AudioLogFactory* audio_log_factory) 81 AudioLogFactory* audio_log_factory,
82 CreateAudioFileWriterCallback create_audio_file_writer_callback)
82 : AudioManager(std::move(task_runner), std::move(worker_task_runner)), 83 : AudioManager(std::move(task_runner), std::move(worker_task_runner)),
83 max_num_output_streams_(kDefaultMaxOutputStreams), 84 max_num_output_streams_(kDefaultMaxOutputStreams),
84 max_num_input_streams_(kDefaultMaxInputStreams), 85 max_num_input_streams_(kDefaultMaxInputStreams),
85 num_output_streams_(0),
86 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we 86 // TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we
87 // don't 87 // don't block the UI thread when swapping devices.
88 // block the UI thread when swapping devices.
89 output_listeners_( 88 output_listeners_(
90 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), 89 base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY),
91 audio_log_factory_(audio_log_factory) {} 90 audio_log_factory_(audio_log_factory),
91 create_audio_file_writer_callback_(
92 std::move(create_audio_file_writer_callback)),
93 next_filename_id_(1) {
94 CHECK(!create_audio_file_writer_callback_.Equals(
95 CreateAudioFileWriterCallback()));
96 }
92 97
93 AudioManagerBase::~AudioManagerBase() { 98 AudioManagerBase::~AudioManagerBase() {
94 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 99 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
95 100
96 // All the output streams should have been deleted. 101 // All the output and input streams should have been deleted.
97 CHECK_EQ(0, num_output_streams_); 102 CHECK(output_streams_.empty());
98 // All the input streams should have been deleted.
99 CHECK(input_streams_.empty()); 103 CHECK(input_streams_.empty());
100 } 104 }
101 105
102 base::string16 AudioManagerBase::GetAudioInputDeviceModel() { 106 base::string16 AudioManagerBase::GetAudioInputDeviceModel() {
103 return base::string16(); 107 return base::string16();
104 } 108 }
105 109
106 void AudioManagerBase::GetAudioInputDeviceDescriptions( 110 void AudioManagerBase::GetAudioInputDeviceDescriptions(
107 AudioDeviceDescriptions* device_descriptions) { 111 AudioDeviceDescriptions* device_descriptions) {
108 CHECK(GetTaskRunner()->BelongsToCurrentThread()); 112 CHECK(GetTaskRunner()->BelongsToCurrentThread());
(...skipping 19 matching lines...) Expand all
128 } 132 }
129 133
130 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( 134 AudioOutputStream* AudioManagerBase::MakeAudioOutputStream(
131 const AudioParameters& params, 135 const AudioParameters& params,
132 const std::string& device_id, 136 const std::string& device_id,
133 const LogCallback& log_callback) { 137 const LogCallback& log_callback) {
134 CHECK(GetTaskRunner()->BelongsToCurrentThread()); 138 CHECK(GetTaskRunner()->BelongsToCurrentThread());
135 139
136 if (!params.IsValid()) { 140 if (!params.IsValid()) {
137 DLOG(ERROR) << "Audio parameters are invalid"; 141 DLOG(ERROR) << "Audio parameters are invalid";
138 return NULL; 142 return nullptr;
139 } 143 }
140 144
141 // Limit the number of audio streams opened. This is to prevent using 145 // Limit the number of audio streams opened. This is to prevent using
142 // excessive resources for a large number of audio streams. More 146 // excessive resources for a large number of audio streams. More
143 // importantly it prevents instability on certain systems. 147 // importantly it prevents instability on certain systems.
144 // See bug: http://crbug.com/30242. 148 // See bug: http://crbug.com/30242.
145 if (num_output_streams_ >= max_num_output_streams_) { 149 if (output_stream_count() >= max_num_output_streams_) {
146 DLOG(ERROR) << "Number of opened output audio streams " 150 DLOG(ERROR) << "Number of opened output audio streams "
147 << num_output_streams_ 151 << output_stream_count() << " exceed the max allowed number "
148 << " exceed the max allowed number "
149 << max_num_output_streams_; 152 << max_num_output_streams_;
150 return NULL; 153 return nullptr;
151 } 154 }
152 155
153 AudioOutputStream* stream; 156 AudioOutputStream* stream;
154 switch (params.format()) { 157 switch (params.format()) {
155 case AudioParameters::AUDIO_PCM_LINEAR: 158 case AudioParameters::AUDIO_PCM_LINEAR:
156 DCHECK(AudioDeviceDescription::IsDefaultDevice(device_id)) 159 DCHECK(AudioDeviceDescription::IsDefaultDevice(device_id))
157 << "AUDIO_PCM_LINEAR supports only the default device."; 160 << "AUDIO_PCM_LINEAR supports only the default device.";
158 stream = MakeLinearOutputStream(params, log_callback); 161 stream = MakeLinearOutputStream(params, log_callback);
159 break; 162 break;
160 case AudioParameters::AUDIO_PCM_LOW_LATENCY: 163 case AudioParameters::AUDIO_PCM_LOW_LATENCY:
161 stream = MakeLowLatencyOutputStream(params, device_id, log_callback); 164 stream = MakeLowLatencyOutputStream(params, device_id, log_callback);
162 break; 165 break;
163 case AudioParameters::AUDIO_BITSTREAM_AC3: 166 case AudioParameters::AUDIO_BITSTREAM_AC3:
164 case AudioParameters::AUDIO_BITSTREAM_EAC3: 167 case AudioParameters::AUDIO_BITSTREAM_EAC3:
165 // TODO(tsunghung): create passthrough output stream. 168 // TODO(tsunghung): create passthrough output stream.
166 NOTREACHED(); 169 NOTREACHED();
167 stream = nullptr; 170 stream = nullptr;
168 break; 171 break;
169 case AudioParameters::AUDIO_FAKE: 172 case AudioParameters::AUDIO_FAKE:
170 stream = FakeAudioOutputStream::MakeFakeStream(this, params); 173 stream = FakeAudioOutputStream::MakeFakeStream(this, params);
171 break; 174 break;
172 default: 175 default:
173 stream = NULL; 176 stream = nullptr;
174 break; 177 break;
175 } 178 }
176 179
177 if (stream) { 180 if (stream) {
178 ++num_output_streams_; 181 output_streams_.insert(stream);
182
183 // Debug recording is enabled if the file name is non-empty. If so, also
184 // enable it on the new stream.
185 if (!debug_recording_base_file_name_.empty()) {
186 stream->EnableDebugRecording(GetDebugRecordingFileNameWithExtensions(
187 debug_recording_base_file_name_));
188 }
179 } 189 }
180 190
181 return stream; 191 return stream;
182 } 192 }
183 193
184 AudioInputStream* AudioManagerBase::MakeAudioInputStream( 194 AudioInputStream* AudioManagerBase::MakeAudioInputStream(
185 const AudioParameters& params, 195 const AudioParameters& params,
186 const std::string& device_id, 196 const std::string& device_id,
187 const LogCallback& log_callback) { 197 const LogCallback& log_callback) {
188 CHECK(GetTaskRunner()->BelongsToCurrentThread()); 198 CHECK(GetTaskRunner()->BelongsToCurrentThread());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 AudioDeviceNames* device_names) { 314 AudioDeviceNames* device_names) {
305 } 315 }
306 316
307 void AudioManagerBase::GetAudioOutputDeviceNames( 317 void AudioManagerBase::GetAudioOutputDeviceNames(
308 AudioDeviceNames* device_names) { 318 AudioDeviceNames* device_names) {
309 } 319 }
310 320
311 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { 321 void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) {
312 CHECK(GetTaskRunner()->BelongsToCurrentThread()); 322 CHECK(GetTaskRunner()->BelongsToCurrentThread());
313 DCHECK(stream); 323 DCHECK(stream);
314 CHECK_GT(num_output_streams_, 0); 324 stream->DisableDebugRecording();
315 // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. 325 // TODO(grunell): Have a clearer destruction path for the AudioOutputStream.
316 // For example, pass the ownership to AudioManager so it can delete the 326 // For example, pass the ownership to AudioManager so it can delete the
317 // streams. 327 // streams.
318 --num_output_streams_; 328 CHECK_EQ(1u, output_streams_.erase(stream));
319 delete stream; 329 delete stream;
320 } 330 }
321 331
322 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { 332 void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) {
323 CHECK(GetTaskRunner()->BelongsToCurrentThread()); 333 CHECK(GetTaskRunner()->BelongsToCurrentThread());
324 DCHECK(stream); 334 DCHECK(stream);
325 // TODO(xians) : Have a clearer destruction path for the AudioInputStream. 335 // TODO(grunell): Have a clearer destruction path for the AudioInputStream.
326 CHECK_EQ(1u, input_streams_.erase(stream)); 336 CHECK_EQ(1u, input_streams_.erase(stream));
327 delete stream; 337 delete stream;
328 } 338 }
329 339
330 void AudioManagerBase::Shutdown() { 340 void AudioManagerBase::Shutdown() {
331 DCHECK(GetTaskRunner()->BelongsToCurrentThread()); 341 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
332 342
333 // Close all output streams. 343 // Close all output streams.
334 output_dispatchers_.clear(); 344 output_dispatchers_.clear();
335 345
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 return buffer_size; 436 return buffer_size;
427 437
428 return 0; 438 return 0;
429 } 439 }
430 440
431 std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog( 441 std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog(
432 AudioLogFactory::AudioComponent component) { 442 AudioLogFactory::AudioComponent component) {
433 return audio_log_factory_->CreateAudioLog(component); 443 return audio_log_factory_->CreateAudioLog(component);
434 } 444 }
435 445
446 std::unique_ptr<AudioFileWriter> AudioManagerBase::CreateAudioFileWriter(
447 const AudioParameters& params) {
448 return create_audio_file_writer_callback_.Run(params);
449 }
450
451 void AudioManagerBase::EnableOutputDebugRecording(
452 const base::FilePath& base_file_name) {
453 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
454 for (auto it : output_streams_) {
455 it->EnableDebugRecording(
456 GetDebugRecordingFileNameWithExtensions(base_file_name));
457 }
458 debug_recording_base_file_name_ = base_file_name;
459 }
460
461 void AudioManagerBase::DisableOutputDebugRecording() {
462 DCHECK(GetTaskRunner()->BelongsToCurrentThread());
463 for (auto it : output_streams_)
464 it->DisableDebugRecording();
465 debug_recording_base_file_name_.clear();
466 }
467
468 #if defined(OS_WIN)
469 #define IntToStringType base::IntToString16
470 #else
471 #define IntToStringType base::IntToString
472 #endif
473
474 base::FilePath AudioManagerBase::GetDebugRecordingFileNameWithExtensions(
475 const base::FilePath& file_name) {
476 return file_name.AddExtension("output").AddExtension(
477 IntToStringType(next_filename_id_++));
478 }
479
436 void AudioManagerBase::SetMaxStreamCountForTesting(int max_input, 480 void AudioManagerBase::SetMaxStreamCountForTesting(int max_input,
437 int max_output) { 481 int max_output) {
438 max_num_output_streams_ = max_output; 482 max_num_output_streams_ = max_output;
439 max_num_input_streams_ = max_input; 483 max_num_input_streams_ = max_input;
440 } 484 }
441 485
442 } // namespace media 486 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698