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

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: dalecurtis@'s comments addressed, build issue fixed 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::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
miu 2016/05/19 22:27:15 This comment is obsolete now.
o1ka 2016/05/23 16:16:54 Done.
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->Stop();
87 sink_cache_->ReleaseSink(source_render_frame_id, device_id, security_origin,
88 sink.get());
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
89 #if !defined(OS_CHROMEOS) 98 #if !defined(OS_CHROMEOS)
(...skipping 17 matching lines...) Expand all
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 };
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(source_render_frame_id, device_id, security_origin,
143 it->second.mixer->sink_ptr());
132 delete it->second.mixer; 144 delete it->second.mixer;
133 mixers_.erase(it); 145 mixers_.erase(it);
134 } 146 }
135 } 147 }
136 148
149 media::OutputDeviceInfo AudioRendererMixerManager::GetOutputDeviceInfo(
150 int source_render_frame_id,
151 int session_id,
152 const std::string& device_id,
153 const url::Origin& security_origin) {
154 return sink_cache_->GetSinkInfo(source_render_frame_id, session_id, device_id,
155 security_origin);
156 }
157
137 AudioRendererMixerManager::MixerKey::MixerKey( 158 AudioRendererMixerManager::MixerKey::MixerKey(
138 int source_render_frame_id, 159 int source_render_frame_id,
139 const media::AudioParameters& params, 160 const media::AudioParameters& params,
140 const std::string& device_id, 161 const std::string& device_id,
141 const url::Origin& security_origin) 162 const url::Origin& security_origin)
142 : source_render_frame_id(source_render_frame_id), 163 : source_render_frame_id(source_render_frame_id),
143 params(params), 164 params(params),
144 device_id(device_id), 165 device_id(device_id),
145 security_origin(security_origin) {} 166 security_origin(security_origin) {}
146 167
147 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default; 168 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default;
148 169
149 } // namespace content 170 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698