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

Side by Side Diff: content/browser/renderer_host/media/audio_input_device_manager.cc

Issue 2763383002: Switching AudioInputDeviceManager from using AudioManager interface to AudioSystem one. (Closed)
Patch Set: (fails on Mac in content_unittests) Created 3 years, 8 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/browser/renderer_host/media/audio_input_device_manager.h" 5 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/common/media_stream_request.h" 14 #include "content/public/common/media_stream_request.h"
15 #include "media/audio/audio_input_ipc.h" 15 #include "media/audio/audio_input_ipc.h"
16 #include "media/audio/audio_manager_base.h" 16 #include "media/audio/audio_system.h"
17 #include "media/base/audio_parameters.h" 17 #include "media/base/audio_parameters.h"
18 #include "media/base/channel_layout.h" 18 #include "media/base/channel_layout.h"
19 #include "media/base/media_switches.h" 19 #include "media/base/media_switches.h"
20 20
21 #if defined(OS_CHROMEOS) 21 #if defined(OS_CHROMEOS)
22 #include "chromeos/audio/cras_audio_handler.h" 22 #include "chromeos/audio/cras_audio_handler.h"
23 #endif 23 #endif
24 24
25 namespace content { 25 namespace content {
26 26
27 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; 27 const int AudioInputDeviceManager::kFakeOpenSessionId = 1;
28 28
29 namespace { 29 namespace {
30 // Starting id for the first capture session. 30 // Starting id for the first capture session.
31 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; 31 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1;
32 } 32 }
33 33
34 AudioInputDeviceManager::AudioInputDeviceManager( 34 AudioInputDeviceManager::AudioInputDeviceManager(
35 media::AudioManager* audio_manager) 35 media::AudioSystem* audio_system)
36 : next_capture_session_id_(kFirstSessionId), 36 : next_capture_session_id_(kFirstSessionId),
37 #if defined(OS_CHROMEOS) 37 #if defined(OS_CHROMEOS)
38 keyboard_mic_streams_count_(0), 38 keyboard_mic_streams_count_(0),
39 #endif 39 #endif
40 audio_manager_(audio_manager), 40 audio_system_(audio_system) {
41 device_task_runner_(audio_manager_->GetTaskRunner()) {
42 } 41 }
43 42
44 AudioInputDeviceManager::~AudioInputDeviceManager() { 43 AudioInputDeviceManager::~AudioInputDeviceManager() {
45 } 44 }
46 45
47 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById( 46 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById(
48 int session_id) { 47 int session_id) {
49 DCHECK_CURRENTLY_ON(BrowserThread::IO); 48 DCHECK_CURRENTLY_ON(BrowserThread::IO);
50 StreamDeviceList::iterator device = GetDevice(session_id); 49 StreamDeviceList::iterator device = GetDevice(session_id);
51 if (device == devices_.end()) 50 if (device == devices_.end())
52 return nullptr; 51 return nullptr;
53 52
54 return &(*device); 53 return &(*device);
55 } 54 }
56 55
57 void AudioInputDeviceManager::RegisterListener( 56 void AudioInputDeviceManager::RegisterListener(
58 MediaStreamProviderListener* listener) { 57 MediaStreamProviderListener* listener) {
59 DCHECK_CURRENTLY_ON(BrowserThread::IO); 58 DCHECK_CURRENTLY_ON(BrowserThread::IO);
60 DCHECK(listener); 59 DCHECK(listener);
61 DCHECK(device_task_runner_);
62 listeners_.AddObserver(listener); 60 listeners_.AddObserver(listener);
63 } 61 }
64 62
65 void AudioInputDeviceManager::UnregisterListener( 63 void AudioInputDeviceManager::UnregisterListener(
66 MediaStreamProviderListener* listener) { 64 MediaStreamProviderListener* listener) {
67 DCHECK_CURRENTLY_ON(BrowserThread::IO); 65 DCHECK_CURRENTLY_ON(BrowserThread::IO);
68 DCHECK(listener); 66 DCHECK(listener);
69 listeners_.RemoveObserver(listener); 67 listeners_.RemoveObserver(listener);
70 } 68 }
71 69
72 int AudioInputDeviceManager::Open(const MediaStreamDevice& device) { 70 int AudioInputDeviceManager::Open(const MediaStreamDevice& device) {
73 DCHECK_CURRENTLY_ON(BrowserThread::IO); 71 DCHECK_CURRENTLY_ON(BrowserThread::IO);
74 // Generate a new id for this device. 72 // Generate a new id for this device.
75 int session_id = next_capture_session_id_++; 73 int session_id = next_capture_session_id_++;
76 device_task_runner_->PostTask( 74
77 FROM_HERE, 75 SCOPED_UMA_HISTOGRAM_TIMER(
78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, 76 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime");
79 this, session_id, device)); 77
78 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
79 switches::kUseFakeDeviceForMediaStream)) {
80 audio_system_->GetAssociatedOutputDeviceID(
Guido Urdaneta 2017/04/03 13:04:38 If the device is fake, does GetAssociatedOutputDev
o1ka 2017/04/05 14:21:22 It gets device association from the AudioManager (
81 device.id,
82 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, this, session_id,
83 device, base::TimeTicks::Now(),
84 media::AudioParameters::UnavailableDeviceParams(),
85 media::AudioParameters::UnavailableDeviceParams()));
86 } else {
87 // TODO(tommi): As is, we hit this code path when device.type is
88 // MEDIA_TAB_AUDIO_CAPTURE and the device id is not a device that
89 // the AudioManager can know about. This currently does not fail because
90 // the implementation of GetInputStreamParameters returns valid parameters
91 // by default for invalid devices. That behavior is problematic because it
92 // causes other parts of the code to attempt to open truly invalid or
93 // missing devices and falling back on alternate devices (and likely fail
94 // twice in a row). Tab audio capture should not pass through here and
95 // GetInputStreamParameters should return invalid parameters for invalid
96 // devices.
97
98 audio_system_->GetInputDeviceInfo(
99 device.id, base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, this,
100 session_id, device, base::TimeTicks::Now()));
101 }
80 102
81 return session_id; 103 return session_id;
82 } 104 }
83 105
84 void AudioInputDeviceManager::Close(int session_id) { 106 void AudioInputDeviceManager::Close(int session_id) {
85 DCHECK_CURRENTLY_ON(BrowserThread::IO); 107 DCHECK_CURRENTLY_ON(BrowserThread::IO);
86 StreamDeviceList::iterator device = GetDevice(session_id); 108 StreamDeviceList::iterator device = GetDevice(session_id);
87 if (device == devices_.end()) 109 if (device == devices_.end())
88 return; 110 return;
89 const MediaStreamType stream_type = device->device.type; 111 const MediaStreamType stream_type = device->device.type;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 BrowserThread::UI, 150 BrowserThread::UI,
129 FROM_HERE, 151 FROM_HERE,
130 base::Bind( 152 base::Bind(
131 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread, 153 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread,
132 this, 154 this,
133 false)); 155 false));
134 } 156 }
135 } 157 }
136 #endif 158 #endif
137 159
138 void AudioInputDeviceManager::OpenOnDeviceThread( 160 void AudioInputDeviceManager::OpenedOnIOThread(
139 int session_id, 161 int session_id,
140 const MediaStreamDevice& device) { 162 const MediaStreamDevice& device,
141 SCOPED_UMA_HISTOGRAM_TIMER( 163 base::TimeTicks start_time,
142 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime"); 164 const media::AudioParameters& input_params,
143 DCHECK(IsOnDeviceThread()); 165 const media::AudioParameters& matched_output_params,
166 const std::string& matched_output_device_id) {
167 DCHECK_CURRENTLY_ON(BrowserThread::IO);
168 DCHECK(GetDevice(session_id) == devices_.end());
144 169
145 StreamDeviceInfo out(device.type, device.name, device.id, 0, 0, 0); 170 UMA_HISTOGRAM_TIMES("Media.AudioInputDeviceManager.OpenOnDeviceThreadTime",
146 out.session_id = session_id; 171 base::TimeTicks::Now() - start_time);
147 172
148 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input; 173 StreamDeviceInfo info(device.type, device.name, device.id);
149 174 info.session_id = session_id;
150 // Add preferred output device information if a matching output device 175 info.device.input.sample_rate = input_params.sample_rate();
151 // exists. 176 info.device.input.channel_layout = input_params.channel_layout();
152 out.device.matched_output_device_id = 177 info.device.input.frames_per_buffer = input_params.frames_per_buffer();
153 audio_manager_->GetAssociatedOutputDeviceID(device.id); 178 info.device.input.effects = input_params.effects();
154 179 info.device.input.mic_positions = input_params.mic_positions();
155 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 180 info.device.matched_output_device_id = matched_output_device_id;
156 switches::kUseFakeDeviceForMediaStream)) { 181 info.device.matched_output.sample_rate = matched_output_params.sample_rate();
157 // Don't need to query the hardware information if using fake device. 182 info.device.matched_output.channel_layout =
158 input_params.sample_rate = 44100; 183 matched_output_params.channel_layout();
159 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO; 184 info.device.matched_output.frames_per_buffer =
160 if (!out.device.matched_output_device_id.empty()) { 185 matched_output_params.frames_per_buffer();
161 out.device.matched_output.sample_rate = 44100; 186 info.device.matched_output.effects = matched_output_params.effects();
162 out.device.matched_output.channel_layout = media::CHANNEL_LAYOUT_STEREO;
163 }
164 } else {
165 // TODO(tommi): As is, we hit this code path when device.type is
166 // MEDIA_TAB_AUDIO_CAPTURE and the device id is not a device that
167 // the AudioManager can know about. This currently does not fail because
168 // the implementation of GetInputStreamParameters returns valid parameters
169 // by default for invalid devices. That behavior is problematic because it
170 // causes other parts of the code to attempt to open truly invalid or
171 // missing devices and falling back on alternate devices (and likely fail
172 // twice in a row). Tab audio capture should not pass through here and
173 // GetInputStreamParameters should return invalid parameters for invalid
174 // devices.
175
176 // Get the preferred sample rate and channel configuration for the
177 // audio device.
178 media::AudioParameters params =
179 audio_manager_->GetInputStreamParameters(device.id);
180 input_params.sample_rate = params.sample_rate();
181 input_params.channel_layout = params.channel_layout();
182 input_params.frames_per_buffer = params.frames_per_buffer();
183 input_params.effects = params.effects();
184 input_params.mic_positions = params.mic_positions();
185 if (!out.device.matched_output_device_id.empty()) {
186 params = audio_manager_->GetOutputStreamParameters(
187 out.device.matched_output_device_id);
188 MediaStreamDevice::AudioDeviceParameters& matched_output_params =
189 out.device.matched_output;
190 matched_output_params.sample_rate = params.sample_rate();
191 matched_output_params.channel_layout = params.channel_layout();
192 matched_output_params.frames_per_buffer = params.frames_per_buffer();
193 }
194 }
195
196 // Return the |session_id| through the listener by posting a task on
197 // IO thread since MediaStreamManager handles the callback asynchronously.
198 BrowserThread::PostTask(BrowserThread::IO,
199 FROM_HERE,
200 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread,
201 this, session_id, out));
202 }
203
204 void AudioInputDeviceManager::OpenedOnIOThread(int session_id,
205 const StreamDeviceInfo& info) {
206 DCHECK_CURRENTLY_ON(BrowserThread::IO);
207 DCHECK_EQ(session_id, info.session_id);
208 DCHECK(GetDevice(session_id) == devices_.end());
209 187
210 devices_.push_back(info); 188 devices_.push_back(info);
211 189
212 for (auto& listener : listeners_) 190 for (auto& listener : listeners_)
213 listener.Opened(info.device.type, session_id); 191 listener.Opened(info.device.type, session_id);
214 } 192 }
215 193
216 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, 194 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type,
217 int session_id) { 195 int session_id) {
218 DCHECK_CURRENTLY_ON(BrowserThread::IO); 196 DCHECK_CURRENTLY_ON(BrowserThread::IO);
219 for (auto& listener : listeners_) 197 for (auto& listener : listeners_)
220 listener.Closed(stream_type, session_id); 198 listener.Closed(stream_type, session_id);
221 } 199 }
222 200
Guido Urdaneta 2017/04/03 13:04:38 remove vertical whitespace
o1ka 2017/04/05 14:21:22 Done.
223 bool AudioInputDeviceManager::IsOnDeviceThread() const {
224 return device_task_runner_->BelongsToCurrentThread();
225 }
226 201
227 AudioInputDeviceManager::StreamDeviceList::iterator 202 AudioInputDeviceManager::StreamDeviceList::iterator
228 AudioInputDeviceManager::GetDevice(int session_id) { 203 AudioInputDeviceManager::GetDevice(int session_id) {
229 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end(); 204 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end();
230 ++i) { 205 ++i) {
231 if (i->session_id == session_id) 206 if (i->session_id == session_id)
232 return i; 207 return i;
233 } 208 }
234 209
235 return devices_.end(); 210 return devices_.end();
236 } 211 }
237 212
238 #if defined(OS_CHROMEOS) 213 #if defined(OS_CHROMEOS)
239 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread( 214 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread(
240 bool active) { 215 bool active) {
241 DCHECK_CURRENTLY_ON(BrowserThread::UI); 216 DCHECK_CURRENTLY_ON(BrowserThread::UI);
242 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active); 217 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active);
243 } 218 }
244 #endif 219 #endif
245 220
246
247 } // namespace content 221 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698