| 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_output_resampler.h" | 5 #include "media/audio/audio_output_resampler.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/metrics/sparse_histogram.h" | 18 #include "base/metrics/sparse_histogram.h" |
| 18 #include "base/numerics/safe_conversions.h" | 19 #include "base/numerics/safe_conversions.h" |
| 19 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
| 20 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
| 21 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 22 #include "media/audio/audio_output_proxy.h" | 23 #include "media/audio/audio_output_proxy.h" |
| 23 #include "media/audio/sample_rates.h" | 24 #include "media/audio/sample_rates.h" |
| 24 #include "media/base/audio_converter.h" | 25 #include "media/base/audio_converter.h" |
| 25 #include "media/base/audio_timestamp_helper.h" | 26 #include "media/base/audio_timestamp_helper.h" |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 DCHECK(streams_opened_); | 249 DCHECK(streams_opened_); |
| 249 | 250 |
| 250 // We can only reinitialize the dispatcher if it has no active proxies. Check | 251 // We can only reinitialize the dispatcher if it has no active proxies. Check |
| 251 // if one has been created since the reinitialization timer was started. | 252 // if one has been created since the reinitialization timer was started. |
| 252 if (dispatcher_->HasOutputProxies()) | 253 if (dispatcher_->HasOutputProxies()) |
| 253 return; | 254 return; |
| 254 | 255 |
| 255 // Log a trace event so we can get feedback in the field when this happens. | 256 // Log a trace event so we can get feedback in the field when this happens. |
| 256 TRACE_EVENT0("audio", "AudioOutputResampler::Reinitialize"); | 257 TRACE_EVENT0("audio", "AudioOutputResampler::Reinitialize"); |
| 257 | 258 |
| 258 dispatcher_->Shutdown(); | |
| 259 output_params_ = original_output_params_; | 259 output_params_ = original_output_params_; |
| 260 streams_opened_ = false; | 260 streams_opened_ = false; |
| 261 Initialize(); | 261 Initialize(); |
| 262 } | 262 } |
| 263 | 263 |
| 264 void AudioOutputResampler::Initialize() { | 264 void AudioOutputResampler::Initialize() { |
| 265 DCHECK(!streams_opened_); | 265 DCHECK(!streams_opened_); |
| 266 DCHECK(callbacks_.empty()); | 266 DCHECK(callbacks_.empty()); |
| 267 dispatcher_ = new AudioOutputDispatcherImpl( | 267 dispatcher_ = base::MakeUnique<AudioOutputDispatcherImpl>( |
| 268 audio_manager_, output_params_, device_id_, close_delay_); | 268 audio_manager_, output_params_, device_id_, close_delay_); |
| 269 } | 269 } |
| 270 | 270 |
| 271 bool AudioOutputResampler::OpenStream() { | 271 bool AudioOutputResampler::OpenStream() { |
| 272 DCHECK(task_runner_->BelongsToCurrentThread()); | 272 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 273 | 273 |
| 274 if (dispatcher_->OpenStream()) { | 274 if (dispatcher_->OpenStream()) { |
| 275 // Only record the UMA statistic if we didn't fallback during construction | 275 // Only record the UMA statistic if we didn't fallback during construction |
| 276 // and only for the first stream we open. | 276 // and only for the first stream we open. |
| 277 if (!streams_opened_ && | 277 if (!streams_opened_ && |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 | 384 |
| 385 // Start the reinitialization timer if there are no active proxies and we're | 385 // Start the reinitialization timer if there are no active proxies and we're |
| 386 // not using the originally requested output parameters. This allows us to | 386 // not using the originally requested output parameters. This allows us to |
| 387 // recover from transient output creation errors. | 387 // recover from transient output creation errors. |
| 388 if (!dispatcher_->HasOutputProxies() && callbacks_.empty() && | 388 if (!dispatcher_->HasOutputProxies() && callbacks_.empty() && |
| 389 !output_params_.Equals(original_output_params_)) { | 389 !output_params_.Equals(original_output_params_)) { |
| 390 reinitialize_timer_.Reset(); | 390 reinitialize_timer_.Reset(); |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 | 393 |
| 394 void AudioOutputResampler::Shutdown() { | |
| 395 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 396 | |
| 397 // No AudioOutputProxy objects should hold a reference to us when we get | |
| 398 // to this stage. | |
| 399 DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference"; | |
| 400 | |
| 401 dispatcher_->Shutdown(); | |
| 402 DCHECK(callbacks_.empty()); | |
| 403 } | |
| 404 | |
| 405 OnMoreDataConverter::OnMoreDataConverter(const AudioParameters& input_params, | 394 OnMoreDataConverter::OnMoreDataConverter(const AudioParameters& input_params, |
| 406 const AudioParameters& output_params) | 395 const AudioParameters& output_params) |
| 407 : io_ratio_(static_cast<double>(input_params.GetBytesPerSecond()) / | 396 : io_ratio_(static_cast<double>(input_params.GetBytesPerSecond()) / |
| 408 output_params.GetBytesPerSecond()), | 397 output_params.GetBytesPerSecond()), |
| 409 source_callback_(nullptr), | 398 source_callback_(nullptr), |
| 410 input_samples_per_second_(input_params.sample_rate()), | 399 input_samples_per_second_(input_params.sample_rate()), |
| 411 audio_converter_(input_params, output_params, false), | 400 audio_converter_(input_params, output_params, false), |
| 412 error_occurred_(false), | 401 error_occurred_(false), |
| 413 input_buffer_size_(input_params.frames_per_buffer()), | 402 input_buffer_size_(input_params.frames_per_buffer()), |
| 414 output_buffer_size_(output_params.frames_per_buffer()) { | 403 output_buffer_size_(output_params.frames_per_buffer()) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 dest->ZeroFramesPartial(frames, dest->frames() - frames); | 457 dest->ZeroFramesPartial(frames, dest->frames() - frames); |
| 469 return frames > 0 ? 1 : 0; | 458 return frames > 0 ? 1 : 0; |
| 470 } | 459 } |
| 471 | 460 |
| 472 void OnMoreDataConverter::OnError(AudioOutputStream* stream) { | 461 void OnMoreDataConverter::OnError(AudioOutputStream* stream) { |
| 473 error_occurred_ = true; | 462 error_occurred_ = true; |
| 474 source_callback_->OnError(stream); | 463 source_callback_->OnError(stream); |
| 475 } | 464 } |
| 476 | 465 |
| 477 } // namespace media | 466 } // namespace media |
| OLD | NEW |