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
15namespace media {
16class AudioHardwareConfig;
17class AudioRendererMixer;
18class AudioRendererMixerInput;
19class AudioRendererSink;
20}
21
22namespace 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.
37class 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 {
78    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