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

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: Rebase. Relocate one-time use variables. 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
« no previous file with comments | « media/audio/audio_output_device.h ('k') | no next file » | 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_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 28 matching lines...) Expand all
39 void MapSharedMemory() override; 39 void MapSharedMemory() override;
40 40
41 // Called whenever we receive notifications about pending data. 41 // Called whenever we receive notifications about pending data.
42 void Process(uint32_t pending_data) override; 42 void Process(uint32_t pending_data) override;
43 43
44 // Returns whether the current thread is the audio device thread or not. 44 // Returns whether the current thread is the audio device thread or not.
45 // Will always return true if DCHECKs are not enabled. 45 // Will always return true if DCHECKs are not enabled.
46 bool CurrentThreadIsAudioDeviceThread(); 46 bool CurrentThreadIsAudioDeviceThread();
47 47
48 private: 48 private:
49 const int bytes_per_frame_;
49 AudioRendererSink::RenderCallback* render_callback_; 50 AudioRendererSink::RenderCallback* render_callback_;
50 std::unique_ptr<AudioBus> output_bus_; 51 std::unique_ptr<AudioBus> output_bus_;
51 uint64_t callback_num_; 52 uint64_t callback_num_;
52 53
53 DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback); 54 DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback);
54 }; 55 };
55 56
56 AudioOutputDevice::AudioOutputDevice( 57 AudioOutputDevice::AudioOutputDevice(
57 std::unique_ptr<AudioOutputIPC> ipc, 58 std::unique_ptr<AudioOutputIPC> ipc,
58 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 59 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
(...skipping 29 matching lines...) Expand all
88 } 89 }
89 90
90 void AudioOutputDevice::Initialize(const AudioParameters& params, 91 void AudioOutputDevice::Initialize(const AudioParameters& params,
91 RenderCallback* callback) { 92 RenderCallback* callback) {
92 DCHECK(!callback_) << "Calling Initialize() twice?"; 93 DCHECK(!callback_) << "Calling Initialize() twice?";
93 DCHECK(params.IsValid()); 94 DCHECK(params.IsValid());
94 audio_parameters_ = params; 95 audio_parameters_ = params;
95 callback_ = callback; 96 callback_ = callback;
96 } 97 }
97 98
98 AudioOutputDevice::~AudioOutputDevice() { 99 AudioOutputDevice::~AudioOutputDevice() {}
99 // The current design requires that the user calls Stop() before deleting
100 // this class.
101 DCHECK(audio_thread_.IsStopped());
102 }
103 100
104 void AudioOutputDevice::RequestDeviceAuthorization() { 101 void AudioOutputDevice::RequestDeviceAuthorization() {
105 task_runner()->PostTask( 102 task_runner()->PostTask(
106 FROM_HERE, 103 FROM_HERE,
107 base::Bind(&AudioOutputDevice::RequestDeviceAuthorizationOnIOThread, 104 base::Bind(&AudioOutputDevice::RequestDeviceAuthorizationOnIOThread,
108 this)); 105 this));
109 } 106 }
110 107
111 void AudioOutputDevice::Start() { 108 void AudioOutputDevice::Start() {
112 DCHECK(callback_) << "Initialize hasn't been called"; 109 DCHECK(callback_) << "Initialize hasn't been called";
113 task_runner()->PostTask(FROM_HERE, 110 task_runner()->PostTask(FROM_HERE,
114 base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this, 111 base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this,
115 audio_parameters_)); 112 audio_parameters_));
116 } 113 }
117 114
118 void AudioOutputDevice::Stop() { 115 void AudioOutputDevice::Stop() {
119 { 116 {
120 base::AutoLock auto_lock(audio_thread_lock_); 117 base::AutoLock auto_lock(audio_thread_lock_);
121 audio_thread_.Stop(base::MessageLoop::current()); 118 audio_thread_.reset();
122 stopping_hack_ = true; 119 stopping_hack_ = true;
123 } 120 }
124 121
125 task_runner()->PostTask(FROM_HERE, 122 task_runner()->PostTask(FROM_HERE,
126 base::Bind(&AudioOutputDevice::ShutDownOnIOThread, this)); 123 base::Bind(&AudioOutputDevice::ShutDownOnIOThread, this));
127 } 124 }
128 125
129 void AudioOutputDevice::Play() { 126 void AudioOutputDevice::Play() {
130 task_runner()->PostTask(FROM_HERE, 127 task_runner()->PostTask(FROM_HERE,
131 base::Bind(&AudioOutputDevice::PlayOnIOThread, this)); 128 base::Bind(&AudioOutputDevice::PlayOnIOThread, this));
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // We can run into an issue where ShutDownOnIOThread is called right after 257 // We can run into an issue where ShutDownOnIOThread is called right after
261 // OnStreamCreated is called in cases where Start/Stop are called before we 258 // OnStreamCreated is called in cases where Start/Stop are called before we
262 // get the OnStreamCreated callback. To handle that corner case, we call 259 // get the OnStreamCreated callback. To handle that corner case, we call
263 // Stop(). In most cases, the thread will already be stopped. 260 // Stop(). In most cases, the thread will already be stopped.
264 // 261 //
265 // Another situation is when the IO thread goes away before Stop() is called 262 // Another situation is when the IO thread goes away before Stop() is called
266 // in which case, we cannot use the message loop to close the thread handle 263 // in which case, we cannot use the message loop to close the thread handle
267 // and can't rely on the main thread existing either. 264 // and can't rely on the main thread existing either.
268 base::AutoLock auto_lock_(audio_thread_lock_); 265 base::AutoLock auto_lock_(audio_thread_lock_);
269 base::ThreadRestrictions::ScopedAllowIO allow_io; 266 base::ThreadRestrictions::ScopedAllowIO allow_io;
270 audio_thread_.Stop(NULL); 267 audio_thread_.reset();
271 audio_callback_.reset(); 268 audio_callback_.reset();
272 stopping_hack_ = false; 269 stopping_hack_ = false;
273 } 270 }
274 271
275 void AudioOutputDevice::SetVolumeOnIOThread(double volume) { 272 void AudioOutputDevice::SetVolumeOnIOThread(double volume) {
276 DCHECK(task_runner()->BelongsToCurrentThread()); 273 DCHECK(task_runner()->BelongsToCurrentThread());
277 if (state_ >= CREATING_STREAM) 274 if (state_ >= CREATING_STREAM)
278 ipc_->SetVolume(volume); 275 ipc_->SetVolume(volume);
279 } 276 }
280 277
(...skipping 11 matching lines...) Expand all
292 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PAUSED: 289 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_PAUSED:
293 break; 290 break;
294 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR: 291 case AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR:
295 DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(ERROR)"; 292 DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(ERROR)";
296 // Don't dereference the callback object if the audio thread 293 // Don't dereference the callback object if the audio thread
297 // is stopped or stopping. That could mean that the callback 294 // is stopped or stopping. That could mean that the callback
298 // object has been deleted. 295 // object has been deleted.
299 // TODO(tommi): Add an explicit contract for clearing the callback 296 // TODO(tommi): Add an explicit contract for clearing the callback
300 // object. Possibly require calling Initialize again or provide 297 // object. Possibly require calling Initialize again or provide
301 // a callback object via Start() and clear it in Stop(). 298 // a callback object via Start() and clear it in Stop().
302 if (!audio_thread_.IsStopped()) 299 {
303 callback_->OnRenderError(); 300 base::AutoLock auto_lock_(audio_thread_lock_);
301 if (audio_thread_)
302 callback_->OnRenderError();
303 }
304 break; 304 break;
305 default: 305 default:
306 NOTREACHED(); 306 NOTREACHED();
307 break; 307 break;
308 } 308 }
309 } 309 }
310 310
311 void AudioOutputDevice::OnDeviceAuthorized( 311 void AudioOutputDevice::OnDeviceAuthorized(
312 OutputDeviceStatus device_status, 312 OutputDeviceStatus device_status,
313 const media::AudioParameters& output_params, 313 const media::AudioParameters& output_params,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 // freed memory is a mess. AudioRendererSink should be non-refcounted so that 393 // freed memory is a mess. AudioRendererSink should be non-refcounted so that
394 // owners (WebRtcAudioDeviceImpl, AudioRendererImpl, etc...) can Stop() and 394 // owners (WebRtcAudioDeviceImpl, AudioRendererImpl, etc...) can Stop() and
395 // delete as they see fit. AudioOutputDevice should internally use WeakPtr 395 // delete as they see fit. AudioOutputDevice should internally use WeakPtr
396 // to handle teardown and thread hopping. See http://crbug.com/151051 for 396 // to handle teardown and thread hopping. See http://crbug.com/151051 for
397 // details. 397 // details.
398 { 398 {
399 base::AutoLock auto_lock(audio_thread_lock_); 399 base::AutoLock auto_lock(audio_thread_lock_);
400 if (stopping_hack_) 400 if (stopping_hack_)
401 return; 401 return;
402 402
403 DCHECK(audio_thread_.IsStopped()); 403 DCHECK(!audio_thread_);
404 DCHECK(!audio_callback_);
405
404 audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback( 406 audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback(
405 audio_parameters_, handle, length, callback_)); 407 audio_parameters_, handle, length, callback_));
406 audio_thread_.Start(audio_callback_.get(), socket_handle, 408 audio_thread_.reset(new AudioDeviceThread(
407 "AudioOutputDevice", true); 409 audio_callback_.get(), socket_handle, "AudioOutputDevice"));
408 state_ = PAUSED; 410 state_ = PAUSED;
409 411
410 // We handle the case where Play() and/or Pause() may have been called 412 // We handle the case where Play() and/or Pause() may have been called
411 // multiple times before OnStreamCreated() gets called. 413 // multiple times before OnStreamCreated() gets called.
412 if (play_on_start_) 414 if (play_on_start_)
413 PlayOnIOThread(); 415 PlayOnIOThread();
414 } 416 }
415 } 417 }
416 418
417 void AudioOutputDevice::OnIPCClosed() { 419 void AudioOutputDevice::OnIPCClosed() {
(...skipping 11 matching lines...) Expand all
429 } 431 }
430 432
431 // AudioOutputDevice::AudioThreadCallback 433 // AudioOutputDevice::AudioThreadCallback
432 434
433 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback( 435 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback(
434 const AudioParameters& audio_parameters, 436 const AudioParameters& audio_parameters,
435 base::SharedMemoryHandle memory, 437 base::SharedMemoryHandle memory,
436 int memory_length, 438 int memory_length,
437 AudioRendererSink::RenderCallback* render_callback) 439 AudioRendererSink::RenderCallback* render_callback)
438 : AudioDeviceThread::Callback(audio_parameters, memory, memory_length, 1), 440 : AudioDeviceThread::Callback(audio_parameters, memory, memory_length, 1),
441 bytes_per_frame_(audio_parameters.GetBytesPerFrame()),
439 render_callback_(render_callback), 442 render_callback_(render_callback),
440 callback_num_(0) {} 443 callback_num_(0) {}
441 444
442 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() { 445 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() {
443 } 446 }
444 447
445 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() { 448 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
446 CHECK_EQ(total_segments_, 1); 449 CHECK_EQ(total_segments_, 1);
447 CHECK(shared_memory_.Map(memory_length_)); 450 CHECK(shared_memory_.Map(memory_length_));
448 DCHECK_EQ(static_cast<size_t>(memory_length_), 451 DCHECK_EQ(static_cast<size_t>(memory_length_),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 render_callback_->Render(output_bus_.get(), std::round(frames_delayed), 490 render_callback_->Render(output_bus_.get(), std::round(frames_delayed),
488 frames_skipped); 491 frames_skipped);
489 } 492 }
490 493
491 bool AudioOutputDevice::AudioThreadCallback:: 494 bool AudioOutputDevice::AudioThreadCallback::
492 CurrentThreadIsAudioDeviceThread() { 495 CurrentThreadIsAudioDeviceThread() {
493 return thread_checker_.CalledOnValidThread(); 496 return thread_checker_.CalledOnValidThread();
494 } 497 }
495 498
496 } // namespace media 499 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_output_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698