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

Side by Side Diff: media/audio/audio_output_resampler.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_proxy_unittest.cc ('k') | media/audio/clockless_audio_sink.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) 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_resampler.h" 5 #include "media/audio/audio_output_resampler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/time/time.h" 12 #include "base/time/time.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "media/audio/audio_io.h" 14 #include "media/audio/audio_io.h"
15 #include "media/audio/audio_output_dispatcher_impl.h" 15 #include "media/audio/audio_output_dispatcher_impl.h"
16 #include "media/audio/audio_output_proxy.h" 16 #include "media/audio/audio_output_proxy.h"
17 #include "media/audio/sample_rates.h" 17 #include "media/audio/sample_rates.h"
18 #include "media/base/audio_converter.h" 18 #include "media/base/audio_converter.h"
19 #include "media/base/limits.h" 19 #include "media/base/limits.h"
20 20
21 namespace media { 21 namespace media {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 167
168 void AudioOutputResampler::Initialize() { 168 void AudioOutputResampler::Initialize() {
169 DCHECK(!streams_opened_); 169 DCHECK(!streams_opened_);
170 DCHECK(callbacks_.empty()); 170 DCHECK(callbacks_.empty());
171 dispatcher_ = new AudioOutputDispatcherImpl( 171 dispatcher_ = new AudioOutputDispatcherImpl(
172 audio_manager_, output_params_, output_device_id_, input_device_id_, 172 audio_manager_, output_params_, output_device_id_, input_device_id_,
173 close_delay_); 173 close_delay_);
174 } 174 }
175 175
176 bool AudioOutputResampler::OpenStream() { 176 bool AudioOutputResampler::OpenStream() {
177 DCHECK(message_loop_->BelongsToCurrentThread()); 177 DCHECK(task_runner_->BelongsToCurrentThread());
178 178
179 if (dispatcher_->OpenStream()) { 179 if (dispatcher_->OpenStream()) {
180 // Only record the UMA statistic if we didn't fallback during construction 180 // Only record the UMA statistic if we didn't fallback during construction
181 // and only for the first stream we open. 181 // and only for the first stream we open.
182 if (!streams_opened_ && 182 if (!streams_opened_ &&
183 output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { 183 output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
184 UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false); 184 UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false);
185 } 185 }
186 streams_opened_ = true; 186 streams_opened_ = true;
187 return true; 187 return true;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 streams_opened_ = true; 226 streams_opened_ = true;
227 return true; 227 return true;
228 } 228 }
229 229
230 return false; 230 return false;
231 } 231 }
232 232
233 bool AudioOutputResampler::StartStream( 233 bool AudioOutputResampler::StartStream(
234 AudioOutputStream::AudioSourceCallback* callback, 234 AudioOutputStream::AudioSourceCallback* callback,
235 AudioOutputProxy* stream_proxy) { 235 AudioOutputProxy* stream_proxy) {
236 DCHECK(message_loop_->BelongsToCurrentThread()); 236 DCHECK(task_runner_->BelongsToCurrentThread());
237 237
238 OnMoreDataConverter* resampler_callback = NULL; 238 OnMoreDataConverter* resampler_callback = NULL;
239 CallbackMap::iterator it = callbacks_.find(stream_proxy); 239 CallbackMap::iterator it = callbacks_.find(stream_proxy);
240 if (it == callbacks_.end()) { 240 if (it == callbacks_.end()) {
241 resampler_callback = new OnMoreDataConverter(params_, output_params_); 241 resampler_callback = new OnMoreDataConverter(params_, output_params_);
242 callbacks_[stream_proxy] = resampler_callback; 242 callbacks_[stream_proxy] = resampler_callback;
243 } else { 243 } else {
244 resampler_callback = it->second; 244 resampler_callback = it->second;
245 } 245 }
246 246
247 resampler_callback->Start(callback); 247 resampler_callback->Start(callback);
248 bool result = dispatcher_->StartStream(resampler_callback, stream_proxy); 248 bool result = dispatcher_->StartStream(resampler_callback, stream_proxy);
249 if (!result) 249 if (!result)
250 resampler_callback->Stop(); 250 resampler_callback->Stop();
251 return result; 251 return result;
252 } 252 }
253 253
254 void AudioOutputResampler::StreamVolumeSet(AudioOutputProxy* stream_proxy, 254 void AudioOutputResampler::StreamVolumeSet(AudioOutputProxy* stream_proxy,
255 double volume) { 255 double volume) {
256 DCHECK(message_loop_->BelongsToCurrentThread()); 256 DCHECK(task_runner_->BelongsToCurrentThread());
257 dispatcher_->StreamVolumeSet(stream_proxy, volume); 257 dispatcher_->StreamVolumeSet(stream_proxy, volume);
258 } 258 }
259 259
260 void AudioOutputResampler::StopStream(AudioOutputProxy* stream_proxy) { 260 void AudioOutputResampler::StopStream(AudioOutputProxy* stream_proxy) {
261 DCHECK(message_loop_->BelongsToCurrentThread()); 261 DCHECK(task_runner_->BelongsToCurrentThread());
262 dispatcher_->StopStream(stream_proxy); 262 dispatcher_->StopStream(stream_proxy);
263 263
264 // Now that StopStream() has completed the underlying physical stream should 264 // Now that StopStream() has completed the underlying physical stream should
265 // be stopped and no longer calling OnMoreData(), making it safe to Stop() the 265 // be stopped and no longer calling OnMoreData(), making it safe to Stop() the
266 // OnMoreDataConverter. 266 // OnMoreDataConverter.
267 CallbackMap::iterator it = callbacks_.find(stream_proxy); 267 CallbackMap::iterator it = callbacks_.find(stream_proxy);
268 if (it != callbacks_.end()) 268 if (it != callbacks_.end())
269 it->second->Stop(); 269 it->second->Stop();
270 } 270 }
271 271
272 void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) { 272 void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) {
273 DCHECK(message_loop_->BelongsToCurrentThread()); 273 DCHECK(task_runner_->BelongsToCurrentThread());
274 dispatcher_->CloseStream(stream_proxy); 274 dispatcher_->CloseStream(stream_proxy);
275 275
276 // We assume that StopStream() is always called prior to CloseStream(), so 276 // We assume that StopStream() is always called prior to CloseStream(), so
277 // that it is safe to delete the OnMoreDataConverter here. 277 // that it is safe to delete the OnMoreDataConverter here.
278 CallbackMap::iterator it = callbacks_.find(stream_proxy); 278 CallbackMap::iterator it = callbacks_.find(stream_proxy);
279 if (it != callbacks_.end()) { 279 if (it != callbacks_.end()) {
280 delete it->second; 280 delete it->second;
281 callbacks_.erase(it); 281 callbacks_.erase(it);
282 } 282 }
283 } 283 }
284 284
285 void AudioOutputResampler::Shutdown() { 285 void AudioOutputResampler::Shutdown() {
286 DCHECK(message_loop_->BelongsToCurrentThread()); 286 DCHECK(task_runner_->BelongsToCurrentThread());
287 287
288 // No AudioOutputProxy objects should hold a reference to us when we get 288 // No AudioOutputProxy objects should hold a reference to us when we get
289 // to this stage. 289 // to this stage.
290 DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference"; 290 DCHECK(HasOneRef()) << "Only the AudioManager should hold a reference";
291 291
292 dispatcher_->Shutdown(); 292 dispatcher_->Shutdown();
293 DCHECK(callbacks_.empty()); 293 DCHECK(callbacks_.empty());
294 } 294 }
295 295
296 void AudioOutputResampler::CloseStreamsForWedgeFix() { 296 void AudioOutputResampler::CloseStreamsForWedgeFix() {
297 DCHECK(message_loop_->BelongsToCurrentThread()); 297 DCHECK(task_runner_->BelongsToCurrentThread());
298 298
299 // Stop and close all active streams. Once all streams across all dispatchers 299 // Stop and close all active streams. Once all streams across all dispatchers
300 // have been closed the AudioManager will call RestartStreamsForWedgeFix(). 300 // have been closed the AudioManager will call RestartStreamsForWedgeFix().
301 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); 301 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end();
302 ++it) { 302 ++it) {
303 if (it->second->started()) 303 if (it->second->started())
304 dispatcher_->StopStream(it->first); 304 dispatcher_->StopStream(it->first);
305 dispatcher_->CloseStream(it->first); 305 dispatcher_->CloseStream(it->first);
306 } 306 }
307 307
308 // Close all idle streams as well. 308 // Close all idle streams as well.
309 dispatcher_->CloseStreamsForWedgeFix(); 309 dispatcher_->CloseStreamsForWedgeFix();
310 } 310 }
311 311
312 void AudioOutputResampler::RestartStreamsForWedgeFix() { 312 void AudioOutputResampler::RestartStreamsForWedgeFix() {
313 DCHECK(message_loop_->BelongsToCurrentThread()); 313 DCHECK(task_runner_->BelongsToCurrentThread());
314 // By opening all streams first and then starting them one by one we ensure 314 // By opening all streams first and then starting them one by one we ensure
315 // the dispatcher only opens streams for those which will actually be used. 315 // the dispatcher only opens streams for those which will actually be used.
316 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); 316 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end();
317 ++it) { 317 ++it) {
318 dispatcher_->OpenStream(); 318 dispatcher_->OpenStream();
319 } 319 }
320 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end(); 320 for (CallbackMap::iterator it = callbacks_.begin(); it != callbacks_.end();
321 ++it) { 321 ++it) {
322 if (it->second->started()) 322 if (it->second->started())
323 dispatcher_->StartStream(it->second, it->first); 323 dispatcher_->StartStream(it->second, it->first);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 if (frames > 0 && frames < dest->frames()) 394 if (frames > 0 && frames < dest->frames())
395 dest->ZeroFramesPartial(frames, dest->frames() - frames); 395 dest->ZeroFramesPartial(frames, dest->frames() - frames);
396 return frames > 0 ? 1 : 0; 396 return frames > 0 ? 1 : 0;
397 } 397 }
398 398
399 void OnMoreDataConverter::OnError(AudioOutputStream* stream) { 399 void OnMoreDataConverter::OnError(AudioOutputStream* stream) {
400 source_callback_->OnError(stream); 400 source_callback_->OnError(stream);
401 } 401 }
402 402
403 } // namespace media 403 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_output_proxy_unittest.cc ('k') | media/audio/clockless_audio_sink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698