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

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

Issue 1809093003: Moving SwitchOutputDevice out of OutputDevice interface, eliminating OutputDevice (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing guidou's comments Created 4 years, 9 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 "build/build_config.h" 11 #include "build/build_config.h"
12 #include "content/renderer/media/audio_device_factory.h" 12 #include "content/renderer/media/audio_device_factory.h"
13 #include "media/audio/audio_output_device.h" 13 #include "media/audio/audio_output_device.h"
14 #include "media/base/audio_hardware_config.h" 14 #include "media/base/audio_hardware_config.h"
15 #include "media/base/audio_renderer_mixer.h" 15 #include "media/base/audio_renderer_mixer.h"
16 #include "media/base/audio_renderer_mixer_input.h" 16 #include "media/base/audio_renderer_mixer_input.h"
17 17
18 namespace content { 18 namespace content {
19 19
20 AudioRendererMixerManager::AudioRendererMixerManager() 20 AudioRendererMixerManager::AudioRendererMixerManager() {}
21 : sink_for_testing_(nullptr) {}
22 21
23 AudioRendererMixerManager::~AudioRendererMixerManager() { 22 AudioRendererMixerManager::~AudioRendererMixerManager() {
24 // References to AudioRendererMixers may be owned by garbage collected 23 // References to AudioRendererMixers may be owned by garbage collected
25 // objects. During process shutdown they may be leaked, so, transitively, 24 // objects. During process shutdown they may be leaked, so, transitively,
26 // |mixers_| may leak (i.e., may be non-empty at this time) as well. 25 // |mixers_| may leak (i.e., may be non-empty at this time) as well.
27 } 26 }
28 27
29 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput( 28 media::AudioRendererMixerInput* AudioRendererMixerManager::CreateInput(
30 int source_render_frame_id, 29 int source_render_frame_id,
31 const std::string& device_id, 30 const std::string& device_id,
32 const url::Origin& security_origin) { 31 const url::Origin& security_origin) {
33 return new media::AudioRendererMixerInput( 32 return new media::AudioRendererMixerInput(
34 base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this), 33 base::Bind(&AudioRendererMixerManager::GetMixer, base::Unretained(this),
35 source_render_frame_id), 34 source_render_frame_id),
36 base::Bind(&AudioRendererMixerManager::RemoveMixer, 35 base::Bind(&AudioRendererMixerManager::RemoveMixer,
37 base::Unretained(this), source_render_frame_id), 36 base::Unretained(this), source_render_frame_id),
38 base::Bind(&AudioRendererMixerManager::GetHardwareOutputParams,
39 source_render_frame_id, 0), // Session id is 0.
40 device_id, 37 device_id,
41 security_origin); 38 security_origin);
42 } 39 }
43 40
44 void AudioRendererMixerManager::SetAudioRendererSinkForTesting(
45 media::AudioRendererSink* sink) {
46 sink_for_testing_ = sink;
47 }
48
49 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( 41 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
50 int source_render_frame_id, 42 int source_render_frame_id,
51 const media::AudioParameters& params, 43 const media::AudioParameters& params,
52 const std::string& device_id, 44 const std::string& device_id,
53 const url::Origin& security_origin, 45 const url::Origin& security_origin,
54 media::OutputDeviceStatus* device_status) { 46 media::OutputDeviceStatus* device_status) {
55 // Effects are not passed through to output creation, so ensure none are set. 47 // Effects are not passed through to output creation, so ensure none are set.
56 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS); 48 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS);
57 49
58 const MixerKey key(source_render_frame_id, params, device_id, 50 const MixerKey key(source_render_frame_id, params, device_id,
59 security_origin); 51 security_origin);
60 base::AutoLock auto_lock(mixers_lock_); 52 base::AutoLock auto_lock(mixers_lock_);
61 53
62 AudioRendererMixerMap::iterator it = mixers_.find(key); 54 AudioRendererMixerMap::iterator it = mixers_.find(key);
63 if (it != mixers_.end()) { 55 if (it != mixers_.end()) {
64 if (device_status) 56 if (device_status)
65 *device_status = media::OUTPUT_DEVICE_STATUS_OK; 57 *device_status = media::OUTPUT_DEVICE_STATUS_OK;
66 58
67 it->second.ref_count++; 59 it->second.ref_count++;
68 return it->second.mixer; 60 return it->second.mixer;
69 } 61 }
70 62
71 scoped_refptr<media::AudioRendererSink> sink = 63 scoped_refptr<media::AudioRendererSink> sink =
72 sink_for_testing_ 64 AudioDeviceFactory::NewAudioRendererMixerSink(source_render_frame_id, 0,
miu 2016/03/24 21:32:02 MUCH cleaner! Thanks for fixing this. :)
73 ? sink_for_testing_ 65 device_id, security_origin);
74 : AudioDeviceFactory::NewOutputDevice(source_render_frame_id, 0,
75 device_id, security_origin)
76 .get();
77 66
78 media::OutputDeviceStatus new_device_status = 67 const media::OutputDeviceInfo& device_info = sink->GetOutputDeviceInfo();
79 sink->GetOutputDevice()->GetDeviceStatus();
80 if (device_status) 68 if (device_status)
81 *device_status = new_device_status; 69 *device_status = device_info.device_status();
82 if (new_device_status != media::OUTPUT_DEVICE_STATUS_OK) { 70 if (device_info.device_status() != media::OUTPUT_DEVICE_STATUS_OK) {
83 sink->Stop(); 71 sink->Stop();
84 return nullptr; 72 return nullptr;
85 } 73 }
86 74
87 // On ChromeOS as well as when a fake device is used, we can rely on the 75 // On ChromeOS as well as when a fake device is used, we can rely on the
88 // playback device to handle resampling, so don't waste cycles on it here. 76 // playback device to handle resampling, so don't waste cycles on it here.
89 int sample_rate = params.sample_rate(); 77 int sample_rate = params.sample_rate();
90 int buffer_size = 78 int buffer_size =
91 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0); 79 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0);
92 80
93 #if !defined(OS_CHROMEOS) 81 #if !defined(OS_CHROMEOS)
94 media::AudioParameters hardware_params = 82 const media::AudioParameters& hardware_params = device_info.output_params();
95 sink->GetOutputDevice()->GetOutputParameters();
96 83
97 // If we have valid, non-fake hardware parameters, use them. Otherwise, pass 84 // If we have valid, non-fake hardware parameters, use them. Otherwise, pass
98 // on the input params and let the browser side handle automatic fallback. 85 // on the input params and let the browser side handle automatic fallback.
99 if (hardware_params.format() != media::AudioParameters::AUDIO_FAKE && 86 if (hardware_params.format() != media::AudioParameters::AUDIO_FAKE &&
100 hardware_params.IsValid()) { 87 hardware_params.IsValid()) {
101 sample_rate = hardware_params.sample_rate(); 88 sample_rate = hardware_params.sample_rate();
102 buffer_size = media::AudioHardwareConfig::GetHighLatencyBufferSize( 89 buffer_size = media::AudioHardwareConfig::GetHighLatencyBufferSize(
103 sample_rate, hardware_params.frames_per_buffer()); 90 sample_rate, hardware_params.frames_per_buffer());
104 } 91 }
105 #endif 92 #endif
(...skipping 26 matching lines...) Expand all
132 DCHECK(it != mixers_.end()); 119 DCHECK(it != mixers_.end());
133 120
134 // Only remove the mixer if AudioRendererMixerManager is the last owner. 121 // Only remove the mixer if AudioRendererMixerManager is the last owner.
135 it->second.ref_count--; 122 it->second.ref_count--;
136 if (it->second.ref_count == 0) { 123 if (it->second.ref_count == 0) {
137 delete it->second.mixer; 124 delete it->second.mixer;
138 mixers_.erase(it); 125 mixers_.erase(it);
139 } 126 }
140 } 127 }
141 128
142 // static
143 media::AudioParameters AudioRendererMixerManager::GetHardwareOutputParams(
144 int render_frame_id,
145 int session_id,
146 const std::string& device_id,
147 const url::Origin& security_origin) {
148 media::AudioParameters params; // Invalid parameters to return by default.
149
150 // TODO(olka): First try to lookup an existing device (cached or belonging
151 // to some mixer) and reuse it. http://crbug.com/586161
152
153 // AudioOutputDevice is the only interface we have to communicate with output
154 // device via IPC. So, that's how we get the parameters when there is no
155 // AudioOutputDevice:
156 scoped_refptr<media::AudioOutputDevice> device =
157 AudioDeviceFactory::NewOutputDevice(render_frame_id, session_id,
158 device_id, security_origin);
159
160 if (device->GetDeviceStatus() == media::OUTPUT_DEVICE_STATUS_OK)
161 params = device->GetOutputParameters();
162
163 device->Stop(); // TODO(olka): temporary cash for future reuse.
164 return params;
165 }
166
167 AudioRendererMixerManager::MixerKey::MixerKey( 129 AudioRendererMixerManager::MixerKey::MixerKey(
168 int source_render_frame_id, 130 int source_render_frame_id,
169 const media::AudioParameters& params, 131 const media::AudioParameters& params,
170 const std::string& device_id, 132 const std::string& device_id,
171 const url::Origin& security_origin) 133 const url::Origin& security_origin)
172 : source_render_frame_id(source_render_frame_id), 134 : source_render_frame_id(source_render_frame_id),
173 params(params), 135 params(params),
174 device_id(device_id), 136 device_id(device_id),
175 security_origin(security_origin) {} 137 security_origin(security_origin) {}
176 138
177 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default; 139 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default;
178 140
179 } // namespace content 141 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698