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

Side by Side Diff: content/renderer/media/audio_renderer_mixer_manager.cc

Issue 1942803002: Caching AudioOutputDevice instances in mixer manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make WebAudioSourceProvider to always return real sink info reguardless the client - to avoid behavior change. Created 4 years, 6 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
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 "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 AudioRendererMixerManager::AudioRendererMixerManager(
22 std::unique_ptr<AudioRendererSinkCache> sink_cache)
23 : sink_cache_(std::move(sink_cache)) {
24 DCHECK(sink_cache_);
25 }
21 26
22 AudioRendererMixerManager::~AudioRendererMixerManager() { 27 AudioRendererMixerManager::~AudioRendererMixerManager() {
23 // References to AudioRendererMixers may be owned by garbage collected 28 // References to AudioRendererMixers may be owned by garbage collected
24 // objects. During process shutdown they may be leaked, so, transitively, 29 // 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. 30 // |mixers_| may leak (i.e., may be non-empty at this time) as well.
26 } 31 }
27 32
33 // static
34 std::unique_ptr<AudioRendererMixerManager> AudioRendererMixerManager::Create() {
35 return base::WrapUnique(
36 new AudioRendererMixerManager(AudioRendererSinkCache::Create()));
37 }
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 // AudioRendererMixerManager lives on the renderer thread and is destroyed on
34 // renderer thread and is destroyed on renderer thread destruction. 45 // renderer thread destruction, so it's safe to pass its pointer to a mixer
46 // input.
35 return new media::AudioRendererMixerInput( 47 return new media::AudioRendererMixerInput(
36 base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this), 48 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, 49 media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id,
41 device_id) 50 device_id)
42 ? AudioDeviceFactory::GetOutputDeviceInfo( 51 ? GetOutputDeviceInfo(source_render_frame_id, session_id, device_id,
43 source_render_frame_id, session_id, device_id, security_origin) 52 security_origin)
44 .device_id() 53 .device_id()
45 : device_id, 54 : device_id,
46 security_origin); 55 security_origin);
47 } 56 }
48 57
49 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( 58 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
50 int source_render_frame_id, 59 int source_render_frame_id,
51 const media::AudioParameters& params, 60 const media::AudioParameters& params,
52 const std::string& device_id, 61 const std::string& device_id,
53 const url::Origin& security_origin, 62 const url::Origin& security_origin,
54 media::OutputDeviceStatus* device_status) { 63 media::OutputDeviceStatus* device_status) {
55 // Effects are not passed through to output creation, so ensure none are set. 64 // Effects are not passed through to output creation, so ensure none are set.
56 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS); 65 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS);
57 66
58 const MixerKey key(source_render_frame_id, params, device_id, 67 const MixerKey key(source_render_frame_id, params, device_id,
59 security_origin); 68 security_origin);
60 base::AutoLock auto_lock(mixers_lock_); 69 base::AutoLock auto_lock(mixers_lock_);
61 70
62 AudioRendererMixerMap::iterator it = mixers_.find(key); 71 AudioRendererMixerMap::iterator it = mixers_.find(key);
63 if (it != mixers_.end()) { 72 if (it != mixers_.end()) {
64 if (device_status) 73 if (device_status)
65 *device_status = media::OUTPUT_DEVICE_STATUS_OK; 74 *device_status = media::OUTPUT_DEVICE_STATUS_OK;
66 75
67 it->second.ref_count++; 76 it->second.ref_count++;
68 return it->second.mixer; 77 return it->second.mixer;
69 } 78 }
70 79
71 scoped_refptr<media::AudioRendererSink> sink = 80 scoped_refptr<media::AudioRendererSink> sink =
72 AudioDeviceFactory::NewAudioRendererMixerSink(source_render_frame_id, 0, 81 sink_cache_->GetSink(source_render_frame_id, device_id, security_origin);
73 device_id, security_origin);
74 82
75 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo(); 83 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo();
76 if (device_status) 84 if (device_status)
77 *device_status = device_info.device_status(); 85 *device_status = device_info.device_status();
78 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) { 86 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) {
87 sink_cache_->ReleaseSink(sink.get());
79 sink->Stop(); 88 sink->Stop();
80 return nullptr; 89 return nullptr;
81 } 90 }
82 91
83 // On ChromeOS as well as when a fake device is used, we can rely on the 92 // 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. 93 // playback device to handle resampling, so don't waste cycles on it here.
85 int sample_rate = params.sample_rate(); 94 int sample_rate = params.sample_rate();
86 int buffer_size = 95 int buffer_size =
87 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0); 96 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0);
88 97
(...skipping 13 matching lines...) Expand all
102 // Create output parameters based on the audio hardware configuration for 111 // Create output parameters based on the audio hardware configuration for
103 // passing on to the output sink. Force to 16-bit output for now since we 112 // passing on to the output sink. Force to 16-bit output for now since we
104 // know that works everywhere; ChromeOS does not support other bit depths. 113 // know that works everywhere; ChromeOS does not support other bit depths.
105 media::AudioParameters output_params( 114 media::AudioParameters output_params(
106 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(), 115 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(),
107 sample_rate, 16, buffer_size); 116 sample_rate, 16, buffer_size);
108 DCHECK(output_params.IsValid()); 117 DCHECK(output_params.IsValid());
109 118
110 media::AudioRendererMixer* mixer = 119 media::AudioRendererMixer* mixer =
111 new media::AudioRendererMixer(output_params, sink); 120 new media::AudioRendererMixer(output_params, sink);
112 AudioRendererMixerReference mixer_reference = { mixer, 1 }; 121 AudioRendererMixerReference mixer_reference = {mixer, 1, sink.get()};
113 mixers_[key] = mixer_reference; 122 mixers_[key] = mixer_reference;
114 return mixer; 123 return mixer;
115 } 124 }
116 125
117 void AudioRendererMixerManager::RemoveMixer( 126 void AudioRendererMixerManager::ReturnMixer(
118 int source_render_frame_id, 127 int source_render_frame_id,
119 const media::AudioParameters& params, 128 const media::AudioParameters& params,
120 const std::string& device_id, 129 const std::string& device_id,
121 const url::Origin& security_origin) { 130 const url::Origin& security_origin) {
122 const MixerKey key(source_render_frame_id, params, device_id, 131 const MixerKey key(source_render_frame_id, params, device_id,
123 security_origin); 132 security_origin);
124 base::AutoLock auto_lock(mixers_lock_); 133 base::AutoLock auto_lock(mixers_lock_);
125 134
126 AudioRendererMixerMap::iterator it = mixers_.find(key); 135 AudioRendererMixerMap::iterator it = mixers_.find(key);
127 DCHECK(it != mixers_.end()); 136 DCHECK(it != mixers_.end());
128 137
129 // Only remove the mixer if AudioRendererMixerManager is the last owner. 138 // Only remove the mixer if AudioRendererMixerManager is the last owner.
130 it->second.ref_count--; 139 it->second.ref_count--;
131 if (it->second.ref_count == 0) { 140 if (it->second.ref_count == 0) {
141 // The mixer will be deleted now, so release the sink.
142 sink_cache_->ReleaseSink(it->second.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
OLDNEW
« no previous file with comments | « content/renderer/media/audio_renderer_mixer_manager.h ('k') | content/renderer/media/audio_renderer_mixer_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698