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 3 // found in the LICENSE file. 4 5 #include "media/audio/audio_output_proxy.h" 6 7 #include "base/check_op.h" 8 #include "media/audio/audio_manager.h" 9 #include "media/audio/audio_output_dispatcher.h" 10 11 namespace media { 12 AudioOutputProxy(base::WeakPtr<AudioOutputDispatcher> dispatcher)13AudioOutputProxy::AudioOutputProxy( 14 base::WeakPtr<AudioOutputDispatcher> dispatcher) 15 : dispatcher_(std::move(dispatcher)), state_(kCreated), volume_(1.0) { 16 DCHECK(dispatcher_); 17 } 18 ~AudioOutputProxy()19AudioOutputProxy::~AudioOutputProxy() { 20 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 21 DCHECK(state_ == kCreated || state_ == kClosed) << "State is: " << state_; 22 } 23 Open()24bool AudioOutputProxy::Open() { 25 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 26 DCHECK_EQ(state_, kCreated); 27 28 if (!dispatcher_ || !dispatcher_->OpenStream()) { 29 state_ = kOpenError; 30 return false; 31 } 32 33 state_ = kOpened; 34 return true; 35 } 36 Start(AudioSourceCallback * callback)37void AudioOutputProxy::Start(AudioSourceCallback* callback) { 38 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 39 40 // We need to support both states since the callback may not handle OnError() 41 // immediately (or at all). It's also possible for subsequent StartStream() 42 // calls to succeed after failing, so we allow it to be called again. 43 DCHECK(state_ == kOpened || state_ == kStartError); 44 45 if (!dispatcher_ || !dispatcher_->StartStream(callback, this)) { 46 state_ = kStartError; 47 callback->OnError(AudioSourceCallback::ErrorType::kUnknown); 48 return; 49 } 50 state_ = kPlaying; 51 } 52 Stop()53void AudioOutputProxy::Stop() { 54 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 55 if (state_ != kPlaying) 56 return; 57 58 if (dispatcher_) 59 dispatcher_->StopStream(this); 60 state_ = kOpened; 61 } 62 SetVolume(double volume)63void AudioOutputProxy::SetVolume(double volume) { 64 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 65 volume_ = volume; 66 67 if (dispatcher_) 68 dispatcher_->StreamVolumeSet(this, volume); 69 } 70 GetVolume(double * volume)71void AudioOutputProxy::GetVolume(double* volume) { 72 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 73 *volume = volume_; 74 } 75 Close()76void AudioOutputProxy::Close() { 77 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 78 DCHECK(state_ == kCreated || state_ == kOpenError || state_ == kOpened || 79 state_ == kStartError); 80 81 // kStartError means OpenStream() succeeded and the stream must be closed 82 // before destruction. 83 if (state_ != kCreated && state_ != kOpenError && dispatcher_) 84 dispatcher_->CloseStream(this); 85 86 state_ = kClosed; 87 88 // Delete the object now like is done in the Close() implementation of 89 // physical stream objects. If we delete the object via DeleteSoon, we 90 // unnecessarily complicate the Shutdown procedure of the 91 // dispatcher+audio manager. 92 delete this; 93 } 94 Flush()95void AudioOutputProxy::Flush() { 96 DCHECK(state_ != kPlaying); 97 98 if (dispatcher_) 99 dispatcher_->FlushStream(this); 100 } 101 102 } // namespace media 103