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

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: nit 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:
116 //
117 // - It is possible to open up a stream in exclusive mode by using the
118 // "--enable-exclusive-mode" command-line flag.
scherkus (not reviewing) 2012/07/25 23:44:44 ditch ""s on the flag
henrika (OOO until Aug 14) 2012/07/26 08:31:11 Done.
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 system sounds, prevent
125 // interoperability with other applications, and otherwise degrade the user
126 // 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 http://msdn.microsoft.com/en-us/library/windows/desktop/dd370844(v=vs.8 5).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
scherkus (not reviewing) 2012/07/25 23:44:44 ditch ""s and just use --enable-exclusive-mode
henrika (OOO until Aug 14) 2012/07/26 08:31:11 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
243 // Called when the device will be opened in shared mode and use the WAS
scherkus (not reviewing) 2012/07/25 23:44:44 WAS?
henrika (OOO until Aug 14) 2012/07/26 08:31:11 Modified.
244 // format.
245 HRESULT SharedModeInitialization();
246
247 // Called when the device will be opened in exclusive mode and use the
248 // application specified format.
249 HRESULT ExclusiveModeInitialization();
250
215 // Converts unique endpoint ID to user-friendly device name. 251 // Converts unique endpoint ID to user-friendly device name.
216 std::string GetDeviceName(LPCWSTR device_id) const; 252 std::string GetDeviceName(LPCWSTR device_id) const;
217 253
218 // Called on the audio render thread when the current audio stream must 254 // Called on the audio render thread when the current audio stream must
219 // be re-initialized because the default audio device has changed. This 255 // be re-initialized because the default audio device has changed. This
220 // method: stops the current renderer, releases and re-creates all WASAPI 256 // method: stops the current renderer, releases and re-creates all WASAPI
221 // interfaces, creates a new IMMDevice and re-starts rendering using the 257 // interfaces, creates a new IMMDevice and re-starts rendering using the
222 // new default audio device. 258 // new default audio device.
223 bool RestartRenderingUsingNewDefaultDevice(); 259 bool RestartRenderingUsingNewDefaultDevice();
224 260
261 AUDCLNT_SHAREMODE share_mode() const { return share_mode_; }
262
225 // Initializes the COM library for use by the calling thread and sets the 263 // Initializes the COM library for use by the calling thread and sets the
226 // thread's concurrency model to multi-threaded. 264 // thread's concurrency model to multi-threaded.
227 base::win::ScopedCOMInitializer com_init_; 265 base::win::ScopedCOMInitializer com_init_;
228 266
229 // Contains the thread ID of the creating thread. 267 // Contains the thread ID of the creating thread.
230 base::PlatformThreadId creating_thread_id_; 268 base::PlatformThreadId creating_thread_id_;
231 269
232 // Our creator, the audio manager needs to be notified when we close. 270 // Our creator, the audio manager needs to be notified when we close.
233 AudioManagerWin* manager_; 271 AudioManagerWin* manager_;
234 272
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 307
270 // Size in milliseconds of each audio packet. 308 // Size in milliseconds of each audio packet.
271 float packet_size_ms_; 309 float packet_size_ms_;
272 310
273 // Length of the audio endpoint buffer. 311 // Length of the audio endpoint buffer.
274 size_t endpoint_buffer_size_frames_; 312 size_t endpoint_buffer_size_frames_;
275 313
276 // Defines the role that the system has assigned to an audio endpoint device. 314 // Defines the role that the system has assigned to an audio endpoint device.
277 ERole device_role_; 315 ERole device_role_;
278 316
317 // The sharing mode for the connection.
318 // Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE
319 // where AUDCLNT_SHAREMODE_SHARED is the default.
320 AUDCLNT_SHAREMODE share_mode_;
321
279 // Counts the number of audio frames written to the endpoint buffer. 322 // Counts the number of audio frames written to the endpoint buffer.
280 UINT64 num_written_frames_; 323 UINT64 num_written_frames_;
281 324
282 // Pointer to the client that will deliver audio samples to be played out. 325 // Pointer to the client that will deliver audio samples to be played out.
283 AudioSourceCallback* source_; 326 AudioSourceCallback* source_;
284 327
285 // An IMMDeviceEnumerator interface which represents a device enumerator. 328 // An IMMDeviceEnumerator interface which represents a device enumerator.
286 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_; 329 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_;
287 330
288 // An IMMDevice interface which represents an audio endpoint device. 331 // An IMMDevice interface which represents an audio endpoint device.
(...skipping 16 matching lines...) Expand all
305 348
306 // This event will be signaled when stream switching shall take place. 349 // This event will be signaled when stream switching shall take place.
307 base::win::ScopedHandle stream_switch_event_; 350 base::win::ScopedHandle stream_switch_event_;
308 351
309 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream); 352 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream);
310 }; 353 };
311 354
312 } // namespace media 355 } // namespace media
313 356
314 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ 357 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698