Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: media/audio/audio_output_dispatcher.cc

Issue 8818012: Remove the AudioManager singleton. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Set svn eol properties for a couple of files Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/audio_output_dispatcher.h ('k') | media/audio/audio_output_proxy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_dispatcher.h" 5 #include "media/audio/audio_output_dispatcher.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "media/audio/audio_io.h" 11 #include "media/audio/audio_io.h"
12 12
13 AudioOutputDispatcher::AudioOutputDispatcher( 13 AudioOutputDispatcher::AudioOutputDispatcher(
14 AudioManager* audio_manager, const AudioParameters& params, 14 AudioManager* audio_manager, const AudioParameters& params,
15 int close_delay_ms) 15 int close_delay_ms)
16 : audio_manager_(audio_manager), 16 : audio_manager_(audio_manager),
17 message_loop_(audio_manager->GetMessageLoop()), 17 message_loop_(audio_manager->GetMessageLoop()),
18 params_(params), 18 params_(params),
19 pause_delay_milliseconds_(2 * params.samples_per_packet * 19 pause_delay_milliseconds_(2 * params.samples_per_packet *
20 base::Time::kMillisecondsPerSecond / params.sample_rate), 20 base::Time::kMillisecondsPerSecond / params.sample_rate),
21 paused_proxies_(0), 21 paused_proxies_(0),
22 ALLOW_THIS_IN_INITIALIZER_LIST(close_timer_(FROM_HERE, 22 ALLOW_THIS_IN_INITIALIZER_LIST(weak_this_(this)),
23 close_timer_(FROM_HERE,
23 base::TimeDelta::FromMilliseconds(close_delay_ms), 24 base::TimeDelta::FromMilliseconds(close_delay_ms),
24 this, &AudioOutputDispatcher::ClosePendingStreams)) { 25 weak_this_.GetWeakPtr(),
26 &AudioOutputDispatcher::ClosePendingStreams) {
27 DCHECK_EQ(MessageLoop::current(), message_loop_);
25 } 28 }
26 29
27 AudioOutputDispatcher::~AudioOutputDispatcher() { 30 AudioOutputDispatcher::~AudioOutputDispatcher() {
31 DCHECK_EQ(MessageLoop::current(), message_loop_);
28 } 32 }
29 33
30 bool AudioOutputDispatcher::StreamOpened() { 34 bool AudioOutputDispatcher::StreamOpened() {
31 DCHECK_EQ(MessageLoop::current(), message_loop_); 35 DCHECK_EQ(MessageLoop::current(), message_loop_);
32 paused_proxies_++; 36 paused_proxies_++;
33 37
34 // Ensure that there is at least one open stream. 38 // Ensure that there is at least one open stream.
35 if (idle_streams_.empty() && !CreateAndOpenStream()) { 39 if (idle_streams_.empty() && !CreateAndOpenStream()) {
36 return false; 40 return false;
37 } 41 }
(...skipping 13 matching lines...) Expand all
51 AudioOutputStream* stream = idle_streams_.back(); 55 AudioOutputStream* stream = idle_streams_.back();
52 idle_streams_.pop_back(); 56 idle_streams_.pop_back();
53 57
54 DCHECK_GT(paused_proxies_, 0u); 58 DCHECK_GT(paused_proxies_, 0u);
55 paused_proxies_--; 59 paused_proxies_--;
56 60
57 close_timer_.Reset(); 61 close_timer_.Reset();
58 62
59 // Schedule task to allocate streams for other proxies if we need to. 63 // Schedule task to allocate streams for other proxies if we need to.
60 message_loop_->PostTask(FROM_HERE, base::Bind( 64 message_loop_->PostTask(FROM_HERE, base::Bind(
61 &AudioOutputDispatcher::OpenTask, this)); 65 &AudioOutputDispatcher::OpenTask, weak_this_.GetWeakPtr()));
62 66
63 return stream; 67 return stream;
64 } 68 }
65 69
66 void AudioOutputDispatcher::StreamStopped(AudioOutputStream* stream) { 70 void AudioOutputDispatcher::StreamStopped(AudioOutputStream* stream) {
67 DCHECK_EQ(MessageLoop::current(), message_loop_); 71 DCHECK_EQ(MessageLoop::current(), message_loop_);
68 72
69 paused_proxies_++; 73 paused_proxies_++;
70 74
71 pausing_streams_.push_front(stream); 75 pausing_streams_.push_front(stream);
72 76
73 // Don't recycle stream until two buffers worth of time has elapsed. 77 // Don't recycle stream until two buffers worth of time has elapsed.
74 message_loop_->PostDelayedTask( 78 message_loop_->PostDelayedTask(
75 FROM_HERE, 79 FROM_HERE,
76 base::Bind(&AudioOutputDispatcher::StopStreamTask, this), 80 base::Bind(&AudioOutputDispatcher::StopStreamTask,
81 weak_this_.GetWeakPtr()),
77 pause_delay_milliseconds_); 82 pause_delay_milliseconds_);
78 } 83 }
79 84
80 void AudioOutputDispatcher::StopStreamTask() { 85 void AudioOutputDispatcher::StopStreamTask() {
86 DCHECK_EQ(MessageLoop::current(), message_loop_);
87
81 if (pausing_streams_.empty()) 88 if (pausing_streams_.empty())
82 return; 89 return;
90
83 AudioOutputStream* stream = pausing_streams_.back(); 91 AudioOutputStream* stream = pausing_streams_.back();
84 pausing_streams_.pop_back(); 92 pausing_streams_.pop_back();
85 idle_streams_.push_back(stream); 93 idle_streams_.push_back(stream);
86 close_timer_.Reset(); 94 close_timer_.Reset();
87 } 95 }
88 96
89 void AudioOutputDispatcher::StreamClosed() { 97 void AudioOutputDispatcher::StreamClosed() {
90 DCHECK_EQ(MessageLoop::current(), message_loop_); 98 DCHECK_EQ(MessageLoop::current(), message_loop_);
91 99
92 while (!pausing_streams_.empty()) { 100 while (!pausing_streams_.empty()) {
93 idle_streams_.push_back(pausing_streams_.back()); 101 idle_streams_.push_back(pausing_streams_.back());
94 pausing_streams_.pop_back(); 102 pausing_streams_.pop_back();
95 } 103 }
96 104
97 DCHECK_GT(paused_proxies_, 0u); 105 DCHECK_GT(paused_proxies_, 0u);
98 paused_proxies_--; 106 paused_proxies_--;
99 107
100 while (idle_streams_.size() > paused_proxies_) { 108 while (idle_streams_.size() > paused_proxies_) {
101 idle_streams_.back()->Close(); 109 idle_streams_.back()->Close();
102 idle_streams_.pop_back(); 110 idle_streams_.pop_back();
103 } 111 }
104 } 112 }
105 113
114 void AudioOutputDispatcher::Shutdown() {
115 DCHECK_EQ(MessageLoop::current(), message_loop_);
116
117 // Cancel any pending tasks to close paused streams or create new ones.
118 weak_this_.InvalidateWeakPtrs();
119
120 // No AudioOutputProxy objects should hold a reference to us when we get
121 // to this stage.
122 DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference";
123
124 AudioOutputStreamList::iterator it = idle_streams_.begin();
125 for (; it != idle_streams_.end(); ++it)
126 (*it)->Close();
127 idle_streams_.clear();
128
129 it = pausing_streams_.begin();
130 for (; it != pausing_streams_.end(); ++it)
131 (*it)->Close();
132 pausing_streams_.clear();
133 }
134
106 MessageLoop* AudioOutputDispatcher::message_loop() { 135 MessageLoop* AudioOutputDispatcher::message_loop() {
107 return message_loop_; 136 return message_loop_;
108 } 137 }
109 138
110 bool AudioOutputDispatcher::CreateAndOpenStream() { 139 bool AudioOutputDispatcher::CreateAndOpenStream() {
111 AudioOutputStream* stream = 140 AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(params_);
112 audio_manager_->MakeAudioOutputStream(params_); 141 if (!stream)
113 if (!stream) {
114 return false; 142 return false;
115 } 143
116 if (!stream->Open()) { 144 if (!stream->Open()) {
117 stream->Close(); 145 stream->Close();
118 return false; 146 return false;
119 } 147 }
120 idle_streams_.push_back(stream); 148 idle_streams_.push_back(stream);
121 return true; 149 return true;
122 } 150 }
123 151
124 void AudioOutputDispatcher::OpenTask() { 152 void AudioOutputDispatcher::OpenTask() {
125 // Make sure that we have at least one stream allocated if there 153 // Make sure that we have at least one stream allocated if there
126 // are paused streams. 154 // are paused streams.
127 if (paused_proxies_ > 0 && idle_streams_.empty() && 155 if (paused_proxies_ > 0 && idle_streams_.empty() &&
128 pausing_streams_.empty()) { 156 pausing_streams_.empty()) {
129 CreateAndOpenStream(); 157 CreateAndOpenStream();
130 } 158 }
131 159
132 close_timer_.Reset(); 160 close_timer_.Reset();
133 } 161 }
134 162
135 // This method is called by |close_timer_|. 163 // This method is called by |close_timer_|.
136 void AudioOutputDispatcher::ClosePendingStreams() { 164 void AudioOutputDispatcher::ClosePendingStreams() {
165 DCHECK_EQ(MessageLoop::current(), message_loop_);
166
137 while (!idle_streams_.empty()) { 167 while (!idle_streams_.empty()) {
138 idle_streams_.back()->Close(); 168 idle_streams_.back()->Close();
139 idle_streams_.pop_back(); 169 idle_streams_.pop_back();
140 } 170 }
141 } 171 }
OLDNEW
« no previous file with comments | « media/audio/audio_output_dispatcher.h ('k') | media/audio/audio_output_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698