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

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: Replace RestartableAudioRendererSink with SwitchableAudioRendererSink in webmediaplayer_impl unit t… 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, 37 base::Bind(&AudioRendererMixerManager::GetOutputDevice,
39 source_render_frame_id, 0), // Session id is 0. 38 source_render_frame_id, 0), // Session id is 0.
40 device_id, 39 device_id,
41 security_origin); 40 security_origin);
42 } 41 }
43 42
44 void AudioRendererMixerManager::SetAudioRendererSinkForTesting(
45 media::AudioRendererSink* sink) {
46 sink_for_testing_ = sink;
47 }
48
49 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer( 43 media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
50 int source_render_frame_id, 44 int source_render_frame_id,
51 const media::AudioParameters& params, 45 const media::AudioParameters& params,
52 const std::string& device_id, 46 const std::string& device_id,
53 const url::Origin& security_origin, 47 const url::Origin& security_origin,
54 media::OutputDeviceStatus* device_status) { 48 media::OutputDeviceStatus* device_status) {
55 // Effects are not passed through to output creation, so ensure none are set. 49 // Effects are not passed through to output creation, so ensure none are set.
56 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS); 50 DCHECK_EQ(params.effects(), media::AudioParameters::NO_EFFECTS);
57 51
58 const MixerKey key(source_render_frame_id, params, device_id, 52 const MixerKey key(source_render_frame_id, params, device_id,
59 security_origin); 53 security_origin);
60 base::AutoLock auto_lock(mixers_lock_); 54 base::AutoLock auto_lock(mixers_lock_);
61 55
62 AudioRendererMixerMap::iterator it = mixers_.find(key); 56 AudioRendererMixerMap::iterator it = mixers_.find(key);
63 if (it != mixers_.end()) { 57 if (it != mixers_.end()) {
64 if (device_status) 58 if (device_status)
65 *device_status = media::OUTPUT_DEVICE_STATUS_OK; 59 *device_status = media::OUTPUT_DEVICE_STATUS_OK;
66 60
67 it->second.ref_count++; 61 it->second.ref_count++;
68 return it->second.mixer; 62 return it->second.mixer;
69 } 63 }
70 64
71 scoped_refptr<media::AudioRendererSink> sink = 65 scoped_refptr<media::AudioRendererSink> sink =
72 sink_for_testing_ 66 AudioDeviceFactory::NewAudioRendererMixerSink(source_render_frame_id, 0,
73 ? sink_for_testing_ 67 device_id, security_origin);
74 : AudioDeviceFactory::NewOutputDevice(source_render_frame_id, 0,
75 device_id, security_origin)
76 .get();
77 68
69 media::OutputDevice* device = sink->GetOutputDevice();
78 media::OutputDeviceStatus new_device_status = 70 media::OutputDeviceStatus new_device_status =
79 sink->GetOutputDevice()->GetDeviceStatus(); 71 device ? device->GetDeviceStatus()
72 : media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL;
80 if (device_status) 73 if (device_status)
81 *device_status = new_device_status; 74 *device_status = new_device_status;
82 if (new_device_status != media::OUTPUT_DEVICE_STATUS_OK) { 75 if (new_device_status != media::OUTPUT_DEVICE_STATUS_OK) {
83 sink->Stop(); 76 sink->Stop();
84 return nullptr; 77 return nullptr;
85 } 78 }
86 79
87 // On ChromeOS as well as when a fake device is used, we can rely on the 80 // 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. 81 // playback device to handle resampling, so don't waste cycles on it here.
89 int sample_rate = params.sample_rate(); 82 int sample_rate = params.sample_rate();
90 int buffer_size = 83 int buffer_size =
91 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0); 84 media::AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, 0);
92 85
93 #if !defined(OS_CHROMEOS) 86 #if !defined(OS_CHROMEOS)
94 media::AudioParameters hardware_params = 87 media::AudioParameters hardware_params = device->GetOutputParameters();
95 sink->GetOutputDevice()->GetOutputParameters();
96 88
97 // If we have valid, non-fake hardware parameters, use them. Otherwise, pass 89 // 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. 90 // on the input params and let the browser side handle automatic fallback.
99 if (hardware_params.format() != media::AudioParameters::AUDIO_FAKE && 91 if (hardware_params.format() != media::AudioParameters::AUDIO_FAKE &&
100 hardware_params.IsValid()) { 92 hardware_params.IsValid()) {
101 sample_rate = hardware_params.sample_rate(); 93 sample_rate = hardware_params.sample_rate();
102 buffer_size = media::AudioHardwareConfig::GetHighLatencyBufferSize( 94 buffer_size = media::AudioHardwareConfig::GetHighLatencyBufferSize(
103 sample_rate, hardware_params.frames_per_buffer()); 95 sample_rate, hardware_params.frames_per_buffer());
104 } 96 }
105 #endif 97 #endif
(...skipping 27 matching lines...) Expand all
133 125
134 // Only remove the mixer if AudioRendererMixerManager is the last owner. 126 // Only remove the mixer if AudioRendererMixerManager is the last owner.
135 it->second.ref_count--; 127 it->second.ref_count--;
136 if (it->second.ref_count == 0) { 128 if (it->second.ref_count == 0) {
137 delete it->second.mixer; 129 delete it->second.mixer;
138 mixers_.erase(it); 130 mixers_.erase(it);
139 } 131 }
140 } 132 }
141 133
142 // static 134 // static
143 media::AudioParameters AudioRendererMixerManager::GetHardwareOutputParams( 135 media::OutputDevice* AudioRendererMixerManager::GetOutputDevice(
Guido Urdaneta 2016/03/17 17:38:24 Why have this method at all. The implementation su
o1ka 2016/03/18 10:45:40 It's a part of a future CL which leaked in; removi
144 int render_frame_id, 136 int render_frame_id,
145 int session_id, 137 int session_id,
146 const std::string& device_id, 138 const std::string& device_id,
147 const url::Origin& security_origin) { 139 const url::Origin& security_origin) {
148 media::AudioParameters params; // Invalid parameters to return by default. 140 // TODO(olka): First try to lookup an existing device (cached or belonging
141 // to some mixer) and reuse it. If non exists - create new and cache it.
142 // http://crbug.com/586161;
149 143
150 // TODO(olka): First try to lookup an existing device (cached or belonging 144 // We can't get here until we start using mixer inputs as sinks for
151 // to some mixer) and reuse it. http://crbug.com/586161 145 // non-mediaelement sources.
146 NOTREACHED();
152 147
153 // AudioOutputDevice is the only interface we have to communicate with output 148 return nullptr;
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 } 149 }
166 150
167 AudioRendererMixerManager::MixerKey::MixerKey( 151 AudioRendererMixerManager::MixerKey::MixerKey(
168 int source_render_frame_id, 152 int source_render_frame_id,
169 const media::AudioParameters& params, 153 const media::AudioParameters& params,
170 const std::string& device_id, 154 const std::string& device_id,
171 const url::Origin& security_origin) 155 const url::Origin& security_origin)
172 : source_render_frame_id(source_render_frame_id), 156 : source_render_frame_id(source_render_frame_id),
173 params(params), 157 params(params),
174 device_id(device_id), 158 device_id(device_id),
175 security_origin(security_origin) {} 159 security_origin(security_origin) {}
176 160
177 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default; 161 AudioRendererMixerManager::MixerKey::MixerKey(const MixerKey& other) = default;
178 162
179 } // namespace content 163 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698