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

Side by Side Diff: media/audio/mac/audio_manager_mac.cc

Issue 9570014: Move some generic functions to AudioManagerBase to be inherited by platform-specific AudioManager*** (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased and fixed windows compiling Created 8 years, 9 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 | « media/audio/mac/audio_manager_mac.h ('k') | media/audio/openbsd/audio_manager_openbsd.h » ('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 #include <CoreAudio/AudioHardware.h> 5 #include <CoreAudio/AudioHardware.h>
6 6
7 #include "base/mac/mac_logging.h" 7 #include "base/mac/mac_logging.h"
8 #include "base/mac/mac_util.h" 8 #include "base/mac/mac_util.h"
9 #include "base/mac/scoped_cftyperef.h" 9 #include "base/mac/scoped_cftyperef.h"
10 #include "base/sys_string_conversions.h" 10 #include "base/sys_string_conversions.h"
11 #include "media/audio/fake_audio_input_stream.h"
12 #include "media/audio/fake_audio_output_stream.h"
13 #include "media/audio/mac/audio_input_mac.h" 11 #include "media/audio/mac/audio_input_mac.h"
14 #include "media/audio/mac/audio_low_latency_input_mac.h" 12 #include "media/audio/mac/audio_low_latency_input_mac.h"
15 #include "media/audio/mac/audio_low_latency_output_mac.h" 13 #include "media/audio/mac/audio_low_latency_output_mac.h"
16 #include "media/audio/mac/audio_manager_mac.h" 14 #include "media/audio/mac/audio_manager_mac.h"
17 #include "media/audio/mac/audio_output_mac.h" 15 #include "media/audio/mac/audio_output_mac.h"
18 #include "media/base/limits.h" 16 #include "media/base/limits.h"
19 17
20 static const int kMaxInputChannels = 2;
21
22 // Maximum number of output streams that can be open simultaneously. 18 // Maximum number of output streams that can be open simultaneously.
23 static const size_t kMaxOutputStreams = 50; 19 static const int kMaxOutputStreams = 50;
24 20
25 // By experiment the maximum number of audio streams allowed in Leopard 21 // By experiment the maximum number of audio streams allowed in Leopard
26 // is 18. But we put a slightly smaller number just to be safe. 22 // is 18. But we put a slightly smaller number just to be safe.
27 static const size_t kMaxOutputStreamsLeopard = 15; 23 static const int kMaxOutputStreamsLeopard = 15;
28
29 // Initialized to ether |kMaxOutputStreams| or |kMaxOutputStreamsLeopard|.
30 static size_t g_max_output_streams = 0;
31
32 // Returns the number of audio streams allowed. This is a practical limit to
33 // prevent failure caused by too many audio streams opened.
34 static size_t GetMaxAudioOutputStreamsAllowed() {
35 if (g_max_output_streams == 0) {
36 // We are hitting a bug in Leopard where too many audio streams will cause
37 // a deadlock in the AudioQueue API when starting the stream. Unfortunately
38 // there's no way to detect it within the AudioQueue API, so we put a
39 // special hard limit only for Leopard.
40 // See bug: http://crbug.com/30242
41 if (base::mac::IsOSLeopardOrEarlier()) {
42 g_max_output_streams = kMaxOutputStreamsLeopard;
43 } else {
44 // In OS other than OSX Leopard, the number of audio streams
45 // allowed is a lot more.
46 g_max_output_streams = kMaxOutputStreams;
47 }
48 }
49
50 return g_max_output_streams;
51 }
52 24
53 static bool HasAudioHardware(AudioObjectPropertySelector selector) { 25 static bool HasAudioHardware(AudioObjectPropertySelector selector) {
54 AudioDeviceID output_device_id = kAudioObjectUnknown; 26 AudioDeviceID output_device_id = kAudioObjectUnknown;
55 const AudioObjectPropertyAddress property_address = { 27 const AudioObjectPropertyAddress property_address = {
56 selector, 28 selector,
57 kAudioObjectPropertyScopeGlobal, // mScope 29 kAudioObjectPropertyScopeGlobal, // mScope
58 kAudioObjectPropertyElementMaster // mElement 30 kAudioObjectPropertyElementMaster // mElement
59 }; 31 };
60 size_t output_device_id_size = sizeof(output_device_id); 32 size_t output_device_id_size = sizeof(output_device_id);
61 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, 33 OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 200 }
229 201
230 if (result) { 202 if (result) {
231 OSSTATUS_DLOG(WARNING, result) << "Unable to query device " << device_id 203 OSSTATUS_DLOG(WARNING, result) << "Unable to query device " << device_id
232 << " for AudioDeviceID"; 204 << " for AudioDeviceID";
233 } 205 }
234 206
235 return audio_device_id; 207 return audio_device_id;
236 } 208 }
237 209
238 AudioManagerMac::AudioManagerMac() 210 AudioManagerMac::AudioManagerMac() {
239 : num_output_streams_(0) { 211 // We are hitting a bug in Leopard where too many audio streams will cause
212 // a deadlock in the AudioQueue API when starting the stream. Unfortunately
213 // there's no way to detect it within the AudioQueue API, so we put a
214 // special hard limit only for Leopard.
215 // See bug: http://crbug.com/30242
216 // In OS other than OSX Leopard, the number of audio streams
217 // allowed is a lot more.
218 int max_output_stream = base::mac::IsOSLeopardOrEarlier() ?
219 kMaxOutputStreamsLeopard : kMaxOutputStreams;
220 SetMaxOutputStreamsAllowed(max_output_stream);
240 } 221 }
241 222
242 AudioManagerMac::~AudioManagerMac() { 223 AudioManagerMac::~AudioManagerMac() {
243 } 224 }
244 225
245 bool AudioManagerMac::HasAudioOutputDevices() { 226 bool AudioManagerMac::HasAudioOutputDevices() {
246 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); 227 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice);
247 } 228 }
248 229
249 bool AudioManagerMac::HasAudioInputDevices() { 230 bool AudioManagerMac::HasAudioInputDevices() {
(...skipping 12 matching lines...) Expand all
262 // Prepend the default device to the list since we always want it to be 243 // Prepend the default device to the list since we always want it to be
263 // on the top of the list for all platforms. There is no duplicate 244 // on the top of the list for all platforms. There is no duplicate
264 // counting here since the default device has been abstracted out before. 245 // counting here since the default device has been abstracted out before.
265 media::AudioDeviceName name; 246 media::AudioDeviceName name;
266 name.device_name = AudioManagerBase::kDefaultDeviceName; 247 name.device_name = AudioManagerBase::kDefaultDeviceName;
267 name.unique_id = AudioManagerBase::kDefaultDeviceId; 248 name.unique_id = AudioManagerBase::kDefaultDeviceId;
268 device_names->push_front(name); 249 device_names->push_front(name);
269 } 250 }
270 } 251 }
271 252
272 AudioOutputStream* AudioManagerMac::MakeAudioOutputStream(
273 const AudioParameters& params) {
274 if (!params.IsValid())
275 return NULL;
276
277 // Limit the number of audio streams opened. This is to prevent using
278 // excessive resources for a large number of audio streams. More
279 // importantly it prevents instability on certain systems.
280 // See bug: http://crbug.com/30242
281 if (num_output_streams_ >= GetMaxAudioOutputStreamsAllowed()) {
282 return NULL;
283 }
284
285 if (params.format == AudioParameters::AUDIO_MOCK) {
286 return FakeAudioOutputStream::MakeFakeStream(params);
287 } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
288 num_output_streams_++;
289 return new PCMQueueOutAudioOutputStream(this, params);
290 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
291 num_output_streams_++;
292 return new AUAudioOutputStream(this, params);
293 }
294 return NULL;
295 }
296
297 AudioInputStream* AudioManagerMac::MakeAudioInputStream(
298 const AudioParameters& params, const std::string& device_id) {
299 if (!params.IsValid() || (params.channels > kMaxInputChannels) ||
300 device_id.empty())
301 return NULL;
302
303 if (params.format == AudioParameters::AUDIO_MOCK) {
304 return FakeAudioInputStream::MakeFakeStream(params);
305 } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
306 return new PCMQueueInAudioInputStream(this, params);
307 } else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
308 // Gets the AudioDeviceID that refers to the AudioDevice with the device
309 // unique id. This AudioDeviceID is used to set the device for Audio Unit.
310 AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
311 if (audio_device_id != kAudioObjectUnknown)
312 return new AUAudioInputStream(this, params, audio_device_id);
313 }
314 return NULL;
315 }
316
317 void AudioManagerMac::MuteAll() { 253 void AudioManagerMac::MuteAll() {
318 // TODO(cpu): implement. 254 // TODO(cpu): implement.
319 } 255 }
320 256
321 void AudioManagerMac::UnMuteAll() { 257 void AudioManagerMac::UnMuteAll() {
322 // TODO(cpu): implement. 258 // TODO(cpu): implement.
323 } 259 }
324 260
325 // Called by the stream when it has been released by calling Close(). 261 AudioOutputStream* AudioManagerMac::MakeLinearOutputStream(
326 void AudioManagerMac::ReleaseOutputStream(AudioOutputStream* stream) { 262 const AudioParameters& params) {
327 DCHECK(stream); 263 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
328 num_output_streams_--; 264 return new PCMQueueOutAudioOutputStream(this, params);
329 delete stream;
330 } 265 }
331 266
332 // Called by the stream when it has been released by calling Close(). 267 AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
333 void AudioManagerMac::ReleaseInputStream(AudioInputStream* stream) { 268 const AudioParameters& params) {
334 delete stream; 269 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
270 return new AUAudioOutputStream(this, params);
271 }
272
273 AudioInputStream* AudioManagerMac::MakeLinearInputStream(
274 const AudioParameters& params, const std::string& device_id) {
275 DCHECK_EQ(AudioParameters::AUDIO_PCM_LINEAR, params.format);
276 return new PCMQueueInAudioInputStream(this, params);
277 }
278
279 AudioInputStream* AudioManagerMac::MakeLowLatencyInputStream(
280 const AudioParameters& params, const std::string& device_id) {
281 DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format);
282 // Gets the AudioDeviceID that refers to the AudioDevice with the device
283 // unique id. This AudioDeviceID is used to set the device for Audio Unit.
284 AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
285 AudioInputStream* stream = NULL;
286 if (audio_device_id != kAudioObjectUnknown)
287 stream = new AUAudioInputStream(this, params, audio_device_id);
288
289 return stream;
335 } 290 }
336 291
337 AudioManager* CreateAudioManager() { 292 AudioManager* CreateAudioManager() {
338 return new AudioManagerMac(); 293 return new AudioManagerMac();
339 } 294 }
OLDNEW
« no previous file with comments | « media/audio/mac/audio_manager_mac.h ('k') | media/audio/openbsd/audio_manager_openbsd.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698