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

Side by Side Diff: content/renderer/media/audio_device.h

Issue 9104043: Monitor the IO message loop in the AudioDevice classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: doh! Created 8 years, 10 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 | « no previous file | content/renderer/media/audio_device.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 // Low-latency audio rendering unit utilizing audio output stream provided 5 // Low-latency audio rendering unit utilizing audio output stream provided
6 // by browser process through IPC. 6 // by browser process through IPC.
7 // 7 //
8 // Relationship of classes. 8 // Relationship of classes.
9 // 9 //
10 // AudioOutputController AudioDevice 10 // AudioOutputController AudioDevice
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // - Pause() is asynchronous/non-blocking. 59 // - Pause() is asynchronous/non-blocking.
60 // - The user must call Stop() before deleting the class instance. 60 // - The user must call Stop() before deleting the class instance.
61 61
62 #ifndef CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_H_ 62 #ifndef CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_H_
63 #define CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_H_ 63 #define CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_H_
64 #pragma once 64 #pragma once
65 65
66 #include <vector> 66 #include <vector>
67 67
68 #include "base/basictypes.h" 68 #include "base/basictypes.h"
69 #include "base/bind.h"
69 #include "base/memory/scoped_ptr.h" 70 #include "base/memory/scoped_ptr.h"
71 #include "base/message_loop.h"
70 #include "base/shared_memory.h" 72 #include "base/shared_memory.h"
71 #include "base/synchronization/lock.h" 73 #include "base/synchronization/lock.h"
72 #include "base/threading/simple_thread.h" 74 #include "base/threading/simple_thread.h"
73 #include "content/common/content_export.h" 75 #include "content/common/content_export.h"
74 #include "content/renderer/media/audio_message_filter.h" 76 #include "content/renderer/media/audio_message_filter.h"
75 #include "media/audio/audio_parameters.h" 77 #include "media/audio/audio_parameters.h"
76 #include "media/base/audio_renderer_sink.h" 78 #include "media/base/audio_renderer_sink.h"
77 79
78 namespace base { 80 // A common base class for AudioDevice and AudioInputDevice that manages
scherkus (not reviewing) 2012/02/04 00:27:46 seeing as this is common code perhaps move to sepa
tommi (sloooow) - chröme 2012/02/06 13:38:56 Done.
79 class WaitableEvent; 81 // the IO message loop pointer and monitors it for destruction.
80 } 82 // When the loop goes away, we automatically stop any running streams.
83 template <class T>
84 class AudioDeviceIOLoopObserver
85 : public MessageLoop::DestructionObserver {
86 public:
87 explicit AudioDeviceIOLoopObserver(MessageLoop* io_loop)
88 : io_loop_(io_loop->message_loop_proxy()) {
89 // Watch the IO loop and make sure that we stop the audio thread before we
90 // lose the IO thread.
91 ObserveIOLoopDestruction(true, NULL);
92 }
93
94 ~AudioDeviceIOLoopObserver() {
scherkus (not reviewing) 2012/02/04 00:27:46 virtual
tommi (sloooow) - chröme 2012/02/06 13:38:56 Done.
95 ObserveIOLoopDestruction(false, NULL);
96 }
97
98 protected:
99 // Accessor to the IO loop that's used by the derived class.
100 base::MessageLoopProxy* loop() { return io_loop_; }
scherkus (not reviewing) 2012/02/04 00:27:46 nit: what about io_message_loop()? Audio{Input}De
tommi (sloooow) - chröme 2012/02/06 13:38:56 I changed it to message_loop() in the end. The re
101
102 private:
103 // MessageLoop::DestructionObserver implementation.
104 // Called on the IO thread when the thread is going away.
105 virtual void WillDestroyCurrentMessageLoop() OVERRIDE {
106 DCHECK(io_loop_->BelongsToCurrentThread());
107 // The IO thread is terminating. We must stop the audio thread before the
108 // IO thread goes away.
109 static_cast<T*>(this)->ShutDownOnIOThread(NULL);
scherkus (not reviewing) 2012/02/04 00:27:46 ISTM the only reason this class is templated is fo
tommi (sloooow) - chröme 2012/02/06 13:38:56 Done.
110 }
111
112 // Call from the IO thread to add or remove ourselves from the list of
113 // destruction observers for the IO message loop.
114 void ObserveIOLoopDestruction(bool enable, base::WaitableEvent* done) {
scherkus (not reviewing) 2012/02/04 00:27:46 nit: what about splitting this method into AddDest
tommi (sloooow) - chröme 2012/02/06 13:38:56 The function is still as it was because it does ba
115 if (io_loop_->BelongsToCurrentThread()) {
116 MessageLoop* loop = MessageLoop::current();
117 if (enable) {
118 loop->AddDestructionObserver(this);
119 } else {
120 loop->RemoveDestructionObserver(this);
121 }
122 } else {
123 base::WaitableEvent event(false, false);
124 if (io_loop_->PostTask(FROM_HERE,
125 base::Bind(
126 &AudioDeviceIOLoopObserver<T>::ObserveIOLoopDestruction,
127 base::Unretained(this), enable, &event))) {
128 event.Wait();
129 } else {
130 // The IO thread has already terminated, so no need to wait.
131 }
132 }
133
134 if (done)
135 done->Signal();
136 }
137
138 // A pointer to the IO thread's message loop. That's here we do control the
139 // stream from. It is possible during shutdown that the IO thread has gone
140 // away before the user of the AudioDevice instance has called Stop().
141 // So, we need to be prepared to stop and take down the audio thread if
142 // the IO thread ever goes away while we're still playing.
143 // So, when this pointer is NULL, the IO thread has gone away and all methods
144 // that post to it, must check for this first.
145 scoped_refptr<base::MessageLoopProxy> io_loop_;
146 };
scherkus (not reviewing) 2012/02/04 00:27:46 DISALLOW_ etc
tommi (sloooow) - chröme 2012/02/06 13:38:56 Done.
81 147
82 class CONTENT_EXPORT AudioDevice 148 class CONTENT_EXPORT AudioDevice
83 : NON_EXPORTED_BASE(public media::AudioRendererSink), 149 : NON_EXPORTED_BASE(public media::AudioRendererSink),
84 public AudioMessageFilter::Delegate, 150 public AudioMessageFilter::Delegate,
85 public base::DelegateSimpleThread::Delegate { 151 public base::DelegateSimpleThread::Delegate,
152 public AudioDeviceIOLoopObserver<AudioDevice> {
86 public: 153 public:
87 // Methods called on main render thread ------------------------------------- 154 // Methods called on main render thread -------------------------------------
88 155
89 // Minimal constructor where Initialize() must be called later. 156 // Minimal constructor where Initialize() must be called later.
90 AudioDevice(); 157 AudioDevice();
91 158
92 AudioDevice(size_t buffer_size, 159 AudioDevice(size_t buffer_size,
93 int channels, 160 int channels,
94 double sample_rate, 161 double sample_rate,
95 RenderCallback* callback); 162 RenderCallback* callback);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 friend class base::RefCountedThreadSafe<AudioDevice>; 214 friend class base::RefCountedThreadSafe<AudioDevice>;
148 virtual ~AudioDevice(); 215 virtual ~AudioDevice();
149 216
150 // Methods called on IO thread ---------------------------------------------- 217 // Methods called on IO thread ----------------------------------------------
151 // The following methods are tasks posted on the IO thread that needs to 218 // The following methods are tasks posted on the IO thread that needs to
152 // be executed on that thread. They interact with AudioMessageFilter and 219 // be executed on that thread. They interact with AudioMessageFilter and
153 // sends IPC messages on that thread. 220 // sends IPC messages on that thread.
154 void InitializeOnIOThread(const AudioParameters& params); 221 void InitializeOnIOThread(const AudioParameters& params);
155 void PlayOnIOThread(); 222 void PlayOnIOThread();
156 void PauseOnIOThread(bool flush); 223 void PauseOnIOThread(bool flush);
224 // Allow AudioDeviceIOLoopObserver to call ShutDownOnIOThread.
225 friend class AudioDeviceIOLoopObserver<AudioDevice>;
157 void ShutDownOnIOThread(base::WaitableEvent* signal); 226 void ShutDownOnIOThread(base::WaitableEvent* signal);
158 void SetVolumeOnIOThread(double volume); 227 void SetVolumeOnIOThread(double volume);
159 228
160 void Send(IPC::Message* message); 229 void Send(IPC::Message* message);
161 230
162 // Method called on the audio thread ---------------------------------------- 231 // Method called on the audio thread ----------------------------------------
163 // Calls the client's callback for rendering audio. 232 // Calls the client's callback for rendering audio.
164 // Returns actual number of filled frames that callback returned. This length 233 // Returns actual number of filled frames that callback returned. This length
165 // is passed to host at the end of the shared memory (i.e. buffer). In case of 234 // is passed to host at the end of the shared memory (i.e. buffer). In case of
166 // continuous stream host just ignores it and assumes buffer is always filled 235 // continuous stream host just ignores it and assumes buffer is always filled
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 // These variables must only be set on the IO thread while the audio_thread_ 290 // These variables must only be set on the IO thread while the audio_thread_
222 // is not running. 291 // is not running.
223 base::SharedMemoryHandle shared_memory_handle_; 292 base::SharedMemoryHandle shared_memory_handle_;
224 scoped_ptr<base::CancelableSyncSocket> audio_socket_; 293 scoped_ptr<base::CancelableSyncSocket> audio_socket_;
225 int memory_length_; 294 int memory_length_;
226 295
227 DISALLOW_COPY_AND_ASSIGN(AudioDevice); 296 DISALLOW_COPY_AND_ASSIGN(AudioDevice);
228 }; 297 };
229 298
230 #endif // CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_H_ 299 #endif // CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_H_
OLDNEW
« no previous file with comments | « no previous file | content/renderer/media/audio_device.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698