OLD | NEW |
---|---|
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 "content/renderer/media/audio_renderer_mixer_manager.h" | 5 #include "content/renderer/media/audio_renderer_mixer_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/memory/ptr_util.h" | |
11 #include "build/build_config.h" | 12 #include "build/build_config.h" |
12 #include "content/renderer/media/audio_device_factory.h" | 13 #include "content/renderer/media/audio_renderer_sink_cache.h" |
13 #include "media/audio/audio_device_description.h" | 14 #include "media/audio/audio_device_description.h" |
14 #include "media/base/audio_hardware_config.h" | 15 #include "media/base/audio_hardware_config.h" |
15 #include "media/base/audio_renderer_mixer.h" | 16 #include "media/base/audio_renderer_mixer.h" |
16 #include "media/base/audio_renderer_mixer_input.h" | 17 #include "media/base/audio_renderer_mixer_input.h" |
17 | 18 |
18 namespace content { | 19 namespace content { |
19 | 20 |
20 AudioRendererMixerManager::AudioRendererMixerManager() {} | 21 // static |
22 std::unique_ptr<AudioRendererMixerManager> AudioRendererMixerManager::Create() { | |
23 return base::WrapUnique( | |
24 new AudioRendererMixerManager(AudioRendererSinkCache::Create())); | |
25 } | |
26 | |
27 AudioRendererMixerManager::AudioRendererMixerManager( | |
28 std::unique_ptr<AudioRendererSinkCache> sink_cache) | |
29 : sink_cache_(std::move(sink_cache)) { | |
30 DCHECK(sink_cache_); | |
31 } | |
21 | 32 |
22 AudioRendererMixerManager::~AudioRendererMixerManager() { | 33 AudioRendererMixerManager::~AudioRendererMixerManager() { |
23 // References to AudioRendererMixers may be owned by garbage collected | 34 // References to AudioRendererMixers may be owned by garbage collected |
24 // objects. During process shutdown they may be leaked, so, transitively, | 35 // objects. During process shutdown they may be leaked, so, transitively, |
25 // |mixers_| may leak (i.e., may be non-empty at this time) as well. | 36 // |mixers_| may leak (i.e., may be non-empty at this time) as well. |
26 } | 37 } |
27 | 38 |
28 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput( | 39 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput( |
29 int source_render_frame_id, | 40 int source_render_frame_id, |
30 int session_id, | 41 int session_id, |
31 const std::string& device_id, | 42 const std::string& device_id, |
32 const url::Origin& security_origin) { | 43 const url::Origin& security_origin) { |
33 // base::Unretained() is safe since AudioRendererMixerManager lives on the | 44 // base::Unretained() is safe since AudioRendererMixerManager lives on the |
34 // renderer thread and is destroyed on renderer thread destruction. | 45 // renderer thread and is destroyed on renderer thread destruction. |
35 return new media::AudioRendererMixerInput( | 46 return new media::AudioRendererMixerInput( |
36 base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this), | 47 this, source_render_frame_id, |
37 source_render_frame_id), | |
38 base::Bind(&AudioRendererMixerManager::RemoveMixer, | |
39 base::Unretained(this), source_render_frame_id), | |
40 media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id, | 48 media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id, |
41 device_id) | 49 device_id) |
42 ? AudioDeviceFactory::GetOutputDeviceInfo( | 50 ? GetOutputDeviceInfo(source_render_frame_id, session_id, device_id, |
43 source_render_frame_id, session_id, device_id, security_origin) | 51 security_origin) |
44 .device_id() | 52 .device_id() |
45 : device_id, | 53 : device_id, |
46 security_origin); | 54 security_origin); |
47 } | 55 } |
48 | 56 |
49 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( | 57 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( |
50 int source_render_frame_id, | 58 int source_render_frame_id, |
51 const media::AudioParameters& params, | 59 const media::AudioParameters& params, |
52 const std::string& device_id, | 60 const std::string& device_id, |
53 const url::Origin& security_origin, | 61 const url::Origin& security_origin, |
54 media::OutputDeviceStatus* device_status) { | 62 media::OutputDeviceStatus* device_status) { |
55 // Effects are not passed through to output creation, so ensure none are set. | 63 // Effects are not passed through to output creation, so ensure none are set. |
56 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS); | 64 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS); |
57 | 65 |
58 const MixerKey key(source_render_frame_id, params, device_id, | 66 const MixerKey key(source_render_frame_id, params, device_id, |
59 security_origin); | 67 security_origin); |
60 base::AutoLock auto_lock(mixers_lock_); | 68 base::AutoLock auto_lock(mixers_lock_); |
61 | 69 |
62 AudioRendererMixerMap::iterator it = mixers_.find(key); | 70 AudioRendererMixerMap::iterator it = mixers_.find(key); |
63 if (it != mixers_.end()) { | 71 if (it != mixers_.end()) { |
64 if (device_status) | 72 if (device_status) |
65 *device_status = media::OUTPUT_DEVICE_STATUS_OK; | 73 *device_status = media::OUTPUT_DEVICE_STATUS_OK; |
66 | 74 |
67 it->second.ref_count++; | 75 it->second.ref_count++; |
68 return it->second.mixer; | 76 return it->second.mixer; |
69 } | 77 } |
70 | 78 |
71 scoped_refptr<media::AudioRendererSink> sink = | 79 scoped_refptr<media::AudioRendererSink> sink = |
72 AudioDeviceFactory::NewAudioRendererMixerSink(source_render_frame_id, 0, | 80 sink_cache_->GetSink(source_render_frame_id, device_id, security_origin); |
73 device_id, security_origin); | |
74 | 81 |
75 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo(); | 82 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo(); |
76 if (device_status) | 83 if (device_status) |
77 *device_status = device_info.device_status(); | 84 *device_status = device_info.device_status(); |
78 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) { | 85 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) { |
79 sink->Stop(); | 86 sink_cache_->ReleaseSink(source_render_frame_id, device_id, security_origin, |
87 sink.get()); | |
80 return nullptr; | 88 return nullptr; |
81 } | 89 } |
82 | 90 |
83 // On ChromeOS as well as when a fake device is used, we can rely on the | 91 // On ChromeOS as well as when a fake device is used, we can rely on the |
84 // playback device to handle resampling, so don't waste cycles on it here. | 92 // playback device to handle resampling, so don't waste cycles on it here. |
85 int sample_rate = params.sample_rate(); | 93 int sample_rate = params.sample_rate(); |
86 int buffer_size = | 94 int buffer_size = |
87 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0); | 95 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0); |
88 | 96 |
89 #if !defined(OS_CHROMEOS) | 97 #if !defined(OS_CHROMEOS) |
(...skipping 17 matching lines...) Expand all Loading... | |
107 sample_rate, 16, buffer_size); | 115 sample_rate, 16, buffer_size); |
108 DCHECK(output_params.IsValid()); | 116 DCHECK(output_params.IsValid()); |
109 | 117 |
110 media::AudioRendererMixer* mixer = | 118 media::AudioRendererMixer* mixer = |
111 new media::AudioRendererMixer(output_params, sink); | 119 new media::AudioRendererMixer(output_params, sink); |
112 AudioRendererMixerReference mixer_reference = { mixer, 1 }; | 120 AudioRendererMixerReference mixer_reference = { mixer, 1 }; |
113 mixers_[key] = mixer_reference; | 121 mixers_[key] = mixer_reference; |
114 return mixer; | 122 return mixer; |
115 } | 123 } |
116 | 124 |
117 void AudioRendererMixerManager::RemoveMixer( | 125 void AudioRendererMixerManager::ReturnMixer( |
118 int source_render_frame_id, | 126 int source_render_frame_id, |
119 const media::AudioParameters& params, | 127 const media::AudioParameters& params, |
120 const std::string& device_id, | 128 const std::string& device_id, |
121 const url::Origin& security_origin) { | 129 const url::Origin& security_origin) { |
122 const MixerKey key(source_render_frame_id, params, device_id, | 130 const MixerKey key(source_render_frame_id, params, device_id, |
123 security_origin); | 131 security_origin); |
124 base::AutoLock auto_lock(mixers_lock_); | 132 base::AutoLock auto_lock(mixers_lock_); |
125 | 133 |
126 AudioRendererMixerMap::iterator it = mixers_.find(key); | 134 AudioRendererMixerMap::iterator it = mixers_.find(key); |
127 DCHECK(it != mixers_.end()); | 135 DCHECK(it != mixers_.end()); |
128 | 136 |
129 // Only remove the mixer if AudioRendererMixerManager is the last owner. | 137 // Only remove the mixer if AudioRendererMixerManager is the last owner. |
130 it->second.ref_count--; | 138 it->second.ref_count--; |
131 if (it->second.ref_count == 0) { | 139 if (it->second.ref_count == 0) { |
140 // The mixer will be deleted now, so releasing the sink. | |
DaleCurtis
2016/05/17 19:13:48
s/releasing/release/
o1ka
2016/05/18 13:15:12
Done.
| |
141 sink_cache_->ReleaseSink(source_render_frame_id, device_id, security_origin, | |
142 it->second.mixer->sink_ptr()); | |
132 delete it->second.mixer; | 143 delete it->second.mixer; |
133 mixers_.erase(it); | 144 mixers_.erase(it); |
134 } | 145 } |
135 } | 146 } |
136 | 147 |
148 media::OutputDeviceInfo AudioRendererMixerManager::GetOutputDeviceInfo( | |
149 int source_render_frame_id, | |
150 int session_id, | |
151 const std::string& device_id, | |
152 const url::Origin& security_origin) { | |
153 return sink_cache_->GetSinkInfo(source_render_frame_id, session_id, device_id, | |
154 security_origin); | |
155 } | |
156 | |
137 AudioRendererMixerManager::MixerKey::MixerKey( | 157 AudioRendererMixerManager::MixerKey::MixerKey( |
138 int source_render_frame_id, | 158 int source_render_frame_id, |
139 const media::AudioParameters& params, | 159 const media::AudioParameters& params, |
140 const std::string& device_id, | 160 const std::string& device_id, |
141 const url::Origin& security_origin) | 161 const url::Origin& security_origin) |
142 : source_render_frame_id(source_render_frame_id), | 162 : source_render_frame_id(source_render_frame_id), |
143 params(params), | 163 params(params), |
144 device_id(device_id), | 164 device_id(device_id), |
145 security_origin(security_origin) {} | 165 security_origin(security_origin) {} |
146 | 166 |
147 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default; | 167 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default; |
148 | 168 |
149 } // namespace content | 169 } // namespace content |
OLD | NEW |