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

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

Issue 2076793002: Cleanup AudioDeviceThread to reduce locking and unused features. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
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_device.h" 5 #include "media/audio/audio_output_device.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <cmath> 10 #include <cmath>
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 84 }
85 85
86 void AudioOutputDevice::Initialize(const AudioParameters& params, 86 void AudioOutputDevice::Initialize(const AudioParameters& params,
87 RenderCallback* callback) { 87 RenderCallback* callback) {
88 DCHECK(!callback_) << "Calling Initialize() twice?"; 88 DCHECK(!callback_) << "Calling Initialize() twice?";
89 DCHECK(params.IsValid()); 89 DCHECK(params.IsValid());
90 audio_parameters_ = params; 90 audio_parameters_ = params;
91 callback_ = callback; 91 callback_ = callback;
92 } 92 }
93 93
94 AudioOutputDevice::~AudioOutputDevice() { 94 AudioOutputDevice::~AudioOutputDevice() {}
95 // The current design requires that the user calls Stop() before deleting
96 // this class.
97 DCHECK(audio_thread_.IsStopped());
98 }
99 95
100 void AudioOutputDevice::RequestDeviceAuthorization() { 96 void AudioOutputDevice::RequestDeviceAuthorization() {
101 task_runner()->PostTask( 97 task_runner()->PostTask(
102 FROM_HERE, 98 FROM_HERE,
103 base::Bind(&AudioOutputDevice::RequestDeviceAuthorizationOnIOThread, 99 base::Bind(&AudioOutputDevice::RequestDeviceAuthorizationOnIOThread,
104 this)); 100 this));
105 } 101 }
106 102
107 void AudioOutputDevice::Start() { 103 void AudioOutputDevice::Start() {
108 DCHECK(callback_) << "Initialize hasn't been called"; 104 DCHECK(callback_) << "Initialize hasn't been called";
109 task_runner()->PostTask(FROM_HERE, 105 task_runner()->PostTask(FROM_HERE,
110 base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this, 106 base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this,
111 audio_parameters_)); 107 audio_parameters_));
112 } 108 }
113 109
114 void AudioOutputDevice::Stop() { 110 void AudioOutputDevice::Stop() {
115 { 111 {
116 base::AutoLock auto_lock(audio_thread_lock_); 112 base::AutoLock auto_lock(audio_thread_lock_);
117 audio_thread_.Stop(base::MessageLoop::current()); 113 audio_thread_.reset();
118 stopping_hack_ = true; 114 stopping_hack_ = true;
119 } 115 }
120 116
121 task_runner()->PostTask(FROM_HERE, 117 task_runner()->PostTask(FROM_HERE,
122 base::Bind(&AudioOutputDevice::ShutDownOnIOThread, this)); 118 base::Bind(&AudioOutputDevice::ShutDownOnIOThread, this));
123 } 119 }
124 120
125 void AudioOutputDevice::Play() { 121 void AudioOutputDevice::Play() {
126 task_runner()->PostTask(FROM_HERE, 122 task_runner()->PostTask(FROM_HERE,
127 base::Bind(&AudioOutputDevice::PlayOnIOThread, this)); 123 base::Bind(&AudioOutputDevice::PlayOnIOThread, this));
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 // We can run into an issue where ShutDownOnIOThread is called right after 245 // We can run into an issue where ShutDownOnIOThread is called right after
250 // OnStreamCreated is called in cases where Start/Stop are called before we 246 // OnStreamCreated is called in cases where Start/Stop are called before we
251 // get the OnStreamCreated callback. To handle that corner case, we call 247 // get the OnStreamCreated callback. To handle that corner case, we call
252 // Stop(). In most cases, the thread will already be stopped. 248 // Stop(). In most cases, the thread will already be stopped.
253 // 249 //
254 // Another situation is when the IO thread goes away before Stop() is called 250 // Another situation is when the IO thread goes away before Stop() is called
255 // in which case, we cannot use the message loop to close the thread handle 251 // in which case, we cannot use the message loop to close the thread handle
256 // and can't rely on the main thread existing either. 252 // and can't rely on the main thread existing either.
257 base::AutoLock auto_lock_(audio_thread_lock_); 253 base::AutoLock auto_lock_(audio_thread_lock_);
258 base::ThreadRestrictions::ScopedAllowIO allow_io; 254 base::ThreadRestrictions::ScopedAllowIO allow_io;
259 audio_thread_.Stop(NULL); 255 audio_thread_.reset();
260 audio_callback_.reset(); 256 audio_callback_.reset();
261 stopping_hack_ = false; 257 stopping_hack_ = false;
262 } 258 }
263 259
264 void AudioOutputDevice::SetVolumeOnIOThread(double volume) { 260 void AudioOutputDevice::SetVolumeOnIOThread(double volume) {
265 DCHECK(task_runner()->BelongsToCurrentThread()); 261 DCHECK(task_runner()->BelongsToCurrentThread());
266 if (state_ >= CREATING_STREAM) 262 if (state_ >= CREATING_STREAM)
267 ipc_->SetVolume(volume); 263 ipc_->SetVolume(volume);
268 } 264 }
269 265
(...skipping 11 matching lines...) Expand all
281 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PAUSED: 277 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PAUSED:
282 break; 278 break;
283 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR: 279 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR:
284 DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(ERROR)"; 280 DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(ERROR)";
285 // Don't dereference the callback object if the audio thread 281 // Don't dereference the callback object if the audio thread
286 // is stopped or stopping. That could mean that the callback 282 // is stopped or stopping. That could mean that the callback
287 // object has been deleted. 283 // object has been deleted.
288 // TODO(tommi): Add an explicit contract for clearing the callback 284 // TODO(tommi): Add an explicit contract for clearing the callback
289 // object. Possibly require calling Initialize again or provide 285 // object. Possibly require calling Initialize again or provide
290 // a callback object via Start() and clear it in Stop(). 286 // a callback object via Start() and clear it in Stop().
291 if (!audio_thread_.IsStopped()) 287 {
292 callback_->OnRenderError(); 288 base::AutoLock auto_lock_(audio_thread_lock_);
289 if (audio_thread_)
290 callback_->OnRenderError();
291 }
293 break; 292 break;
294 default: 293 default:
295 NOTREACHED(); 294 NOTREACHED();
296 break; 295 break;
297 } 296 }
298 } 297 }
299 298
300 void AudioOutputDevice::OnDeviceAuthorized( 299 void AudioOutputDevice::OnDeviceAuthorized(
301 OutputDeviceStatus device_status, 300 OutputDeviceStatus device_status,
302 const media::AudioParameters& output_params, 301 const media::AudioParameters& output_params,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 // freed memory is a mess. AudioRendererSink should be non-refcounted so that 381 // freed memory is a mess. AudioRendererSink should be non-refcounted so that
383 // owners (WebRtcAudioDeviceImpl, AudioRendererImpl, etc...) can Stop() and 382 // owners (WebRtcAudioDeviceImpl, AudioRendererImpl, etc...) can Stop() and
384 // delete as they see fit. AudioOutputDevice should internally use WeakPtr 383 // delete as they see fit. AudioOutputDevice should internally use WeakPtr
385 // to handle teardown and thread hopping. See http://crbug.com/151051 for 384 // to handle teardown and thread hopping. See http://crbug.com/151051 for
386 // details. 385 // details.
387 { 386 {
388 base::AutoLock auto_lock(audio_thread_lock_); 387 base::AutoLock auto_lock(audio_thread_lock_);
389 if (stopping_hack_) 388 if (stopping_hack_)
390 return; 389 return;
391 390
392 DCHECK(audio_thread_.IsStopped()); 391 DCHECK(!audio_thread_);
392 DCHECK(!audio_callback_);
393
393 audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback( 394 audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback(
394 audio_parameters_, handle, length, callback_)); 395 audio_parameters_, handle, length, callback_));
395 audio_thread_.Start(audio_callback_.get(), socket_handle, 396 audio_thread_.reset(new AudioDeviceThread(
396 "AudioOutputDevice", true); 397 audio_callback_.get(), socket_handle, "AudioOutputDevice"));
397 state_ = PAUSED; 398 state_ = PAUSED;
398 399
399 // We handle the case where Play() and/or Pause() may have been called 400 // We handle the case where Play() and/or Pause() may have been called
400 // multiple times before OnStreamCreated() gets called. 401 // multiple times before OnStreamCreated() gets called.
401 if (play_on_start_) 402 if (play_on_start_)
402 PlayOnIOThread(); 403 PlayOnIOThread();
403 } 404 }
404 } 405 }
405 406
406 void AudioOutputDevice::OnIPCClosed() { 407 void AudioOutputDevice::OnIPCClosed() {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 472
472 // Update the audio-delay measurement, inform about the number of skipped 473 // Update the audio-delay measurement, inform about the number of skipped
473 // frames, and ask client to render audio. Since |output_bus_| is wrapping 474 // frames, and ask client to render audio. Since |output_bus_| is wrapping
474 // the shared memory the Render() call is writing directly into the shared 475 // the shared memory the Render() call is writing directly into the shared
475 // memory. 476 // memory.
476 render_callback_->Render(output_bus_.get(), std::round(frames_delayed), 477 render_callback_->Render(output_bus_.get(), std::round(frames_delayed),
477 frames_skipped); 478 frames_skipped);
478 } 479 }
479 480
480 } // namespace media 481 } // namespace media
OLDNEW
« media/audio/audio_input_device.cc ('K') | « media/audio/audio_output_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698