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