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

Side by Side Diff: media/audio/win/audio_low_latency_output_win.h

Issue 10575017: Adding experimental exclusive-mode streaming to WASAPIAudioOutputStream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Changes based on review from Andrew Created 8 years, 4 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
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 // Implementation of AudioOutputStream for Windows using Windows Core Audio 5 // Implementation of AudioOutputStream for Windows using Windows Core Audio
6 // WASAPI for low latency rendering. 6 // WASAPI for low latency rendering.
7 // 7 //
8 // Overview of operation and performance: 8 // Overview of operation and performance:
9 // 9 //
10 // - An object of WASAPIAudioOutputStream is created by the AudioManager 10 // - An object of WASAPIAudioOutputStream is created by the AudioManager
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // by the AudioManager. 105 // by the AudioManager.
106 // - It is a requirement to call the following methods on the same audio 106 // - It is a requirement to call the following methods on the same audio
107 // thread: Open(), Start(), Stop(), and Close(). 107 // thread: Open(), Start(), Stop(), and Close().
108 // - Audio rendering is performed on the audio render thread, owned by this 108 // - Audio rendering is performed on the audio render thread, owned by this
109 // class, and the AudioSourceCallback::OnMoreData() method will be called 109 // class, and the AudioSourceCallback::OnMoreData() method will be called
110 // from this thread. Stream switching also takes place on the audio-render 110 // from this thread. Stream switching also takes place on the audio-render
111 // thread. 111 // thread.
112 // - All callback methods from the IMMNotificationClient interface will be 112 // - All callback methods from the IMMNotificationClient interface will be
113 // called on a Windows-internal MMDevice thread. 113 // called on a Windows-internal MMDevice thread.
114 // 114 //
115 // Experimental exclusive mode (DO NOT USE IN PRODUCTION CODE):
116 //
117 // - It is possible to open up a stream in exclusive mode by using the
118 // "--enable-exclusive-mode" command-line flag.
119 // - The internal buffering scheme is less flexible for exclusive-mode streams.
120 // Hence, some manual tuning will be required before deciding what frame
121 // size to use. See the WinAudioOutputTest unit test for more details.
122 // - If an application opens a stream in exclusive mode, the application has
123 // exclusive use of the audio endpoint device that plays the stream.
124 // - Exclusive-mode access to an audio device can block crucial system sounds,
tommi (sloooow) - chröme 2012/07/25 11:49:40 s/can/will (correct?) you can also leave out 'cruc
henrika (OOO until Aug 14) 2012/07/25 15:26:30 Done.
125 // prevent interoperability with other applications, and otherwise degrade
126 // the user experience.
127 // - Exclusive-mode should only be utilized when the lowest possible latency
128 // is important.
129 // - In exclusive mode, the client can choose to open the stream in any audio
130 // format that the endpoint device supports.
131 // - Initial measurements on Windows 7 have shown that the lowest possible
132 // latencies we can achieve are:
133 // o ~3.3333ms @ 48kHz <=> 160 audio frames per buffer.
134 // o ~3.6281ms @ 44.1kHz <=> 160 audio frames per buffer.
135 // - See msdn.microsoft.com/en-us/library/windows/desktop/dd370844(v=vs.85).aspx
136 // for more details.
137
115 #ifndef MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ 138 #ifndef MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_
116 #define MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ 139 #define MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_
117 140
118 #include <Audioclient.h> 141 #include <Audioclient.h>
119 #include <audiopolicy.h> 142 #include <audiopolicy.h>
120 #include <MMDeviceAPI.h> 143 #include <MMDeviceAPI.h>
121 144
122 #include <string> 145 #include <string>
123 146
124 #include "base/compiler_specific.h" 147 #include "base/compiler_specific.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 // Implementation of AudioOutputStream. 179 // Implementation of AudioOutputStream.
157 virtual bool Open() OVERRIDE; 180 virtual bool Open() OVERRIDE;
158 virtual void Start(AudioSourceCallback* callback) OVERRIDE; 181 virtual void Start(AudioSourceCallback* callback) OVERRIDE;
159 virtual void Stop() OVERRIDE; 182 virtual void Stop() OVERRIDE;
160 virtual void Close() OVERRIDE; 183 virtual void Close() OVERRIDE;
161 virtual void SetVolume(double volume) OVERRIDE; 184 virtual void SetVolume(double volume) OVERRIDE;
162 virtual void GetVolume(double* volume) OVERRIDE; 185 virtual void GetVolume(double* volume) OVERRIDE;
163 186
164 // Retrieves the stream format that the audio engine uses for its internal 187 // Retrieves the stream format that the audio engine uses for its internal
165 // processing/mixing of shared-mode streams. 188 // processing/mixing of shared-mode streams.
189 // This method should not be used in combination with exclusive-mode streams.
166 static int HardwareSampleRate(ERole device_role); 190 static int HardwareSampleRate(ERole device_role);
167 191
168 bool started() const { return started_; } 192 bool started() const { return started_; }
169 193
170 private: 194 private:
195 // Returns AUDCLNT_SHAREMODE_EXCLUSIVE if "enable-exclusive-mode" is used
tommi (sloooow) - chröme 2012/07/25 11:49:40 fix indent
henrika (OOO until Aug 14) 2012/07/25 15:26:30 Done.
196 // as command-line flag and AUDCLNT_SHAREMODE_SHARED otherwise (default).
197 static AUDCLNT_SHAREMODE GetShareMode();
198
171 // Implementation of IUnknown (trivial in this case). See 199 // Implementation of IUnknown (trivial in this case). See
172 // msdn.microsoft.com/en-us/library/windows/desktop/dd371403(v=vs.85).aspx 200 // msdn.microsoft.com/en-us/library/windows/desktop/dd371403(v=vs.85).aspx
173 // for details regarding why proper implementations of AddRef(), Release() 201 // for details regarding why proper implementations of AddRef(), Release()
174 // and QueryInterface() are not needed here. 202 // and QueryInterface() are not needed here.
175 STDMETHOD_(ULONG, AddRef)(); 203 STDMETHOD_(ULONG, AddRef)();
176 STDMETHOD_(ULONG, Release)(); 204 STDMETHOD_(ULONG, Release)();
177 STDMETHOD(QueryInterface)(REFIID iid, void** object); 205 STDMETHOD(QueryInterface)(REFIID iid, void** object);
178 206
179 // Implementation of the abstract interface IMMNotificationClient. 207 // Implementation of the abstract interface IMMNotificationClient.
180 // Provides notifications when an audio endpoint device is added or removed, 208 // Provides notifications when an audio endpoint device is added or removed,
(...skipping 18 matching lines...) Expand all
199 return S_OK; 227 return S_OK;
200 } 228 }
201 229
202 // DelegateSimpleThread::Delegate implementation. 230 // DelegateSimpleThread::Delegate implementation.
203 virtual void Run() OVERRIDE; 231 virtual void Run() OVERRIDE;
204 232
205 // Issues the OnError() callback to the |sink_|. 233 // Issues the OnError() callback to the |sink_|.
206 void HandleError(HRESULT err); 234 void HandleError(HRESULT err);
207 235
208 // The Open() method is divided into these sub methods. 236 // The Open() method is divided into these sub methods.
209 HRESULT SetRenderDevice(ERole device_role); 237 HRESULT SetRenderDevice();
210 HRESULT ActivateRenderDevice(); 238 HRESULT ActivateRenderDevice();
211 HRESULT GetAudioEngineStreamFormat(); 239 HRESULT GetAudioEngineStreamFormat();
212 bool DesiredFormatIsSupported(); 240 bool DesiredFormatIsSupported();
213 HRESULT InitializeAudioEngine(); 241 HRESULT InitializeAudioEngine();
214 242
215 // Converts unique endpoint ID to user-friendly device name. 243 // Converts unique endpoint ID to user-friendly device name.
216 std::string GetDeviceName(LPCWSTR device_id) const; 244 std::string GetDeviceName(LPCWSTR device_id) const;
217 245
218 // Called on the audio render thread when the current audio stream must 246 // Called on the audio render thread when the current audio stream must
219 // be re-initialized because the default audio device has changed. This 247 // be re-initialized because the default audio device has changed. This
220 // method: stops the current renderer, releases and re-creates all WASAPI 248 // method: stops the current renderer, releases and re-creates all WASAPI
221 // interfaces, creates a new IMMDevice and re-starts rendering using the 249 // interfaces, creates a new IMMDevice and re-starts rendering using the
222 // new default audio device. 250 // new default audio device.
223 bool RestartRenderingUsingNewDefaultDevice(); 251 bool RestartRenderingUsingNewDefaultDevice();
224 252
253 AUDCLNT_SHAREMODE share_mode() const { return share_mode_; }
254
225 // Initializes the COM library for use by the calling thread and sets the 255 // Initializes the COM library for use by the calling thread and sets the
226 // thread's concurrency model to multi-threaded. 256 // thread's concurrency model to multi-threaded.
227 base::win::ScopedCOMInitializer com_init_; 257 base::win::ScopedCOMInitializer com_init_;
228 258
229 // Contains the thread ID of the creating thread. 259 // Contains the thread ID of the creating thread.
230 base::PlatformThreadId creating_thread_id_; 260 base::PlatformThreadId creating_thread_id_;
231 261
232 // Our creator, the audio manager needs to be notified when we close. 262 // Our creator, the audio manager needs to be notified when we close.
233 AudioManagerWin* manager_; 263 AudioManagerWin* manager_;
234 264
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 299
270 // Size in milliseconds of each audio packet. 300 // Size in milliseconds of each audio packet.
271 float packet_size_ms_; 301 float packet_size_ms_;
272 302
273 // Length of the audio endpoint buffer. 303 // Length of the audio endpoint buffer.
274 size_t endpoint_buffer_size_frames_; 304 size_t endpoint_buffer_size_frames_;
275 305
276 // Defines the role that the system has assigned to an audio endpoint device. 306 // Defines the role that the system has assigned to an audio endpoint device.
277 ERole device_role_; 307 ERole device_role_;
278 308
309 // The sharing mode for the connection.
310 // Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE
311 // where AUDCLNT_SHAREMODE_SHARED is the default.
312 AUDCLNT_SHAREMODE share_mode_;
313
279 // Counts the number of audio frames written to the endpoint buffer. 314 // Counts the number of audio frames written to the endpoint buffer.
280 UINT64 num_written_frames_; 315 UINT64 num_written_frames_;
281 316
282 // Pointer to the client that will deliver audio samples to be played out. 317 // Pointer to the client that will deliver audio samples to be played out.
283 AudioSourceCallback* source_; 318 AudioSourceCallback* source_;
284 319
285 // An IMMDeviceEnumerator interface which represents a device enumerator. 320 // An IMMDeviceEnumerator interface which represents a device enumerator.
286 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_; 321 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_;
287 322
288 // An IMMDevice interface which represents an audio endpoint device. 323 // An IMMDevice interface which represents an audio endpoint device.
(...skipping 16 matching lines...) Expand all
305 340
306 // This event will be signaled when stream switching shall take place. 341 // This event will be signaled when stream switching shall take place.
307 base::win::ScopedHandle stream_switch_event_; 342 base::win::ScopedHandle stream_switch_event_;
308 343
309 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream); 344 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream);
310 }; 345 };
311 346
312 } // namespace media 347 } // namespace media
313 348
314 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ 349 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698