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 3 // found in the LICENSE file. 4 5 #include "content/renderer/media/audio_renderer_mixer_manager.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "content/renderer/media/audio_device_factory.h" 10 #include "media/audio/audio_output_device.h" 11 #include "media/base/audio_hardware_config.h" 12 #include "media/base/audio_renderer_mixer.h" 13 #include "media/base/audio_renderer_mixer_input.h" 14 15 namespace content { 16 17 AudioRendererMixerManager::AudioRendererMixerManager( 18 media::AudioHardwareConfig* hardware_config) 19 : hardware_config_(hardware_config), 20 sink_for_testing_(NULL) { 21 } 22 23 AudioRendererMixerManager::~AudioRendererMixerManager() { 24 DCHECK(mixers_.empty()); 25 } 26 27 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput( 28 int source_render_view_id) { 29 return new media::AudioRendererMixerInput( 30 base::Bind( 31 &AudioRendererMixerManager::GetMixer, base::Unretained(this), 32 source_render_view_id), 33 base::Bind( 34 &AudioRendererMixerManager::RemoveMixer, base::Unretained(this), 35 source_render_view_id)); 36 } 37 38 void AudioRendererMixerManager::SetAudioRendererSinkForTesting( 39 media::AudioRendererSink* sink) { 40 sink_for_testing_ = sink; 41 } 42 43 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( 44 int source_render_view_id, 45 const media::AudioParameters& params) { 46 const MixerKey key(source_render_view_id, params); 47 base::AutoLock auto_lock(mixers_lock_); 48 49 AudioRendererMixerMap::iterator it = mixers_.find(key); 50 if (it != mixers_.end()) { 51 it->second.ref_count++; 52 return it->second.mixer; 53 } 54 55 // On ChromeOS and Linux we can rely on the playback device to handle 56 // resampling, so don't waste cycles on it here. 57 #if defined(OS_CHROMEOS) || defined(OS_LINUX) 58 int sample_rate = params.sample_rate(); 59 #else 60 int sample_rate = hardware_config_->GetOutputSampleRate(); 61 #endif 62 63 // Create output parameters based on the audio hardware configuration for 64 // passing on to the output sink. Force to 16-bit output for now since we 65 // know that works well for WebAudio and WebRTC. 66 media::AudioParameters output_params( 67 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(), 68 sample_rate, 16, hardware_config_->GetOutputBufferSize()); 69 70 // If we've created invalid output parameters, simply pass on the input params 71 // and let the browser side handle automatic fallback. 72 if (!output_params.IsValid()) 73 output_params = params; 74 75 media::AudioRendererMixer* mixer; 76 if (sink_for_testing_) { 77 mixer = new media::AudioRendererMixer( 78 params, output_params, sink_for_testing_); 79 } else { 80 mixer = new media::AudioRendererMixer( 81 params, output_params, AudioDeviceFactory::NewOutputDevice( 82 source_render_view_id)); 83 } 84 85 AudioRendererMixerReference mixer_reference = { mixer, 1 }; 86 mixers_[key] = mixer_reference; 87 return mixer; 88 } 89 90 void AudioRendererMixerManager::RemoveMixer( 91 int source_render_view_id, 92 const media::AudioParameters& params) { 93 const MixerKey key(source_render_view_id, params); 94 base::AutoLock auto_lock(mixers_lock_); 95 96 AudioRendererMixerMap::iterator it = mixers_.find(key); 97 DCHECK(it != mixers_.end()); 98 99 // Only remove the mixer if AudioRendererMixerManager is the last owner. 100 it->second.ref_count--; 101 if (it->second.ref_count == 0) { 102 delete it->second.mixer; 103 mixers_.erase(it); 104 } 105 } 106 107 } // namespace content 108