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

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

Issue 66183002: Replace MessageLoopProxy with SingleThreadTaskRunner for the rest of media/. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win and audio tests Created 6 years, 11 months 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.cc ('k') | media/audio/audio_output_proxy_unittest.cc » ('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) 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_dispatcher_impl.h" 5 #include "media/audio/audio_output_dispatcher_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/single_thread_task_runner.h"
12 #include "base/time/time.h" 12 #include "base/time/time.h"
13 #include "media/audio/audio_io.h" 13 #include "media/audio/audio_io.h"
14 #include "media/audio/audio_output_proxy.h" 14 #include "media/audio/audio_output_proxy.h"
15 15
16 namespace media { 16 namespace media {
17 17
18 AudioOutputDispatcherImpl::AudioOutputDispatcherImpl( 18 AudioOutputDispatcherImpl::AudioOutputDispatcherImpl(
19 AudioManager* audio_manager, 19 AudioManager* audio_manager,
20 const AudioParameters& params, 20 const AudioParameters& params,
21 const std::string& output_device_id, 21 const std::string& output_device_id,
(...skipping 12 matching lines...) Expand all
34 audio_manager->CreateAudioLog(AudioLogFactory::AUDIO_OUTPUT_STREAM)), 34 audio_manager->CreateAudioLog(AudioLogFactory::AUDIO_OUTPUT_STREAM)),
35 audio_stream_id_(0) {} 35 audio_stream_id_(0) {}
36 36
37 AudioOutputDispatcherImpl::~AudioOutputDispatcherImpl() { 37 AudioOutputDispatcherImpl::~AudioOutputDispatcherImpl() {
38 DCHECK_EQ(idle_proxies_, 0u); 38 DCHECK_EQ(idle_proxies_, 0u);
39 DCHECK(proxy_to_physical_map_.empty()); 39 DCHECK(proxy_to_physical_map_.empty());
40 DCHECK(idle_streams_.empty()); 40 DCHECK(idle_streams_.empty());
41 } 41 }
42 42
43 bool AudioOutputDispatcherImpl::OpenStream() { 43 bool AudioOutputDispatcherImpl::OpenStream() {
44 DCHECK(message_loop_->BelongsToCurrentThread()); 44 DCHECK(task_runner_->BelongsToCurrentThread());
45 45
46 // Ensure that there is at least one open stream. 46 // Ensure that there is at least one open stream.
47 if (idle_streams_.empty() && !CreateAndOpenStream()) 47 if (idle_streams_.empty() && !CreateAndOpenStream())
48 return false; 48 return false;
49 49
50 ++idle_proxies_; 50 ++idle_proxies_;
51 close_timer_.Reset(); 51 close_timer_.Reset();
52 return true; 52 return true;
53 } 53 }
54 54
55 bool AudioOutputDispatcherImpl::StartStream( 55 bool AudioOutputDispatcherImpl::StartStream(
56 AudioOutputStream::AudioSourceCallback* callback, 56 AudioOutputStream::AudioSourceCallback* callback,
57 AudioOutputProxy* stream_proxy) { 57 AudioOutputProxy* stream_proxy) {
58 DCHECK(message_loop_->BelongsToCurrentThread()); 58 DCHECK(task_runner_->BelongsToCurrentThread());
59 DCHECK(proxy_to_physical_map_.find(stream_proxy) == 59 DCHECK(proxy_to_physical_map_.find(stream_proxy) ==
60 proxy_to_physical_map_.end()); 60 proxy_to_physical_map_.end());
61 61
62 if (idle_streams_.empty() && !CreateAndOpenStream()) 62 if (idle_streams_.empty() && !CreateAndOpenStream())
63 return false; 63 return false;
64 64
65 AudioOutputStream* physical_stream = idle_streams_.back(); 65 AudioOutputStream* physical_stream = idle_streams_.back();
66 idle_streams_.pop_back(); 66 idle_streams_.pop_back();
67 67
68 DCHECK_GT(idle_proxies_, 0u); 68 DCHECK_GT(idle_proxies_, 0u);
69 --idle_proxies_; 69 --idle_proxies_;
70 70
71 double volume = 0; 71 double volume = 0;
72 stream_proxy->GetVolume(&volume); 72 stream_proxy->GetVolume(&volume);
73 physical_stream->SetVolume(volume); 73 physical_stream->SetVolume(volume);
74 const int stream_id = audio_stream_ids_[physical_stream]; 74 const int stream_id = audio_stream_ids_[physical_stream];
75 audio_log_->OnSetVolume(stream_id, volume); 75 audio_log_->OnSetVolume(stream_id, volume);
76 physical_stream->Start(callback); 76 physical_stream->Start(callback);
77 audio_log_->OnStarted(stream_id); 77 audio_log_->OnStarted(stream_id);
78 proxy_to_physical_map_[stream_proxy] = physical_stream; 78 proxy_to_physical_map_[stream_proxy] = physical_stream;
79 79
80 close_timer_.Reset(); 80 close_timer_.Reset();
81 return true; 81 return true;
82 } 82 }
83 83
84 void AudioOutputDispatcherImpl::StopStream(AudioOutputProxy* stream_proxy) { 84 void AudioOutputDispatcherImpl::StopStream(AudioOutputProxy* stream_proxy) {
85 DCHECK(message_loop_->BelongsToCurrentThread()); 85 DCHECK(task_runner_->BelongsToCurrentThread());
86 86
87 AudioStreamMap::iterator it = proxy_to_physical_map_.find(stream_proxy); 87 AudioStreamMap::iterator it = proxy_to_physical_map_.find(stream_proxy);
88 DCHECK(it != proxy_to_physical_map_.end()); 88 DCHECK(it != proxy_to_physical_map_.end());
89 AudioOutputStream* physical_stream = it->second; 89 AudioOutputStream* physical_stream = it->second;
90 proxy_to_physical_map_.erase(it); 90 proxy_to_physical_map_.erase(it);
91 91
92 physical_stream->Stop(); 92 physical_stream->Stop();
93 audio_log_->OnStopped(audio_stream_ids_[physical_stream]); 93 audio_log_->OnStopped(audio_stream_ids_[physical_stream]);
94 ++idle_proxies_; 94 ++idle_proxies_;
95 idle_streams_.push_back(physical_stream); 95 idle_streams_.push_back(physical_stream);
96 96
97 close_timer_.Reset(); 97 close_timer_.Reset();
98 } 98 }
99 99
100 void AudioOutputDispatcherImpl::StreamVolumeSet(AudioOutputProxy* stream_proxy, 100 void AudioOutputDispatcherImpl::StreamVolumeSet(AudioOutputProxy* stream_proxy,
101 double volume) { 101 double volume) {
102 DCHECK(message_loop_->BelongsToCurrentThread()); 102 DCHECK(task_runner_->BelongsToCurrentThread());
103 AudioStreamMap::iterator it = proxy_to_physical_map_.find(stream_proxy); 103 AudioStreamMap::iterator it = proxy_to_physical_map_.find(stream_proxy);
104 if (it != proxy_to_physical_map_.end()) { 104 if (it != proxy_to_physical_map_.end()) {
105 AudioOutputStream* physical_stream = it->second; 105 AudioOutputStream* physical_stream = it->second;
106 physical_stream->SetVolume(volume); 106 physical_stream->SetVolume(volume);
107 audio_log_->OnSetVolume(audio_stream_ids_[physical_stream], volume); 107 audio_log_->OnSetVolume(audio_stream_ids_[physical_stream], volume);
108 } 108 }
109 } 109 }
110 110
111 void AudioOutputDispatcherImpl::CloseStream(AudioOutputProxy* stream_proxy) { 111 void AudioOutputDispatcherImpl::CloseStream(AudioOutputProxy* stream_proxy) {
112 DCHECK(message_loop_->BelongsToCurrentThread()); 112 DCHECK(task_runner_->BelongsToCurrentThread());
113 113
114 DCHECK_GT(idle_proxies_, 0u); 114 DCHECK_GT(idle_proxies_, 0u);
115 --idle_proxies_; 115 --idle_proxies_;
116 116
117 // Leave at least a single stream running until the close timer fires to help 117 // Leave at least a single stream running until the close timer fires to help
118 // cycle time when streams are opened and closed repeatedly. 118 // cycle time when streams are opened and closed repeatedly.
119 CloseIdleStreams(std::max(idle_proxies_, static_cast<size_t>(1))); 119 CloseIdleStreams(std::max(idle_proxies_, static_cast<size_t>(1)));
120 close_timer_.Reset(); 120 close_timer_.Reset();
121 } 121 }
122 122
123 void AudioOutputDispatcherImpl::Shutdown() { 123 void AudioOutputDispatcherImpl::Shutdown() {
124 DCHECK(message_loop_->BelongsToCurrentThread()); 124 DCHECK(task_runner_->BelongsToCurrentThread());
125 125
126 // Close all idle streams immediately. The |close_timer_| will handle 126 // Close all idle streams immediately. The |close_timer_| will handle
127 // invalidating any outstanding tasks upon its destruction. 127 // invalidating any outstanding tasks upon its destruction.
128 CloseAllIdleStreams(); 128 CloseAllIdleStreams();
129 } 129 }
130 130
131 bool AudioOutputDispatcherImpl::CreateAndOpenStream() { 131 bool AudioOutputDispatcherImpl::CreateAndOpenStream() {
132 DCHECK(message_loop_->BelongsToCurrentThread()); 132 DCHECK(task_runner_->BelongsToCurrentThread());
133 AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream( 133 AudioOutputStream* stream = audio_manager_->MakeAudioOutputStream(
134 params_, output_device_id_, input_device_id_); 134 params_, output_device_id_, input_device_id_);
135 if (!stream) 135 if (!stream)
136 return false; 136 return false;
137 137
138 if (!stream->Open()) { 138 if (!stream->Open()) {
139 stream->Close(); 139 stream->Close();
140 return false; 140 return false;
141 } 141 }
142 142
143 const int stream_id = audio_stream_id_++; 143 const int stream_id = audio_stream_id_++;
144 audio_stream_ids_[stream] = stream_id; 144 audio_stream_ids_[stream] = stream_id;
145 audio_log_->OnCreated( 145 audio_log_->OnCreated(
146 stream_id, params_, input_device_id_, output_device_id_); 146 stream_id, params_, input_device_id_, output_device_id_);
147 147
148 idle_streams_.push_back(stream); 148 idle_streams_.push_back(stream);
149 return true; 149 return true;
150 } 150 }
151 151
152 void AudioOutputDispatcherImpl::CloseAllIdleStreams() { 152 void AudioOutputDispatcherImpl::CloseAllIdleStreams() {
153 DCHECK(message_loop_->BelongsToCurrentThread()); 153 DCHECK(task_runner_->BelongsToCurrentThread());
154 CloseIdleStreams(0); 154 CloseIdleStreams(0);
155 } 155 }
156 156
157 void AudioOutputDispatcherImpl::CloseIdleStreams(size_t keep_alive) { 157 void AudioOutputDispatcherImpl::CloseIdleStreams(size_t keep_alive) {
158 DCHECK(message_loop_->BelongsToCurrentThread()); 158 DCHECK(task_runner_->BelongsToCurrentThread());
159 if (idle_streams_.size() <= keep_alive) 159 if (idle_streams_.size() <= keep_alive)
160 return; 160 return;
161 for (size_t i = keep_alive; i < idle_streams_.size(); ++i) { 161 for (size_t i = keep_alive; i < idle_streams_.size(); ++i) {
162 AudioOutputStream* stream = idle_streams_[i]; 162 AudioOutputStream* stream = idle_streams_[i];
163 stream->Close(); 163 stream->Close();
164 164
165 AudioStreamIDMap::iterator it = audio_stream_ids_.find(stream); 165 AudioStreamIDMap::iterator it = audio_stream_ids_.find(stream);
166 DCHECK(it != audio_stream_ids_.end()); 166 DCHECK(it != audio_stream_ids_.end());
167 audio_log_->OnClosed(it->second); 167 audio_log_->OnClosed(it->second);
168 audio_stream_ids_.erase(it); 168 audio_stream_ids_.erase(it);
169 } 169 }
170 idle_streams_.erase(idle_streams_.begin() + keep_alive, idle_streams_.end()); 170 idle_streams_.erase(idle_streams_.begin() + keep_alive, idle_streams_.end());
171 } 171 }
172 172
173 void AudioOutputDispatcherImpl::CloseStreamsForWedgeFix() { 173 void AudioOutputDispatcherImpl::CloseStreamsForWedgeFix() {
174 DCHECK(message_loop_->BelongsToCurrentThread()); 174 DCHECK(task_runner_->BelongsToCurrentThread());
175 CloseAllIdleStreams(); 175 CloseAllIdleStreams();
176 } 176 }
177 177
178 void AudioOutputDispatcherImpl::RestartStreamsForWedgeFix() { 178 void AudioOutputDispatcherImpl::RestartStreamsForWedgeFix() {
179 DCHECK(message_loop_->BelongsToCurrentThread()); 179 DCHECK(task_runner_->BelongsToCurrentThread());
180 180
181 // Should only be called when the dispatcher is used with fake streams which 181 // Should only be called when the dispatcher is used with fake streams which
182 // don't need to be shutdown or restarted. 182 // don't need to be shutdown or restarted.
183 CHECK_EQ(params_.format(), AudioParameters::AUDIO_FAKE); 183 CHECK_EQ(params_.format(), AudioParameters::AUDIO_FAKE);
184 } 184 }
185 185
186 } // namespace media 186 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_output_dispatcher.cc ('k') | media/audio/audio_output_proxy_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698