| Index: media/audio/restartable_audio_output_device_impl.cc
|
| diff --git a/media/audio/restartable_audio_output_device_impl.cc b/media/audio/restartable_audio_output_device_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a1b2d1ce09262618e287343fe7cbcc21d2faab07
|
| --- /dev/null
|
| +++ b/media/audio/restartable_audio_output_device_impl.cc
|
| @@ -0,0 +1,118 @@
|
| +// Copyright (c) 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "media/audio/restartable_audio_output_device_impl.h"
|
| +
|
| +#include "media/audio/audio_output_device.h"
|
| +
|
| +namespace media {
|
| +
|
| +RestartableAudioOutputDeviceImpl::RestartableAudioOutputDeviceImpl(
|
| + const GetSinkCB& get_sink_cb,
|
| + const GetHWParamsCB& get_hw_params_cb)
|
| + : state_(kStopped),
|
| + volume_(1.0f),
|
| + render_cb_(nullptr),
|
| + get_sink_cb_(get_sink_cb),
|
| + get_hw_params_cb_(get_hw_params_cb),
|
| + // Creating output device now, since it may be needed to get output
|
| + // parameters before the device is started.
|
| + sink_(get_sink_cb_.Run()) {}
|
| +
|
| +void RestartableAudioOutputDeviceImpl::Initialize(const AudioParameters& params,
|
| + RenderCallback* callback) {
|
| + DCHECK_EQ(state_, kStopped) << "Calling Initialize() on a running device.";
|
| + DCHECK(callback);
|
| +
|
| + params_ = params;
|
| + render_cb_ = callback;
|
| +}
|
| +
|
| +RestartableAudioOutputDeviceImpl::~RestartableAudioOutputDeviceImpl() {
|
| + DCHECK_EQ(state_, kStopped) << "Stop() has not been called.";
|
| + if (sink_)
|
| + sink_->Stop(); // AudioOutputDevice must be stopped.
|
| +}
|
| +
|
| +void RestartableAudioOutputDeviceImpl::Start() {
|
| + DCHECK_EQ(state_, kStopped) << "Already started.";
|
| + DCHECK(render_cb_) << "Initialize() has not been called.";
|
| +
|
| + state_ = kStarted;
|
| +
|
| + if (!sink_) {
|
| + // Restarting the device after it was stopped.
|
| + sink_ = get_sink_cb_.Run(); // Restarting the device after it was stopped.
|
| + } // Otherwise the sink is created in the constructor.
|
| +
|
| + if (sink_->GetDeviceStatus() == OUTPUT_DEVICE_STATUS_OK)
|
| + sink_->Initialize(params_, render_cb_);
|
| +}
|
| +
|
| +void RestartableAudioOutputDeviceImpl::Stop() {
|
| + if (sink_) {
|
| + sink_->Stop();
|
| + sink_ = nullptr; // AudioOutputDevice cannot be restarted.
|
| + }
|
| + state_ = kStopped;
|
| +}
|
| +
|
| +void RestartableAudioOutputDeviceImpl::Play() {
|
| + if ((state_ == kPlaying) || (state_ == kStopped))
|
| + return;
|
| +
|
| + if (state_ == kPaused)
|
| + sink_->Play();
|
| + else { // kStarted, it's the first time Play() is called.
|
| + sink_->Start(); // AudioOutputDevice plays on start.
|
| + sink_->SetVolume(volume_);
|
| + }
|
| + state_ = kPlaying;
|
| +}
|
| +
|
| +void RestartableAudioOutputDeviceImpl::Pause() {
|
| + if (state_ != kPlaying)
|
| + return;
|
| +
|
| + sink_->Pause();
|
| + state_ = kPaused;
|
| +}
|
| +
|
| +bool RestartableAudioOutputDeviceImpl::SetVolume(double volume) {
|
| + volume_ = volume;
|
| + if (sink_ && ((state_ == kPaused) || (state_ == kPlaying)))
|
| + return sink_->SetVolume(volume_); // sink_->Start() is already called.
|
| + return true;
|
| +}
|
| +
|
| +OutputDevice* RestartableAudioOutputDeviceImpl::GetOutputDevice() {
|
| + return this;
|
| +}
|
| +
|
| +void RestartableAudioOutputDeviceImpl::SwitchOutputDevice(
|
| + const std::string& device_id,
|
| + const url::Origin& security_origin,
|
| + const SwitchOutputDeviceCB& callback) {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +AudioParameters RestartableAudioOutputDeviceImpl::GetOutputParameters() {
|
| + if (sink_)
|
| + return sink_->GetOutputParameters();
|
| +
|
| + return get_hw_params_cb_.Run();
|
| +}
|
| +
|
| +OutputDeviceStatus RestartableAudioOutputDeviceImpl::GetDeviceStatus() {
|
| + if (sink_)
|
| + return sink_->GetDeviceStatus();
|
| +
|
| + // If there is no sink because the device was stopped:
|
| + if (state_ == kStopped)
|
| + return OUTPUT_DEVICE_STATUS_OK;
|
| +
|
| + return OUTPUT_DEVICE_STATUS_ERROR_INTERNAL;
|
| +}
|
| +
|
| +} // namespace media
|
|
|