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

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

Issue 12387006: Pass more detailed audio hardware configuration information to the renderer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 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
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/mac/audio_manager_mac.h" 5 #include "media/audio/mac/audio_manager_mac.h"
6 6
7 #include <CoreAudio/AudioHardware.h> 7 #include <CoreAudio/AudioHardware.h>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 257 }
258 258
259 bool AudioManagerMac::HasAudioOutputDevices() { 259 bool AudioManagerMac::HasAudioOutputDevices() {
260 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice); 260 return HasAudioHardware(kAudioHardwarePropertyDefaultOutputDevice);
261 } 261 }
262 262
263 bool AudioManagerMac::HasAudioInputDevices() { 263 bool AudioManagerMac::HasAudioInputDevices() {
264 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice); 264 return HasAudioHardware(kAudioHardwarePropertyDefaultInputDevice);
265 } 265 }
266 266
267 // TODO(crogers): There are several places on the OSX specific code which
268 // could benefit from this helper function.
269 bool AudioManagerMac::GetDefaultOutputDevice(
270 AudioDeviceID* device) {
271 CHECK(device);
272
273 // Obtain the current output device selected by the user.
274 static const AudioObjectPropertyAddress kAddress = {
275 kAudioHardwarePropertyDefaultOutputDevice,
276 kAudioObjectPropertyScopeGlobal,
277 kAudioObjectPropertyElementMaster
278 };
279
280 UInt32 size = sizeof(*device);
281
282 OSStatus result = AudioObjectGetPropertyData(
283 kAudioObjectSystemObject,
284 &kAddress,
285 0,
286 0,
287 &size,
288 device);
289
290 if ((result != kAudioHardwareNoError) || (*device == kAudioDeviceUnknown)) {
291 DLOG(ERROR) << "Error getting default output AudioDevice.";
292 return false;
293 }
294
295 return true;
296 }
297
298 bool AudioManagerMac::GetDefaultOutputChannels(
299 int* channels, int* channels_per_frame) {
300 AudioDeviceID device;
301 if (!GetDefaultOutputDevice(&device))
302 return false;
303
304 return GetDeviceChannels(device,
305 kAudioDevicePropertyScopeOutput,
306 channels,
307 channels_per_frame);
308 }
309
310 bool AudioManagerMac::GetDeviceChannels(
311 AudioDeviceID device,
312 AudioObjectPropertyScope scope,
313 int* channels,
314 int* channels_per_frame) {
315 CHECK(channels);
316 CHECK(channels_per_frame);
317
318 // Get stream configuration.
319 AudioObjectPropertyAddress pa;
320 pa.mSelector = kAudioDevicePropertyStreamConfiguration;
321 pa.mScope = scope;
322 pa.mElement = kAudioObjectPropertyElementMaster;
323
324 UInt32 size;
325 OSStatus result = AudioObjectGetPropertyDataSize(device, &pa, 0, 0, &size);
326 if (result != noErr || !size)
327 return false;
328
329 // Allocate storage.
330 scoped_array<uint8> list_storage(new uint8[size]);
331 AudioBufferList& buffer_list =
332 *reinterpret_cast<AudioBufferList*>(list_storage.get());
333
334 result = AudioObjectGetPropertyData(
335 device,
336 &pa,
337 0,
338 0,
339 &size,
340 &buffer_list);
341 if (result != noErr)
342 return false;
343
344 // Determine number of input channels.
345 *channels_per_frame = buffer_list.mNumberBuffers > 0 ?
346 buffer_list.mBuffers[0].mNumberChannels : 0;
347 if (*channels_per_frame == 1 && buffer_list.mNumberBuffers > 1) {
348 // Non-interleaved.
349 *channels = buffer_list.mNumberBuffers;
350 } else {
351 // Interleaved.
352 *channels = *channels_per_frame;
353 }
354
355 return true;
356 }
357
267 void AudioManagerMac::GetAudioInputDeviceNames( 358 void AudioManagerMac::GetAudioInputDeviceNames(
268 media::AudioDeviceNames* device_names) { 359 media::AudioDeviceNames* device_names) {
269 GetAudioDeviceInfo(true, device_names); 360 GetAudioDeviceInfo(true, device_names);
270 if (!device_names->empty()) { 361 if (!device_names->empty()) {
271 // Prepend the default device to the list since we always want it to be 362 // Prepend the default device to the list since we always want it to be
272 // on the top of the list for all platforms. There is no duplicate 363 // on the top of the list for all platforms. There is no duplicate
273 // counting here since the default device has been abstracted out before. 364 // counting here since the default device has been abstracted out before.
274 media::AudioDeviceName name; 365 media::AudioDeviceName name;
275 name.device_name = AudioManagerBase::kDefaultDeviceName; 366 name.device_name = AudioManagerBase::kDefaultDeviceName;
276 name.unique_id = AudioManagerBase::kDefaultDeviceId; 367 name.unique_id = AudioManagerBase::kDefaultDeviceId;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id); 417 AudioDeviceID audio_device_id = GetAudioDeviceIdByUId(true, device_id);
327 AudioInputStream* stream = NULL; 418 AudioInputStream* stream = NULL;
328 if (audio_device_id != kAudioObjectUnknown) 419 if (audio_device_id != kAudioObjectUnknown)
329 stream = new AUAudioInputStream(this, params, audio_device_id); 420 stream = new AUAudioInputStream(this, params, audio_device_id);
330 421
331 return stream; 422 return stream;
332 } 423 }
333 424
334 AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters( 425 AudioParameters AudioManagerMac::GetPreferredOutputStreamParameters(
335 const AudioParameters& input_params) { 426 const AudioParameters& input_params) {
336 ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; 427 int hardware_channels = 2;
428 int hardware_channels_per_frame;
429 GetDefaultOutputChannels(&hardware_channels, &hardware_channels_per_frame);
DaleCurtis 2013/03/11 19:21:50 Check return value? hardware_channels_per_frame sh
Chris Rogers 2013/03/12 22:32:31 Fixed - although hardware_channels_per_frame is un
430
431 ChannelLayout channel_layout = GuessChannelLayout(hardware_channels);
432
337 int buffer_size = kDefaultLowLatencyBufferSize; 433 int buffer_size = kDefaultLowLatencyBufferSize;
434 int user_buffer_size = GetUserBufferSize();
435 if (user_buffer_size)
436 buffer_size = user_buffer_size;
437
338 int input_channels = 0; 438 int input_channels = 0;
339 if (input_params.IsValid()) { 439 if (input_params.IsValid()) {
340 channel_layout = input_params.channel_layout();
341 input_channels = input_params.input_channels(); 440 input_channels = input_params.input_channels();
342 441
343 if (input_channels > 0) { 442 if (input_channels > 0) {
344 // TODO(crogers): given the limitations of the AudioOutputStream 443 // TODO(crogers): given the limitations of the AudioOutputStream
345 // back-ends used with synchronized I/O, we hard-code to stereo. 444 // back-ends used with synchronized I/O, we hard-code to stereo.
346 // Specifically, this is a limitation of AudioSynchronizedStream which 445 // Specifically, this is a limitation of AudioSynchronizedStream which
347 // can be removed as part of the work to consolidate these back-ends. 446 // can be removed as part of the work to consolidate these back-ends.
348 channel_layout = CHANNEL_LAYOUT_STEREO; 447 channel_layout = CHANNEL_LAYOUT_STEREO;
349 } 448 }
350 } 449 }
351 450
352 int user_buffer_size = GetUserBufferSize(); 451 AudioParameters params(
353 if (user_buffer_size) 452 AudioParameters::AUDIO_PCM_LOW_LATENCY,
354 buffer_size = user_buffer_size; 453 channel_layout,
454 input_channels,
455 AUAudioOutputStream::HardwareSampleRate(),
456 16,
457 buffer_size);
355 458
356 return AudioParameters( 459 if (channel_layout == CHANNEL_LAYOUT_UNSUPPORTED)
357 AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, input_channels, 460 params.SetDiscreteChannels(hardware_channels);
358 AUAudioOutputStream::HardwareSampleRate(), 16, buffer_size); 461
462 return params;
359 } 463 }
360 464
361 void AudioManagerMac::CreateDeviceListener() { 465 void AudioManagerMac::CreateDeviceListener() {
362 DCHECK(GetMessageLoop()->BelongsToCurrentThread()); 466 DCHECK(GetMessageLoop()->BelongsToCurrentThread());
363 output_device_listener_.reset(new AudioDeviceListenerMac(base::Bind( 467 output_device_listener_.reset(new AudioDeviceListenerMac(base::Bind(
364 &AudioManagerMac::DelayedDeviceChange, base::Unretained(this)))); 468 &AudioManagerMac::DelayedDeviceChange, base::Unretained(this))));
365 } 469 }
366 470
367 void AudioManagerMac::DestroyDeviceListener() { 471 void AudioManagerMac::DestroyDeviceListener() {
368 DCHECK(GetMessageLoop()->BelongsToCurrentThread()); 472 DCHECK(GetMessageLoop()->BelongsToCurrentThread());
369 output_device_listener_.reset(); 473 output_device_listener_.reset();
370 } 474 }
371 475
372 void AudioManagerMac::DelayedDeviceChange() { 476 void AudioManagerMac::DelayedDeviceChange() {
373 // TODO(dalecurtis): This is ridiculous, but we need to delay device changes 477 // TODO(dalecurtis): This is ridiculous, but we need to delay device changes
374 // to workaround threading issues with OSX property listener callbacks. See 478 // to workaround threading issues with OSX property listener callbacks. See
375 // http://crbug.com/158170 479 // http://crbug.com/158170
376 GetMessageLoop()->PostDelayedTask(FROM_HERE, base::Bind( 480 GetMessageLoop()->PostDelayedTask(FROM_HERE, base::Bind(
377 &AudioManagerMac::NotifyAllOutputDeviceChangeListeners, 481 &AudioManagerMac::NotifyAllOutputDeviceChangeListeners,
378 base::Unretained(this)), base::TimeDelta::FromSeconds(2)); 482 base::Unretained(this)), base::TimeDelta::FromSeconds(2));
379 } 483 }
380 484
381 AudioManager* CreateAudioManager() { 485 AudioManager* CreateAudioManager() {
382 return new AudioManagerMac(); 486 return new AudioManagerMac();
383 } 487 }
384 488
385 } // namespace media 489 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698