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

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

Issue 2729783003: [Mojo Video Capture] Add content_browsertest for exercising video capture (Closed)
Patch Set: miguel@ suggestions Created 3 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/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"
(...skipping 15 matching lines...) Expand all
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::AudioManager* audio_manager)
36 : listener_(nullptr), 36 : next_capture_session_id_(kFirstSessionId),
37 next_capture_session_id_(kFirstSessionId),
38 #if defined(OS_CHROMEOS) 37 #if defined(OS_CHROMEOS)
39 keyboard_mic_streams_count_(0), 38 keyboard_mic_streams_count_(0),
40 #endif 39 #endif
41 audio_manager_(audio_manager), 40 audio_manager_(audio_manager),
42 device_task_runner_(audio_manager_->GetTaskRunner()) { 41 device_task_runner_(audio_manager_->GetTaskRunner()) {
43 } 42 }
44 43
45 AudioInputDeviceManager::~AudioInputDeviceManager() { 44 AudioInputDeviceManager::~AudioInputDeviceManager() {
46 } 45 }
47 46
48 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById( 47 const StreamDeviceInfo* AudioInputDeviceManager::GetOpenedDeviceInfoById(
49 int session_id) { 48 int session_id) {
50 DCHECK_CURRENTLY_ON(BrowserThread::IO); 49 DCHECK_CURRENTLY_ON(BrowserThread::IO);
51 StreamDeviceList::iterator device = GetDevice(session_id); 50 StreamDeviceList::iterator device = GetDevice(session_id);
52 if (device == devices_.end()) 51 if (device == devices_.end())
53 return nullptr; 52 return nullptr;
54 53
55 return &(*device); 54 return &(*device);
56 } 55 }
57 56
58 void AudioInputDeviceManager::RegisterListener( 57 void AudioInputDeviceManager::RegisterListener(
59 MediaStreamProviderListener* listener) { 58 MediaStreamProviderListener* listener) {
60 DCHECK_CURRENTLY_ON(BrowserThread::IO); 59 DCHECK_CURRENTLY_ON(BrowserThread::IO);
61 DCHECK(!listener_); 60 DCHECK(listener);
62 DCHECK(device_task_runner_); 61 DCHECK(device_task_runner_);
63 listener_ = listener; 62 listeners_.AddObserver(listener);
64 } 63 }
65 64
66 void AudioInputDeviceManager::UnregisterListener() { 65 void AudioInputDeviceManager::UnregisterListener(
66 MediaStreamProviderListener* listener) {
67 DCHECK_CURRENTLY_ON(BrowserThread::IO); 67 DCHECK_CURRENTLY_ON(BrowserThread::IO);
68 DCHECK(listener_); 68 DCHECK(listener);
69 listener_ = nullptr; 69 listeners_.RemoveObserver(listener);
70 } 70 }
71 71
72 int AudioInputDeviceManager::Open(const StreamDeviceInfo& device) { 72 int AudioInputDeviceManager::Open(const MediaStreamDevice& device) {
73 DCHECK_CURRENTLY_ON(BrowserThread::IO); 73 DCHECK_CURRENTLY_ON(BrowserThread::IO);
74 // Generate a new id for this device. 74 // Generate a new id for this device.
75 int session_id = next_capture_session_id_++; 75 int session_id = next_capture_session_id_++;
76 device_task_runner_->PostTask( 76 device_task_runner_->PostTask(
77 FROM_HERE, 77 FROM_HERE,
78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, 78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread,
79 this, session_id, device)); 79 this, session_id, device));
80 80
81 return session_id; 81 return session_id;
82 } 82 }
83 83
84 void AudioInputDeviceManager::Close(int session_id) { 84 void AudioInputDeviceManager::Close(int session_id) {
85 DCHECK_CURRENTLY_ON(BrowserThread::IO); 85 DCHECK_CURRENTLY_ON(BrowserThread::IO);
86 DCHECK(listener_); 86 DCHECK(listeners_.might_have_observers());
miu 2017/03/06 21:54:10 This is weird. Why would a Close() operation requi
chfremer 2017/03/06 23:39:38 removed
87 StreamDeviceList::iterator device = GetDevice(session_id); 87 StreamDeviceList::iterator device = GetDevice(session_id);
88 if (device == devices_.end()) 88 if (device == devices_.end())
89 return; 89 return;
90 const MediaStreamType stream_type = device->device.type; 90 const MediaStreamType stream_type = device->device.type;
91 if (session_id != kFakeOpenSessionId) 91 if (session_id != kFakeOpenSessionId)
92 devices_.erase(device); 92 devices_.erase(device);
93 93
94 // Post a callback through the listener on IO thread since 94 // Post a callback through the listener on IO thread since
95 // MediaStreamManager is expecting the callback asynchronously. 95 // MediaStreamManager is expecting the callback asynchronously.
96 BrowserThread::PostTask(BrowserThread::IO, 96 BrowserThread::PostTask(BrowserThread::IO,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 FROM_HERE, 130 FROM_HERE,
131 base::Bind( 131 base::Bind(
132 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread, 132 &AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread,
133 this, 133 this,
134 false)); 134 false));
135 } 135 }
136 } 136 }
137 #endif 137 #endif
138 138
139 void AudioInputDeviceManager::OpenOnDeviceThread( 139 void AudioInputDeviceManager::OpenOnDeviceThread(
140 int session_id, const StreamDeviceInfo& info) { 140 int session_id,
141 const MediaStreamDevice& device) {
141 SCOPED_UMA_HISTOGRAM_TIMER( 142 SCOPED_UMA_HISTOGRAM_TIMER(
142 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime"); 143 "Media.AudioInputDeviceManager.OpenOnDeviceThreadTime");
143 DCHECK(IsOnDeviceThread()); 144 DCHECK(IsOnDeviceThread());
144 145
145 StreamDeviceInfo out(info.device.type, info.device.name, info.device.id, 0, 0, 146 StreamDeviceInfo out(device.type, device.name, device.id, 0, 0, 0);
146 0);
147 out.session_id = session_id; 147 out.session_id = session_id;
148 148
149 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input; 149 MediaStreamDevice::AudioDeviceParameters& input_params = out.device.input;
150 150
151 // Add preferred output device information if a matching output device 151 // Add preferred output device information if a matching output device
152 // exists. 152 // exists.
153 out.device.matched_output_device_id = 153 out.device.matched_output_device_id =
154 audio_manager_->GetAssociatedOutputDeviceID(info.device.id); 154 audio_manager_->GetAssociatedOutputDeviceID(device.id);
155 155
156 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 156 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
157 switches::kUseFakeDeviceForMediaStream)) { 157 switches::kUseFakeDeviceForMediaStream)) {
158 // Don't need to query the hardware information if using fake device. 158 // Don't need to query the hardware information if using fake device.
159 input_params.sample_rate = 44100; 159 input_params.sample_rate = 44100;
160 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO; 160 input_params.channel_layout = media::CHANNEL_LAYOUT_STEREO;
161 if (!out.device.matched_output_device_id.empty()) { 161 if (!out.device.matched_output_device_id.empty()) {
162 out.device.matched_output.sample_rate = 44100; 162 out.device.matched_output.sample_rate = 44100;
163 out.device.matched_output.channel_layout = media::CHANNEL_LAYOUT_STEREO; 163 out.device.matched_output.channel_layout = media::CHANNEL_LAYOUT_STEREO;
164 } 164 }
165 } else { 165 } else {
166 // TODO(tommi): As is, we hit this code path when device.type is 166 // TODO(tommi): As is, we hit this code path when device.type is
167 // MEDIA_TAB_AUDIO_CAPTURE and the device id is not a device that 167 // MEDIA_TAB_AUDIO_CAPTURE and the device id is not a device that
168 // the AudioManager can know about. This currently does not fail because 168 // the AudioManager can know about. This currently does not fail because
169 // the implementation of GetInputStreamParameters returns valid parameters 169 // the implementation of GetInputStreamParameters returns valid parameters
170 // by default for invalid devices. That behavior is problematic because it 170 // by default for invalid devices. That behavior is problematic because it
171 // causes other parts of the code to attempt to open truly invalid or 171 // causes other parts of the code to attempt to open truly invalid or
172 // missing devices and falling back on alternate devices (and likely fail 172 // missing devices and falling back on alternate devices (and likely fail
173 // twice in a row). Tab audio capture should not pass through here and 173 // twice in a row). Tab audio capture should not pass through here and
174 // GetInputStreamParameters should return invalid parameters for invalid 174 // GetInputStreamParameters should return invalid parameters for invalid
175 // devices. 175 // devices.
176 176
177 // Get the preferred sample rate and channel configuration for the 177 // Get the preferred sample rate and channel configuration for the
178 // audio device. 178 // audio device.
179 media::AudioParameters params = 179 media::AudioParameters params =
180 audio_manager_->GetInputStreamParameters(info.device.id); 180 audio_manager_->GetInputStreamParameters(device.id);
181 input_params.sample_rate = params.sample_rate(); 181 input_params.sample_rate = params.sample_rate();
182 input_params.channel_layout = params.channel_layout(); 182 input_params.channel_layout = params.channel_layout();
183 input_params.frames_per_buffer = params.frames_per_buffer(); 183 input_params.frames_per_buffer = params.frames_per_buffer();
184 input_params.effects = params.effects(); 184 input_params.effects = params.effects();
185 input_params.mic_positions = params.mic_positions(); 185 input_params.mic_positions = params.mic_positions();
186 if (!out.device.matched_output_device_id.empty()) { 186 if (!out.device.matched_output_device_id.empty()) {
187 params = audio_manager_->GetOutputStreamParameters( 187 params = audio_manager_->GetOutputStreamParameters(
188 out.device.matched_output_device_id); 188 out.device.matched_output_device_id);
189 MediaStreamDevice::AudioDeviceParameters& matched_output_params = 189 MediaStreamDevice::AudioDeviceParameters& matched_output_params =
190 out.device.matched_output; 190 out.device.matched_output;
(...skipping 12 matching lines...) Expand all
203 } 203 }
204 204
205 void AudioInputDeviceManager::OpenedOnIOThread(int session_id, 205 void AudioInputDeviceManager::OpenedOnIOThread(int session_id,
206 const StreamDeviceInfo& info) { 206 const StreamDeviceInfo& info) {
207 DCHECK_CURRENTLY_ON(BrowserThread::IO); 207 DCHECK_CURRENTLY_ON(BrowserThread::IO);
208 DCHECK_EQ(session_id, info.session_id); 208 DCHECK_EQ(session_id, info.session_id);
209 DCHECK(GetDevice(session_id) == devices_.end()); 209 DCHECK(GetDevice(session_id) == devices_.end());
210 210
211 devices_.push_back(info); 211 devices_.push_back(info);
212 212
213 if (listener_) 213 for (auto& listener : listeners_)
214 listener_->Opened(info.device.type, session_id); 214 listener.Opened(info.device.type, session_id);
215 } 215 }
216 216
217 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, 217 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type,
218 int session_id) { 218 int session_id) {
219 DCHECK_CURRENTLY_ON(BrowserThread::IO); 219 DCHECK_CURRENTLY_ON(BrowserThread::IO);
220 if (listener_) 220 for (auto& listener : listeners_)
221 listener_->Closed(stream_type, session_id); 221 listener.Closed(stream_type, session_id);
222 } 222 }
223 223
224 bool AudioInputDeviceManager::IsOnDeviceThread() const { 224 bool AudioInputDeviceManager::IsOnDeviceThread() const {
225 return device_task_runner_->BelongsToCurrentThread(); 225 return device_task_runner_->BelongsToCurrentThread();
226 } 226 }
227 227
228 AudioInputDeviceManager::StreamDeviceList::iterator 228 AudioInputDeviceManager::StreamDeviceList::iterator
229 AudioInputDeviceManager::GetDevice(int session_id) { 229 AudioInputDeviceManager::GetDevice(int session_id) {
230 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end(); 230 for (StreamDeviceList::iterator i(devices_.begin()); i != devices_.end();
231 ++i) { 231 ++i) {
232 if (i->session_id == session_id) 232 if (i->session_id == session_id)
233 return i; 233 return i;
234 } 234 }
235 235
236 return devices_.end(); 236 return devices_.end();
237 } 237 }
238 238
239 #if defined(OS_CHROMEOS) 239 #if defined(OS_CHROMEOS)
240 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread( 240 void AudioInputDeviceManager::SetKeyboardMicStreamActiveOnUIThread(
241 bool active) { 241 bool active) {
242 DCHECK_CURRENTLY_ON(BrowserThread::UI); 242 DCHECK_CURRENTLY_ON(BrowserThread::UI);
243 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active); 243 chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(active);
244 } 244 }
245 #endif 245 #endif
246 246
247 247
248 } // namespace content 248 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698