Index: media/audio/audio_manager_base.cc |
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc |
index 670820dc3a6ad0f446d429cd97b4e3a7484f5c67..8b44ff1c92d185fd3f88fb6a0034ed5ec0cdca50 100644 |
--- a/media/audio/audio_manager_base.cc |
+++ b/media/audio/audio_manager_base.cc |
@@ -78,24 +78,28 @@ class AudioManagerBase::CompareByParams { |
AudioManagerBase::AudioManagerBase( |
scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
- AudioLogFactory* audio_log_factory) |
+ AudioLogFactory* audio_log_factory, |
+ CreateAudioFileWriterCallback create_audio_file_writer_callback) |
: AudioManager(std::move(task_runner), std::move(worker_task_runner)), |
max_num_output_streams_(kDefaultMaxOutputStreams), |
max_num_input_streams_(kDefaultMaxInputStreams), |
- num_output_streams_(0), |
// TODO(dalecurtis): Switch this to an base::ObserverListThreadSafe, so we |
- // don't |
- // block the UI thread when swapping devices. |
+ // don't block the UI thread when swapping devices. |
output_listeners_( |
base::ObserverList<AudioDeviceListener>::NOTIFY_EXISTING_ONLY), |
- audio_log_factory_(audio_log_factory) {} |
+ audio_log_factory_(audio_log_factory), |
+ create_audio_file_writer_callback_( |
+ std::move(create_audio_file_writer_callback)), |
+ next_filename_id_(1) { |
+ CHECK(!create_audio_file_writer_callback_.Equals( |
+ CreateAudioFileWriterCallback())); |
+} |
AudioManagerBase::~AudioManagerBase() { |
DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
- // All the output streams should have been deleted. |
- CHECK_EQ(0, num_output_streams_); |
- // All the input streams should have been deleted. |
+ // All the output and input streams should have been deleted. |
+ CHECK(output_streams_.empty()); |
CHECK(input_streams_.empty()); |
} |
@@ -135,19 +139,18 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
if (!params.IsValid()) { |
DLOG(ERROR) << "Audio parameters are invalid"; |
- return NULL; |
+ return nullptr; |
} |
// Limit the number of audio streams opened. This is to prevent using |
// excessive resources for a large number of audio streams. More |
// importantly it prevents instability on certain systems. |
// See bug: http://crbug.com/30242. |
- if (num_output_streams_ >= max_num_output_streams_) { |
+ if (output_stream_count() >= max_num_output_streams_) { |
DLOG(ERROR) << "Number of opened output audio streams " |
- << num_output_streams_ |
- << " exceed the max allowed number " |
+ << output_stream_count() << " exceed the max allowed number " |
<< max_num_output_streams_; |
- return NULL; |
+ return nullptr; |
} |
AudioOutputStream* stream; |
@@ -170,12 +173,19 @@ AudioOutputStream* AudioManagerBase::MakeAudioOutputStream( |
stream = FakeAudioOutputStream::MakeFakeStream(this, params); |
break; |
default: |
- stream = NULL; |
+ stream = nullptr; |
break; |
} |
if (stream) { |
- ++num_output_streams_; |
+ output_streams_.insert(stream); |
+ |
+ // Debug recording is enabled if the file name is non-empty. If so, also |
+ // enable it on the new stream. |
+ if (!debug_recording_base_file_name_.empty()) { |
+ stream->EnableDebugRecording(GetDebugRecordingFileNameWithExtensions( |
+ debug_recording_base_file_name_)); |
+ } |
} |
return stream; |
@@ -311,18 +321,18 @@ void AudioManagerBase::GetAudioOutputDeviceNames( |
void AudioManagerBase::ReleaseOutputStream(AudioOutputStream* stream) { |
CHECK(GetTaskRunner()->BelongsToCurrentThread()); |
DCHECK(stream); |
- CHECK_GT(num_output_streams_, 0); |
- // TODO(xians) : Have a clearer destruction path for the AudioOutputStream. |
+ stream->DisableDebugRecording(); |
+ // TODO(grunell): Have a clearer destruction path for the AudioOutputStream. |
// For example, pass the ownership to AudioManager so it can delete the |
// streams. |
- --num_output_streams_; |
+ CHECK_EQ(1u, output_streams_.erase(stream)); |
delete stream; |
} |
void AudioManagerBase::ReleaseInputStream(AudioInputStream* stream) { |
CHECK(GetTaskRunner()->BelongsToCurrentThread()); |
DCHECK(stream); |
- // TODO(xians) : Have a clearer destruction path for the AudioInputStream. |
+ // TODO(grunell): Have a clearer destruction path for the AudioInputStream. |
CHECK_EQ(1u, input_streams_.erase(stream)); |
delete stream; |
} |
@@ -433,6 +443,40 @@ std::unique_ptr<AudioLog> AudioManagerBase::CreateAudioLog( |
return audio_log_factory_->CreateAudioLog(component); |
} |
+std::unique_ptr<AudioFileWriter> AudioManagerBase::CreateAudioFileWriter( |
+ const AudioParameters& params) { |
+ return create_audio_file_writer_callback_.Run(params); |
+} |
+ |
+void AudioManagerBase::EnableOutputDebugRecording( |
+ const base::FilePath& base_file_name) { |
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
+ for (auto it : output_streams_) { |
+ it->EnableDebugRecording( |
+ GetDebugRecordingFileNameWithExtensions(base_file_name)); |
+ } |
+ debug_recording_base_file_name_ = base_file_name; |
+} |
+ |
+void AudioManagerBase::DisableOutputDebugRecording() { |
+ DCHECK(GetTaskRunner()->BelongsToCurrentThread()); |
+ for (auto it : output_streams_) |
+ it->DisableDebugRecording(); |
+ debug_recording_base_file_name_.clear(); |
+} |
+ |
+#if defined(OS_WIN) |
+#define IntToStringType base::IntToString16 |
+#else |
+#define IntToStringType base::IntToString |
+#endif |
+ |
+base::FilePath AudioManagerBase::GetDebugRecordingFileNameWithExtensions( |
+ const base::FilePath& file_name) { |
+ return file_name.AddExtension("output").AddExtension( |
+ IntToStringType(next_filename_id_++)); |
+} |
+ |
void AudioManagerBase::SetMaxStreamCountForTesting(int max_input, |
int max_output) { |
max_num_output_streams_ = max_output; |