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 #ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_ 6 #define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_ 7 8 #include <map> 9 #include <utility> 10 11 #include "base/synchronization/lock.h" 12 #include "content/common/content_export.h" 13 #include "media/audio/audio_parameters.h" 14 15 namespace media { 16 class AudioHardwareConfig; 17 class AudioRendererMixer; 18 class AudioRendererMixerInput; 19 class AudioRendererSink; 20 } 21 22 namespace content { 23 24 // Manages sharing of an AudioRendererMixer among AudioRendererMixerInputs based 25 // on their AudioParameters configuration. Inputs with the same AudioParameters 26 // configuration will share a mixer while a new AudioRendererMixer will be 27 // lazily created if one with the exact AudioParameters does not exist. 28 // 29 // There should only be one instance of AudioRendererMixerManager per render 30 // thread. 31 // 32 // TODO(dalecurtis): Right now we require AudioParameters to be an exact match 33 // when we should be able to ignore bits per channel since we're only dealing 34 // with floats. However, bits per channel is currently used to interleave the 35 // audio data by AudioOutputDevice::AudioThreadCallback::Process for consumption 36 // via the shared memory. See http://crbug.com/114700. 37 class CONTENT_EXPORT AudioRendererMixerManager { 38 public: 39 // Construct an instance using the given audio hardware configuration. The 40 // provided |hardware_config| is not owned by AudioRendererMixerManager and 41 // must outlive it. 42 explicit AudioRendererMixerManager( 43 media::AudioHardwareConfig* hardware_config); 44 ~AudioRendererMixerManager(); 45 46 // Creates an AudioRendererMixerInput with the proper callbacks necessary to 47 // retrieve an AudioRendererMixer instance from AudioRendererMixerManager. 48 // |source_render_view_id| refers to the RenderView containing the entity 49 // rendering the audio. |source_render_frame_id| refers to the RenderFrame 50 // containing the entity rendering the audio. Caller must ensure 51 // AudioRendererMixerManager outlives the returned input. 52 media::AudioRendererMixerInput* CreateInput(int source_render_view_id, 53 int source_render_frame_id); 54 55 // Returns a mixer instance based on AudioParameters; an existing one if one 56 // with the provided AudioParameters exists or a new one if not. 57 media::AudioRendererMixer* GetMixer(int source_render_view_id, 58 int source_render_frame_id, 59 const media::AudioParameters& params); 60 61 // Remove a mixer instance given a mixer if the only other reference is held 62 // by AudioRendererMixerManager. Every AudioRendererMixer owner must call 63 // this method when it's done with a mixer. 64 void RemoveMixer(int source_render_view_id, 65 const media::AudioParameters& params); 66 67 private: 68 friend class AudioRendererMixerManagerTest; 69 70 // Define a key so that only those AudioRendererMixerInputs from the same 71 // RenderView and with the same AudioParameters can be mixed together. The 72 // first value is the RenderViewId. 73 typedef std::pair<int, media::AudioParameters> MixerKey; 74 75 // Custom compare operator for the AudioRendererMixerMap. Allows reuse of 76 // mixers where only irrelevant keys mismatch; e.g., effects, bits per sample. 77 struct MixerKeyCompare { operatorMixerKeyCompare78 bool operator()(const MixerKey& a, const MixerKey& b) const { 79 if (a.first != b.first) 80 return a.first < b.first; 81 if (a.second.sample_rate() != b.second.sample_rate()) 82 return a.second.sample_rate() < b.second.sample_rate(); 83 if (a.second.channels() != b.second.channels()) 84 return a.second.channels() < b.second.channels(); 85 86 // Ignore effects(), bits_per_sample(), format(), and frames_per_buffer(), 87 // these parameters do not affect mixer reuse. All AudioRendererMixer 88 // units disable FIFO, so frames_per_buffer() can be safely ignored. 89 return a.second.channel_layout() < b.second.channel_layout(); 90 } 91 }; 92 93 // Map of MixerKey to <AudioRendererMixer, Count>. Count allows 94 // AudioRendererMixerManager to keep track explicitly (v.s. RefCounted which 95 // is implicit) of the number of outstanding AudioRendererMixers. 96 struct AudioRendererMixerReference { 97 media::AudioRendererMixer* mixer; 98 int ref_count; 99 }; 100 typedef std::map<MixerKey, AudioRendererMixerReference, MixerKeyCompare> 101 AudioRendererMixerMap; 102 103 // Overrides the AudioRendererSink implementation for unit testing. 104 void SetAudioRendererSinkForTesting(media::AudioRendererSink* sink); 105 106 // Active mixers. 107 AudioRendererMixerMap mixers_; 108 base::Lock mixers_lock_; 109 110 // Audio hardware configuration. Used to construct output AudioParameters for 111 // each AudioRendererMixer instance. 112 media::AudioHardwareConfig* const hardware_config_; 113 114 media::AudioRendererSink* sink_for_testing_; 115 116 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerManager); 117 }; 118 119 } // namespace content 120 121 #endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_ 122