OLD | NEW |
---|---|
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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "content/browser/renderer_host/media/audio_input_device_manager_event_h andler.h" | |
10 #include "content/public/browser/browser_thread.h" | 9 #include "content/public/browser/browser_thread.h" |
11 #include "content/public/common/media_stream_request.h" | 10 #include "content/public/common/media_stream_request.h" |
12 #include "media/audio/audio_device_name.h" | 11 #include "media/audio/audio_device_name.h" |
13 #include "media/audio/audio_input_ipc.h" | 12 #include "media/audio/audio_input_ipc.h" |
14 #include "media/audio/audio_manager_base.h" | 13 #include "media/audio/audio_manager_base.h" |
15 #include "media/audio/audio_parameters.h" | 14 #include "media/audio/audio_parameters.h" |
16 #include "media/base/channel_layout.h" | 15 #include "media/base/channel_layout.h" |
17 | 16 |
18 namespace content { | 17 namespace content { |
19 | 18 |
20 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; | 19 const int AudioInputDeviceManager::kFakeOpenSessionId = 1; |
21 | 20 |
22 namespace { | 21 namespace { |
23 // Starting id for the first capture session. | 22 // Starting id for the first capture session. |
24 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; | 23 const int kFirstSessionId = AudioInputDeviceManager::kFakeOpenSessionId + 1; |
25 } | 24 } |
26 | 25 |
27 AudioInputDeviceManager::AudioInputDeviceManager( | 26 AudioInputDeviceManager::AudioInputDeviceManager( |
28 media::AudioManager* audio_manager) | 27 media::AudioManager* audio_manager) |
29 : listener_(NULL), | 28 : listener_(NULL), |
30 next_capture_session_id_(kFirstSessionId), | 29 next_capture_session_id_(kFirstSessionId), |
31 use_fake_device_(false), | 30 use_fake_device_(false), |
32 audio_manager_(audio_manager) { | 31 audio_manager_(audio_manager) { |
33 } | 32 } |
34 | 33 |
35 AudioInputDeviceManager::~AudioInputDeviceManager() { | 34 AudioInputDeviceManager::~AudioInputDeviceManager() { |
36 } | 35 } |
37 | 36 |
37 StreamDeviceInfo AudioInputDeviceManager::GetOpenedDeviceInfoById( | |
38 int session_id) { | |
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
40 StreamDeviceMap::iterator device = devices_.find(session_id); | |
palmer
2013/03/12 17:45:11
Now that we are indexing this map with an int, per
no longer working on chromium
2013/03/14 10:47:32
Done with changing to a vector.
Now we use -1 to
| |
41 if (device == devices_.end()) | |
42 return StreamDeviceInfo(); | |
43 | |
44 return device->second; | |
45 } | |
46 | |
38 void AudioInputDeviceManager::Register( | 47 void AudioInputDeviceManager::Register( |
39 MediaStreamProviderListener* listener, | 48 MediaStreamProviderListener* listener, |
40 base::MessageLoopProxy* device_thread_loop) { | 49 base::MessageLoopProxy* device_thread_loop) { |
41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
42 DCHECK(!listener_); | 51 DCHECK(!listener_); |
43 DCHECK(!device_loop_); | 52 DCHECK(!device_loop_); |
44 listener_ = listener; | 53 listener_ = listener; |
45 device_loop_ = device_thread_loop; | 54 device_loop_ = device_thread_loop; |
46 } | 55 } |
47 | 56 |
(...skipping 20 matching lines...) Expand all Loading... | |
68 FROM_HERE, | 77 FROM_HERE, |
69 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, | 78 base::Bind(&AudioInputDeviceManager::OpenOnDeviceThread, |
70 this, session_id, device)); | 79 this, session_id, device)); |
71 | 80 |
72 return session_id; | 81 return session_id; |
73 } | 82 } |
74 | 83 |
75 void AudioInputDeviceManager::Close(int session_id) { | 84 void AudioInputDeviceManager::Close(int session_id) { |
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
77 DCHECK(listener_); | 86 DCHECK(listener_); |
78 // Check if the device has been stopped, if not, send stop signal. | 87 StreamDeviceMap::iterator device = devices_.find(session_id); |
79 EventHandlerMap::iterator it = event_handlers_.find(session_id); | 88 if (device == devices_.end()) |
80 if (it != event_handlers_.end()) { | 89 return; |
81 it->second->OnDeviceStopped(session_id); | 90 const MediaStreamType stream_type = device->second.device.type; |
82 event_handlers_.erase(it); | 91 devices_.erase(device); |
83 } | |
84 | 92 |
85 device_loop_->PostTask( | 93 // Post a callback through the listener on IO thread since |
86 FROM_HERE, | 94 // MediaStreamManager is expecting the callback asynchronously. |
87 base::Bind(&AudioInputDeviceManager::CloseOnDeviceThread, | 95 BrowserThread::PostTask(BrowserThread::IO, |
88 this, session_id)); | 96 FROM_HERE, |
89 } | 97 base::Bind(&AudioInputDeviceManager::ClosedOnIOThread, |
90 | 98 this, stream_type, session_id)); |
91 void AudioInputDeviceManager::Start( | |
92 int session_id, AudioInputDeviceManagerEventHandler* handler) { | |
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
94 DCHECK(handler); | |
95 | |
96 // Solution for not using MediaStreamManager. This is needed when Start() is | |
97 // called without using Open(), we post default device for test purpose. | |
98 // And we do not store the info for the kFakeOpenSessionId but return | |
99 // the callback immediately. | |
100 if (session_id == kFakeOpenSessionId) { | |
101 handler->OnDeviceStarted(session_id, | |
102 media::AudioManagerBase::kDefaultDeviceId); | |
103 return; | |
104 } | |
105 | |
106 // Look up the device_id of the session so we can notify the renderer that | |
107 // the device has started. If the session has not been started, | |
108 // use the empty device_id to indicate that Start() failed. | |
109 std::string device_id; | |
110 if (event_handlers_.insert(std::make_pair(session_id, handler)).second) { | |
111 StreamDeviceMap::const_iterator it = devices_.find(session_id); | |
112 if (it != devices_.end()) | |
113 device_id = it->second.device.id; | |
114 } | |
115 | |
116 // Post a callback through the AudioInputRendererHost to notify the renderer | |
117 // that the device has started. | |
118 handler->OnDeviceStarted(session_id, device_id); | |
119 } | |
120 | |
121 void AudioInputDeviceManager::Stop(int session_id) { | |
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
123 | |
124 // Erase the event handler referenced by the session_id. | |
125 event_handlers_.erase(session_id); | |
126 } | 99 } |
127 | 100 |
128 void AudioInputDeviceManager::UseFakeDevice() { | 101 void AudioInputDeviceManager::UseFakeDevice() { |
129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
130 use_fake_device_ = true; | 103 use_fake_device_ = true; |
131 } | 104 } |
132 | 105 |
133 bool AudioInputDeviceManager::ShouldUseFakeDevice() const { | 106 bool AudioInputDeviceManager::ShouldUseFakeDevice() const { |
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
135 return use_fake_device_; | 108 return use_fake_device_; |
(...skipping 13 matching lines...) Expand all Loading... | |
149 break; | 122 break; |
150 | 123 |
151 default: | 124 default: |
152 NOTREACHED(); | 125 NOTREACHED(); |
153 break; | 126 break; |
154 } | 127 } |
155 | 128 |
156 scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray()); | 129 scoped_ptr<StreamDeviceInfoArray> devices(new StreamDeviceInfoArray()); |
157 for (media::AudioDeviceNames::iterator it = device_names.begin(); | 130 for (media::AudioDeviceNames::iterator it = device_names.begin(); |
158 it != device_names.end(); ++it) { | 131 it != device_names.end(); ++it) { |
159 // Get the preferred sample rate and channel configuration for the | |
160 // current audio device. | |
161 media::AudioParameters default_params = | |
162 audio_manager_->GetInputStreamParameters(it->unique_id); | |
163 | |
164 // Add device information to device vector. | 132 // Add device information to device vector. |
165 devices->push_back(StreamDeviceInfo( | 133 devices->push_back(StreamDeviceInfo( |
166 stream_type, it->device_name, it->unique_id, | 134 stream_type, it->device_name, it->unique_id, false)); |
167 default_params.sample_rate(), default_params.channel_layout(), false)); | |
168 } | 135 } |
169 | 136 |
170 // Return the device list through the listener by posting a task on | 137 // Return the device list through the listener by posting a task on |
171 // IO thread since MediaStreamManager handles the callback asynchronously. | 138 // IO thread since MediaStreamManager handles the callback asynchronously. |
172 BrowserThread::PostTask( | 139 BrowserThread::PostTask( |
173 BrowserThread::IO, | 140 BrowserThread::IO, |
174 FROM_HERE, | 141 FROM_HERE, |
175 base::Bind(&AudioInputDeviceManager::DevicesEnumeratedOnIOThread, | 142 base::Bind(&AudioInputDeviceManager::DevicesEnumeratedOnIOThread, |
176 this, stream_type, base::Passed(&devices))); | 143 this, stream_type, base::Passed(&devices))); |
177 } | 144 } |
178 | 145 |
179 void AudioInputDeviceManager::OpenOnDeviceThread( | 146 void AudioInputDeviceManager::OpenOnDeviceThread( |
180 int session_id, const StreamDeviceInfo& device) { | 147 int session_id, const StreamDeviceInfo& info) { |
181 DCHECK(IsOnDeviceThread()); | 148 DCHECK(IsOnDeviceThread()); |
182 | 149 |
183 // Add the session_id and device to the map. | 150 // Get the preferred sample rate and channel configuration for the |
184 if (!devices_.insert(std::make_pair(session_id, device)).second) { | 151 // audio device. |
185 NOTREACHED(); | 152 media::AudioParameters params = |
186 devices_[session_id] = device; | 153 audio_manager_->GetInputStreamParameters(info.device.id); |
187 } | 154 |
155 const StreamDeviceInfo out( | |
156 info.device.type, info.device.name, info.device.id, | |
157 params.sample_rate(), params.channel_layout(), false); | |
188 | 158 |
189 // Return the |session_id| through the listener by posting a task on | 159 // Return the |session_id| through the listener by posting a task on |
190 // IO thread since MediaStreamManager handles the callback asynchronously. | 160 // IO thread since MediaStreamManager handles the callback asynchronously. |
191 BrowserThread::PostTask(BrowserThread::IO, | 161 BrowserThread::PostTask(BrowserThread::IO, |
192 FROM_HERE, | 162 FROM_HERE, |
193 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, | 163 base::Bind(&AudioInputDeviceManager::OpenedOnIOThread, |
194 this, device.device.type, session_id)); | 164 this, session_id, out)); |
195 } | |
196 | |
197 void AudioInputDeviceManager::CloseOnDeviceThread(int session_id) { | |
198 DCHECK(IsOnDeviceThread()); | |
199 | |
200 StreamDeviceMap::iterator it = devices_.find(session_id); | |
201 if (it == devices_.end()) | |
202 return; | |
203 const MediaStreamType stream_type = it->second.device.type; | |
204 devices_.erase(it); | |
205 | |
206 // Post a callback through the listener on IO thread since | |
207 // MediaStreamManager handles the callback asynchronously. | |
208 BrowserThread::PostTask(BrowserThread::IO, | |
209 FROM_HERE, | |
210 base::Bind(&AudioInputDeviceManager::ClosedOnIOThread, | |
211 this, stream_type, session_id)); | |
212 } | 165 } |
213 | 166 |
214 void AudioInputDeviceManager::DevicesEnumeratedOnIOThread( | 167 void AudioInputDeviceManager::DevicesEnumeratedOnIOThread( |
215 MediaStreamType stream_type, | 168 MediaStreamType stream_type, |
216 scoped_ptr<StreamDeviceInfoArray> devices) { | 169 scoped_ptr<StreamDeviceInfoArray> devices) { |
217 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
218 // Ensure that |devices| gets deleted on exit. | 171 // Ensure that |devices| gets deleted on exit. |
219 if (listener_) | 172 if (listener_) |
220 listener_->DevicesEnumerated(stream_type, *devices); | 173 listener_->DevicesEnumerated(stream_type, *devices); |
221 } | 174 } |
222 | 175 |
223 void AudioInputDeviceManager::OpenedOnIOThread(MediaStreamType stream_type, | 176 void AudioInputDeviceManager::OpenedOnIOThread(int session_id, |
224 int session_id) { | 177 const StreamDeviceInfo& info) { |
225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
179 // Add the session_id and device to the map. | |
180 if (!devices_.insert(std::make_pair(session_id, info)).second) { | |
palmer
2013/03/12 17:45:11
I don't understand what the intention of this expr
no longer working on chromium
2013/03/14 10:47:32
This code has been removed. insert() will fail and
| |
181 NOTREACHED(); | |
182 devices_[session_id] = info; | |
183 } | |
184 | |
226 if (listener_) | 185 if (listener_) |
227 listener_->Opened(stream_type, session_id); | 186 listener_->Opened(info.device.type, session_id); |
228 } | 187 } |
229 | 188 |
230 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, | 189 void AudioInputDeviceManager::ClosedOnIOThread(MediaStreamType stream_type, |
231 int session_id) { | 190 int session_id) { |
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
233 if (listener_) | 192 if (listener_) |
234 listener_->Closed(stream_type, session_id); | 193 listener_->Closed(stream_type, session_id); |
235 } | 194 } |
236 | 195 |
237 bool AudioInputDeviceManager::IsOnDeviceThread() const { | 196 bool AudioInputDeviceManager::IsOnDeviceThread() const { |
238 return device_loop_->BelongsToCurrentThread(); | 197 return device_loop_->BelongsToCurrentThread(); |
239 } | 198 } |
240 | 199 |
241 } // namespace content | 200 } // namespace content |
OLD | NEW |