| Index: media/audio/audio_output_resampler.cc
|
| diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc
|
| index 9439a634fcdb45a6e38d32768662c8310a5c888e..dac341336aae2418d989576b355436dc3e8411ee 100644
|
| --- a/media/audio/audio_output_resampler.cc
|
| +++ b/media/audio/audio_output_resampler.cc
|
| @@ -18,8 +18,10 @@
|
| #include "base/metrics/sparse_histogram.h"
|
| #include "base/numerics/safe_conversions.h"
|
| #include "base/single_thread_task_runner.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "base/trace_event/trace_event.h"
|
| #include "build/build_config.h"
|
| +#include "media/audio/audio_debug_recording_helper.h"
|
| #include "media/audio/audio_output_proxy.h"
|
| #include "media/audio/sample_rates.h"
|
| #include "media/base/audio_converter.h"
|
| @@ -28,12 +30,33 @@
|
|
|
| namespace media {
|
|
|
| +namespace {
|
| +
|
| +// Running id to append to debug recording filename.
|
| +int g_next_debug_recording_filename_id = 1;
|
| +
|
| +#if defined(OS_WIN)
|
| +#define IntToStringType base::IntToString16
|
| +#else
|
| +#define IntToStringType base::IntToString
|
| +#endif
|
| +
|
| +// Adds debug recording filename running id as an extension.
|
| +base::FilePath AddDebugRecordingFilenameId(const base::FilePath& file_name) {
|
| + return file_name.AddExtension(
|
| + IntToStringType(g_next_debug_recording_filename_id++));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| class OnMoreDataConverter
|
| : public AudioOutputStream::AudioSourceCallback,
|
| public AudioConverter::InputCallback {
|
| public:
|
| - OnMoreDataConverter(const AudioParameters& input_params,
|
| - const AudioParameters& output_params);
|
| + OnMoreDataConverter(
|
| + const AudioParameters& input_params,
|
| + const AudioParameters& output_params,
|
| + std::unique_ptr<AudioDebugRecordingHelper> debug_recording_helper);
|
| ~OnMoreDataConverter() override;
|
|
|
| // AudioSourceCallback interface.
|
| @@ -50,6 +73,10 @@ class OnMoreDataConverter
|
| // Clears |source_callback_| and flushes the resampler.
|
| void Stop();
|
|
|
| + // Controls debug recording.
|
| + void EnableDebugRecording(const base::FilePath& file_name);
|
| + void DisableDebugRecording();
|
| +
|
| bool started() const { return source_callback_ != nullptr; }
|
|
|
| bool error_occurred() const { return error_occurred_; }
|
| @@ -84,6 +111,10 @@ class OnMoreDataConverter
|
| const int input_buffer_size_;
|
| const int output_buffer_size_;
|
|
|
| + // Used for audio debug recordings.
|
| + std::unique_ptr<AudioDebugRecordingHelper> debug_recording_helper_;
|
| + AudioParameters output_params_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(OnMoreDataConverter);
|
| };
|
|
|
| @@ -221,6 +252,7 @@ AudioOutputResampler::AudioOutputResampler(AudioManager* audio_manager,
|
| const std::string& output_device_id,
|
| const base::TimeDelta& close_delay)
|
| : AudioOutputDispatcher(audio_manager, input_params, output_device_id),
|
| + audio_manager_(audio_manager),
|
| close_delay_(close_delay),
|
| output_params_(output_params),
|
| original_output_params_(output_params),
|
| @@ -341,9 +373,17 @@ bool AudioOutputResampler::StartStream(
|
| OnMoreDataConverter* resampler_callback = nullptr;
|
| CallbackMap::iterator it = callbacks_.find(stream_proxy);
|
| if (it == callbacks_.end()) {
|
| - resampler_callback = new OnMoreDataConverter(params_, output_params_);
|
| + resampler_callback = new OnMoreDataConverter(
|
| + params_, output_params_,
|
| + base::MakeUnique<AudioDebugRecordingHelper>(
|
| + audio_manager_, audio_manager_->GetTaskRunner()));
|
| callbacks_[stream_proxy] =
|
| base::WrapUnique<OnMoreDataConverter>(resampler_callback);
|
| +
|
| + // If debug recording is enabled, enable it on the new OnMoreDataConverter.
|
| + if (!debug_recording_file_name_.empty())
|
| + resampler_callback->EnableDebugRecording(
|
| + AddDebugRecordingFilenameId(debug_recording_file_name_));
|
| } else {
|
| resampler_callback = it->second.get();
|
| }
|
| @@ -387,6 +427,21 @@ void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) {
|
| }
|
| }
|
|
|
| +void AudioOutputResampler::EnableDebugRecording(
|
| + const base::FilePath& file_name) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + for (const auto& item : callbacks_)
|
| + item.second->EnableDebugRecording(AddDebugRecordingFilenameId(file_name));
|
| + debug_recording_file_name_ = file_name;
|
| +}
|
| +
|
| +void AudioOutputResampler::DisableDebugRecording() {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + for (const auto& item : callbacks_)
|
| + item.second->DisableDebugRecording();
|
| + debug_recording_file_name_.clear();
|
| +}
|
| +
|
| void AudioOutputResampler::StopStreamInternal(
|
| const CallbackMap::value_type& item) {
|
| AudioOutputProxy* stream_proxy = item.first;
|
| @@ -408,8 +463,10 @@ void AudioOutputResampler::StopStreamInternal(
|
| dispatcher_->CloseAllIdleStreams();
|
| }
|
|
|
| -OnMoreDataConverter::OnMoreDataConverter(const AudioParameters& input_params,
|
| - const AudioParameters& output_params)
|
| +OnMoreDataConverter::OnMoreDataConverter(
|
| + const AudioParameters& input_params,
|
| + const AudioParameters& output_params,
|
| + std::unique_ptr<AudioDebugRecordingHelper> debug_recording_helper)
|
| : io_ratio_(static_cast<double>(input_params.GetBytesPerSecond()) /
|
| output_params.GetBytesPerSecond()),
|
| source_callback_(nullptr),
|
| @@ -417,7 +474,9 @@ OnMoreDataConverter::OnMoreDataConverter(const AudioParameters& input_params,
|
| audio_converter_(input_params, output_params, false),
|
| error_occurred_(false),
|
| input_buffer_size_(input_params.frames_per_buffer()),
|
| - output_buffer_size_(output_params.frames_per_buffer()) {
|
| + output_buffer_size_(output_params.frames_per_buffer()),
|
| + debug_recording_helper_(std::move(debug_recording_helper)),
|
| + output_params_(output_params) {
|
| RecordRebufferingStats(input_params, output_params);
|
| }
|
|
|
| @@ -454,6 +513,8 @@ int OnMoreDataConverter::OnMoreData(base::TimeDelta delay,
|
| current_delay_timestamp_ = delay_timestamp;
|
| audio_converter_.Convert(dest);
|
|
|
| + debug_recording_helper_->MaybeWrite(dest);
|
| +
|
| // Always return the full number of frames requested, ProvideInput()
|
| // will pad with silence if it wasn't able to acquire enough data.
|
| return dest->frames();
|
| @@ -480,4 +541,13 @@ void OnMoreDataConverter::OnError(AudioOutputStream* stream) {
|
| source_callback_->OnError(stream);
|
| }
|
|
|
| +void OnMoreDataConverter::EnableDebugRecording(
|
| + const base::FilePath& file_name) {
|
| + debug_recording_helper_->EnableDebugRecording(output_params_, file_name);
|
| +}
|
| +
|
| +void OnMoreDataConverter::DisableDebugRecording() {
|
| + debug_recording_helper_->DisableDebugRecording();
|
| +}
|
| +
|
| } // namespace media
|
|
|