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

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: Rebase, fix for sleep() compile error on win and a bit of cleanup around timeouts. Created 4 years, 7 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 // static
22 std::unique_ptr<AudioRendererMixerManager> AudioRendererMixerManager::Create() {
23 return base::WrapUnique(
24 new AudioRendererMixerManager(AudioRendererSinkCache::CreateDefault()));
25 }
26
27 AudioRendererMixerManager::AudioRendererMixerManager(
28 std::unique_ptr<AudioRendererSinkCache> sink_cache)
29 : sink_cache_(std::move(sink_cache)) {}
miu 2016/05/12 21:53:06 nit: Looks like all the code assumes |sink_cache_|
o1ka 2016/05/17 17:17:23 Done.
21 30
22 AudioRendererMixerManager::~AudioRendererMixerManager() { 31 AudioRendererMixerManager::~AudioRendererMixerManager() {
23 // References to AudioRendererMixers may be owned by garbage collected 32 // References to AudioRendererMixers may be owned by garbage collected
24 // objects. During process shutdown they may be leaked, so, transitively, 33 // 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. 34 // |mixers_| may leak (i.e., may be non-empty at this time) as well.
26 } 35 }
27 36
28 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput( 37 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput(
29 int source_render_frame_id, 38 int source_render_frame_id,
30 int session_id, 39 int session_id,
31 const std::string& device_id, 40 const std::string& device_id,
32 const url::Origin& security_origin) { 41 const url::Origin& security_origin) {
33 // base::Unretained() is safe since AudioRendererMixerManager lives on the 42 // base::Unretained() is safe since AudioRendererMixerManager lives on the
34 // renderer thread and is destroyed on renderer thread destruction. 43 // renderer thread and is destroyed on renderer thread destruction.
35 return new media::AudioRendererMixerInput( 44 return new media::AudioRendererMixerInput(
36 base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this), 45 base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this),
37 source_render_frame_id), 46 source_render_frame_id),
38 base::Bind(&AudioRendererMixerManager::RemoveMixer, 47 base::Bind(&AudioRendererMixerManager::RemoveMixer,
39 base::Unretained(this), source_render_frame_id), 48 base::Unretained(this), source_render_frame_id),
49 base::Bind(&AudioRendererMixerManager::GetOutputDeviceInfo,
50 base::Unretained(this), source_render_frame_id, 0 /*sink id*/),
40 media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id, 51 media::AudioDeviceDescription::UseSessionIdToSelectDevice(session_id,
41 device_id) 52 device_id)
42 ? AudioDeviceFactory::GetOutputDeviceInfo( 53 ? sink_cache_
chcunningham 2016/05/12 19:56:31 Can you make this call AudioRendererMixerManager::
o1ka 2016/05/17 17:17:23 Done.
43 source_render_frame_id, session_id, device_id, security_origin) 54 ->GetSinkInfo(source_render_frame_id, session_id, device_id,
55 security_origin)
44 .device_id() 56 .device_id()
45 : device_id, 57 : device_id,
46 security_origin); 58 security_origin);
47 } 59 }
48 60
49 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( 61 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
50 int source_render_frame_id, 62 int source_render_frame_id,
51 const media::AudioParameters& params, 63 const media::AudioParameters& params,
52 const std::string& device_id, 64 const std::string& device_id,
53 const url::Origin& security_origin, 65 const url::Origin& security_origin,
54 media::OutputDeviceStatus* device_status) { 66 media::OutputDeviceStatus* device_status) {
55 // Effects are not passed through to output creation, so ensure none are set. 67 // Effects are not passed through to output creation, so ensure none are set.
56 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS); 68 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS);
57 69
58 const MixerKey key(source_render_frame_id, params, device_id, 70 const MixerKey key(source_render_frame_id, params, device_id,
59 security_origin); 71 security_origin);
60 base::AutoLock auto_lock(mixers_lock_); 72 base::AutoLock auto_lock(mixers_lock_);
61 73
62 AudioRendererMixerMap::iterator it = mixers_.find(key); 74 AudioRendererMixerMap::iterator it = mixers_.find(key);
63 if (it != mixers_.end()) { 75 if (it != mixers_.end()) {
64 if (device_status) 76 if (device_status)
65 *device_status = media::OUTPUT_DEVICE_STATUS_OK; 77 *device_status = media::OUTPUT_DEVICE_STATUS_OK;
66 78
67 it->second.ref_count++; 79 it->second.ref_count++;
68 return it->second.mixer; 80 return it->second.mixer;
69 } 81 }
70 82
71 scoped_refptr<media::AudioRendererSink> sink = 83 media::AudioRendererSink* sink =
72 AudioDeviceFactory::NewAudioRendererMixerSink(source_render_frame_id, 0, 84 sink_cache_->GetSink(source_render_frame_id, device_id, security_origin);
73 device_id, security_origin);
74 85
75 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo(); 86 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo();
76 if (device_status) 87 if (device_status)
77 *device_status = device_info.device_status(); 88 *device_status = device_info.device_status();
78 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) { 89 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) {
79 sink->Stop(); 90 sink_cache_->ReleaseSink(sink);
80 return nullptr; 91 return nullptr;
81 } 92 }
82 93
83 // On ChromeOS as well as when a fake device is used, we can rely on the 94 // 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. 95 // playback device to handle resampling, so don't waste cycles on it here.
85 int sample_rate = params.sample_rate(); 96 int sample_rate = params.sample_rate();
86 int buffer_size = 97 int buffer_size =
87 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0); 98 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0);
88 99
89 #if !defined(OS_CHROMEOS) 100 #if !defined(OS_CHROMEOS)
(...skipping 10 matching lines...) Expand all
100 #endif 111 #endif
101 112
102 // Create output parameters based on the audio hardware configuration for 113 // 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 114 // 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. 115 // know that works everywhere; ChromeOS does not support other bit depths.
105 media::AudioParameters output_params( 116 media::AudioParameters output_params(
106 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(), 117 media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(),
107 sample_rate, 16, buffer_size); 118 sample_rate, 16, buffer_size);
108 DCHECK(output_params.IsValid()); 119 DCHECK(output_params.IsValid());
109 120
110 media::AudioRendererMixer* mixer = 121 // |sink_cache_| will outlive any mixers, so it's fine to use Unretained().
chcunningham 2016/05/12 19:56:31 I'm not sure sink_cache_ really will outlive mixer
o1ka 2016/05/17 17:17:23 I made some changes around that, mostly because if
111 new media::AudioRendererMixer(output_params, sink); 122 media::AudioRendererMixer* mixer = new media::AudioRendererMixer(
123 output_params, sink, base::Bind(&AudioRendererSinkCache::ReleaseSink,
124 base::Unretained(sink_cache_.get())));
112 AudioRendererMixerReference mixer_reference = { mixer, 1 }; 125 AudioRendererMixerReference mixer_reference = { mixer, 1 };
113 mixers_[key] = mixer_reference; 126 mixers_[key] = mixer_reference;
114 return mixer; 127 return mixer;
115 } 128 }
116 129
117 void AudioRendererMixerManager::RemoveMixer( 130 void AudioRendererMixerManager::RemoveMixer(
118 int source_render_frame_id, 131 int source_render_frame_id,
119 const media::AudioParameters& params, 132 const media::AudioParameters& params,
120 const std::string& device_id, 133 const std::string& device_id,
121 const url::Origin& security_origin) { 134 const url::Origin& security_origin) {
122 const MixerKey key(source_render_frame_id, params, device_id, 135 const MixerKey key(source_render_frame_id, params, device_id,
123 security_origin); 136 security_origin);
124 base::AutoLock auto_lock(mixers_lock_); 137 base::AutoLock auto_lock(mixers_lock_);
125 138
126 AudioRendererMixerMap::iterator it = mixers_.find(key); 139 AudioRendererMixerMap::iterator it = mixers_.find(key);
127 DCHECK(it != mixers_.end()); 140 DCHECK(it != mixers_.end());
128 141
129 // Only remove the mixer if AudioRendererMixerManager is the last owner. 142 // Only remove the mixer if AudioRendererMixerManager is the last owner.
130 it->second.ref_count--; 143 it->second.ref_count--;
131 if (it->second.ref_count == 0) { 144 if (it->second.ref_count == 0) {
132 delete it->second.mixer; 145 delete it->second.mixer;
133 mixers_.erase(it); 146 mixers_.erase(it);
134 } 147 }
135 } 148 }
136 149
150 media::OutputDeviceInfo AudioRendererMixerManager::GetOutputDeviceInfo(
151 int source_render_frame_id,
152 int session_id,
153 const std::string& device_id,
154 const url::Origin& security_origin) {
155 return sink_cache_->GetSinkInfo(source_render_frame_id, session_id, device_id,
156 security_origin);
157 }
158
137 AudioRendererMixerManager::MixerKey::MixerKey( 159 AudioRendererMixerManager::MixerKey::MixerKey(
138 int source_render_frame_id, 160 int source_render_frame_id,
139 const media::AudioParameters& params, 161 const media::AudioParameters& params,
140 const std::string& device_id, 162 const std::string& device_id,
141 const url::Origin& security_origin) 163 const url::Origin& security_origin)
142 : source_render_frame_id(source_render_frame_id), 164 : source_render_frame_id(source_render_frame_id),
143 params(params), 165 params(params),
144 device_id(device_id), 166 device_id(device_id),
145 security_origin(security_origin) {} 167 security_origin(security_origin) {}
146 168
147 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default; 169 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default;
148 170
149 } // namespace content 171 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698