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/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 29 matching lines...) Expand all Loading... | |
40 for (size_t i = 0; i < label.size(); ++i) { | 40 for (size_t i = 0; i < label.size(); ++i) { |
41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); | 41 int random_char = base::RandGenerator(sizeof(kAlphabet) - 1); |
42 label[i] = kAlphabet[random_char]; | 42 label[i] = kAlphabet[random_char]; |
43 } | 43 } |
44 return label; | 44 return label; |
45 } | 45 } |
46 | 46 |
47 // Helper to verify if a media stream type is part of options or not. | 47 // Helper to verify if a media stream type is part of options or not. |
48 static bool Requested(const StreamOptions& options, | 48 static bool Requested(const StreamOptions& options, |
49 MediaStreamType stream_type) { | 49 MediaStreamType stream_type) { |
50 return (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE && | 50 return (options.audio_type == stream_type || |
51 options.video) || | 51 options.video_type == stream_type); |
52 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE && | |
53 options.audio); | |
54 } | 52 } |
55 | 53 |
56 DeviceThread::DeviceThread(const char* name) | 54 DeviceThread::DeviceThread(const char* name) |
57 : base::Thread(name) { | 55 : base::Thread(name) { |
58 } | 56 } |
59 | 57 |
60 DeviceThread::~DeviceThread() { | 58 DeviceThread::~DeviceThread() { |
61 Stop(); | 59 Stop(); |
62 } | 60 } |
63 | 61 |
(...skipping 19 matching lines...) Expand all Loading... | |
83 }; | 81 }; |
84 | 82 |
85 enum RequestType { | 83 enum RequestType { |
86 GENERATE_STREAM = 0, | 84 GENERATE_STREAM = 0, |
87 ENUMERATE_DEVICES, | 85 ENUMERATE_DEVICES, |
88 OPEN_DEVICE | 86 OPEN_DEVICE |
89 }; | 87 }; |
90 | 88 |
91 DeviceRequest() | 89 DeviceRequest() |
92 : requester(NULL), | 90 : requester(NULL), |
93 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), | 91 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), |
94 type(GENERATE_STREAM), | 92 type(GENERATE_STREAM), |
95 render_process_id(-1), | 93 render_process_id(-1), |
96 render_view_id(-1) { | 94 render_view_id(-1) { |
97 options.audio = false; | |
98 options.video = false; | |
99 } | 95 } |
100 | 96 |
101 DeviceRequest(MediaStreamRequester* requester, | 97 DeviceRequest(MediaStreamRequester* requester, |
102 const StreamOptions& request_options, | 98 const StreamOptions& request_options, |
103 int render_process_id, | 99 int render_process_id, |
104 int render_view_id, | 100 int render_view_id, |
105 const GURL& request_security_origin) | 101 const GURL& request_security_origin) |
106 : requester(requester), | 102 : requester(requester), |
107 options(request_options), | 103 options(request_options), |
108 state(content::NUM_MEDIA_STREAM_DEVICE_TYPES, STATE_NOT_REQUESTED), | 104 state(content::NUM_MEDIA_TYPES, STATE_NOT_REQUESTED), |
109 type(GENERATE_STREAM), | 105 type(GENERATE_STREAM), |
110 render_process_id(render_process_id), | 106 render_process_id(render_process_id), |
111 render_view_id(render_view_id), | 107 render_view_id(render_view_id), |
112 security_origin(request_security_origin) { | 108 security_origin(request_security_origin) { |
113 DCHECK(requester); | 109 DCHECK(requester); |
114 } | 110 } |
115 | 111 |
116 ~DeviceRequest() {} | 112 ~DeviceRequest() {} |
117 | 113 |
118 MediaStreamRequester* requester; | 114 MediaStreamRequester* requester; |
119 StreamOptions options; | 115 StreamOptions options; |
120 std::vector<RequestState> state; | 116 std::vector<RequestState> state; |
121 RequestType type; | 117 RequestType type; |
122 int render_process_id; | 118 int render_process_id; |
123 int render_view_id; | 119 int render_view_id; |
124 GURL security_origin; | 120 GURL security_origin; |
125 std::string requested_device_id; | 121 std::string requested_device_id; |
126 StreamDeviceInfoArray audio_devices; | 122 StreamDeviceInfoArray devices; |
127 StreamDeviceInfoArray video_devices; | |
128 }; | 123 }; |
129 | 124 |
130 MediaStreamManager::EnumerationCache::EnumerationCache() | 125 MediaStreamManager::EnumerationCache::EnumerationCache() |
131 : valid(false) { | 126 : valid(false) { |
132 } | 127 } |
133 | 128 |
134 MediaStreamManager::EnumerationCache::~EnumerationCache() { | 129 MediaStreamManager::EnumerationCache::~EnumerationCache() { |
135 } | 130 } |
136 | 131 |
137 MediaStreamManager::MediaStreamManager( | 132 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) |
138 AudioInputDeviceManager* audio_input_device_manager, | |
139 VideoCaptureManager* video_capture_manager) | |
140 : ALLOW_THIS_IN_INITIALIZER_LIST( | 133 : ALLOW_THIS_IN_INITIALIZER_LIST( |
141 device_settings_(new MediaStreamDeviceSettings(this))), | 134 device_settings_(new MediaStreamDeviceSettings(this))), |
142 audio_input_device_manager_(audio_input_device_manager), | 135 audio_manager_(audio_manager), |
143 video_capture_manager_(video_capture_manager), | |
144 monitoring_started_(false), | 136 monitoring_started_(false), |
145 io_loop_(NULL) { | 137 io_loop_(NULL) { |
138 DCHECK(audio_manager_); | |
146 memset(active_enumeration_ref_count_, 0, | 139 memset(active_enumeration_ref_count_, 0, |
147 sizeof(active_enumeration_ref_count_)); | 140 sizeof(active_enumeration_ref_count_)); |
148 } | 141 } |
149 | 142 |
150 MediaStreamManager::~MediaStreamManager() { | 143 MediaStreamManager::~MediaStreamManager() { |
151 DCHECK(requests_.empty()); | 144 DCHECK(requests_.empty()); |
152 DCHECK(!device_thread_.get()); | 145 DCHECK(!device_thread_.get()); |
153 DCHECK(!io_loop_); | 146 DCHECK(!io_loop_); |
154 } | 147 } |
155 | 148 |
156 VideoCaptureManager* MediaStreamManager::video_capture_manager() { | 149 VideoCaptureManager* MediaStreamManager::video_capture_manager() { |
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
151 EnsureDeviceManagersStarted(); | |
158 DCHECK(video_capture_manager_); | 152 DCHECK(video_capture_manager_); |
159 EnsureDeviceThreadAndListener(); | |
160 return video_capture_manager_; | 153 return video_capture_manager_; |
161 } | 154 } |
162 | 155 |
163 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { | 156 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { |
164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
158 EnsureDeviceManagersStarted(); | |
165 DCHECK(audio_input_device_manager_); | 159 DCHECK(audio_input_device_manager_); |
166 EnsureDeviceThreadAndListener(); | |
167 return audio_input_device_manager_; | 160 return audio_input_device_manager_; |
168 } | 161 } |
169 | 162 |
170 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, | 163 void MediaStreamManager::GenerateStream(MediaStreamRequester* requester, |
171 int render_process_id, | 164 int render_process_id, |
172 int render_view_id, | 165 int render_view_id, |
173 const StreamOptions& options, | 166 const StreamOptions& options, |
174 const GURL& security_origin, | 167 const GURL& security_origin, |
175 std::string* label) { | 168 std::string* label) { |
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
177 | 170 |
178 // Create a new request based on options. | 171 // Create a new request based on options. |
179 DeviceRequest new_request(requester, options, | 172 DeviceRequest new_request(requester, options, |
180 render_process_id, | 173 render_process_id, |
181 render_view_id, | 174 render_view_id, |
182 security_origin); | 175 security_origin); |
183 StartEnumeration(&new_request, label); | 176 StartEnumeration(&new_request, label); |
184 | 177 |
185 // Get user confirmation to use capture devices. | 178 // Get user confirmation to use capture devices. |
186 device_settings_->RequestCaptureDeviceUsage(*label, | 179 device_settings_->RequestCaptureDeviceUsage(*label, |
187 render_process_id, | 180 render_process_id, |
188 render_view_id, | 181 render_view_id, |
189 options, | 182 options, |
190 security_origin); | 183 security_origin); |
191 } | 184 } |
192 | 185 |
186 void MediaStreamManager::GenerateStreamForDevice( | |
187 MediaStreamRequester* requester, int render_process_id, int render_view_id, | |
188 const StreamOptions& options, const std::string& device_id, | |
189 const GURL& security_origin, std::string* label) { | |
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
191 | |
192 // Create a new request based on options. | |
193 AddRequest(DeviceRequest(requester, options, | |
194 render_process_id, render_view_id, | |
195 security_origin), | |
196 label); | |
197 DeviceRequest& request = requests_[*label]; | |
198 | |
199 // Get user confirmation to use the capture device. | |
200 device_settings_->RequestCaptureDeviceUsage(*label, | |
201 render_process_id, | |
202 render_view_id, | |
203 options, | |
204 security_origin); | |
205 // TODO(miu): We should ask the device manager whether a device with id | |
206 // |device_id| actually exists. Note that no such MediaStreamProvider API for | |
207 // this currently exists. Also, we don't have a user-friendly device name for | |
208 // the infobar UI. | |
209 if (content::IsAudioMediaType(options.audio_type)) { | |
210 request.state[options.audio_type] = DeviceRequest::STATE_PENDING_APPROVAL; | |
211 device_settings_->AvailableDevices( | |
212 *label, options.audio_type, StreamDeviceInfoArray( | |
213 1, StreamDeviceInfo(options.audio_type, device_id, device_id, | |
214 false))); | |
215 } | |
216 if (content::IsVideoMediaType(options.video_type)) { | |
217 request.state[options.video_type] = DeviceRequest::STATE_PENDING_APPROVAL; | |
218 device_settings_->AvailableDevices( | |
219 *label, options.video_type, StreamDeviceInfoArray( | |
220 1, StreamDeviceInfo(options.video_type, device_id, device_id, | |
221 false))); | |
222 } | |
223 } | |
224 | |
193 void MediaStreamManager::CancelGenerateStream(const std::string& label) { | 225 void MediaStreamManager::CancelGenerateStream(const std::string& label) { |
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
195 | 227 |
196 DeviceRequests::iterator it = requests_.find(label); | 228 DeviceRequests::iterator it = requests_.find(label); |
197 if (it != requests_.end()) { | 229 if (it != requests_.end()) { |
198 // The request isn't complete. | 230 // The request isn't complete. |
199 if (!RequestDone(it->second)) { | 231 if (!RequestDone(it->second)) { |
200 DeviceRequest* request = &(it->second); | 232 DeviceRequest& request = it->second; |
201 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE] == | 233 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
202 DeviceRequest::STATE_OPENING) { | 234 ++i) { |
203 for (StreamDeviceInfoArray::iterator it = | 235 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
204 request->audio_devices.begin(); it != request->audio_devices.end(); | 236 if (request.state[stream_type] != DeviceRequest::STATE_OPENING) { |
205 ++it) { | 237 continue; |
206 audio_input_device_manager()->Close(it->session_id); | |
207 } | 238 } |
208 } | 239 for (StreamDeviceInfoArray::const_iterator device_it = |
209 if (request->state[content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE] == | 240 request.devices.begin(); |
210 DeviceRequest::STATE_OPENING) { | 241 device_it != request.devices.end(); ++device_it) { |
211 for (StreamDeviceInfoArray::iterator it = | 242 if (device_it->stream_type == stream_type) { |
212 request->video_devices.begin(); it != request->video_devices.end(); | 243 GetDeviceManager(stream_type)->Close(device_it->session_id); |
213 ++it) { | 244 } |
214 video_capture_manager()->Close(it->session_id); | |
215 } | 245 } |
216 } | 246 } |
217 requests_.erase(it); | 247 requests_.erase(it); |
218 } else { | 248 } else { |
219 StopGeneratedStream(label); | 249 StopGeneratedStream(label); |
220 } | 250 } |
221 device_settings_->RemovePendingCaptureRequest(label); | 251 device_settings_->RemovePendingCaptureRequest(label); |
222 } | 252 } |
223 } | 253 } |
224 | 254 |
225 void MediaStreamManager::StopGeneratedStream(const std::string& label) { | 255 void MediaStreamManager::StopGeneratedStream(const std::string& label) { |
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 256 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
227 // Find the request and close all open devices for the request. | 257 // Find the request and close all open devices for the request. |
228 DeviceRequests::iterator it = requests_.find(label); | 258 DeviceRequests::iterator it = requests_.find(label); |
229 if (it != requests_.end()) { | 259 if (it != requests_.end()) { |
230 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { | 260 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES) { |
231 StopEnumerateDevices(label); | 261 StopEnumerateDevices(label); |
232 return; | 262 return; |
233 } | 263 } |
234 for (StreamDeviceInfoArray::iterator audio_it = | 264 for (StreamDeviceInfoArray::const_iterator device_it = |
235 it->second.audio_devices.begin(); | 265 it->second.devices.begin(); |
236 audio_it != it->second.audio_devices.end(); ++audio_it) { | 266 device_it != it->second.devices.end(); ++device_it) { |
237 audio_input_device_manager()->Close(audio_it->session_id); | 267 GetDeviceManager(device_it->stream_type)->Close(device_it->session_id); |
238 } | |
239 for (StreamDeviceInfoArray::iterator video_it = | |
240 it->second.video_devices.begin(); | |
241 video_it != it->second.video_devices.end(); ++video_it) { | |
242 video_capture_manager()->Close(video_it->session_id); | |
243 } | 268 } |
244 if (it->second.type == DeviceRequest::GENERATE_STREAM && | 269 if (it->second.type == DeviceRequest::GENERATE_STREAM && |
245 RequestDone(it->second)) { | 270 RequestDone(it->second)) { |
246 NotifyObserverDevicesClosed(&(it->second)); | 271 NotifyObserverDevicesClosed(&(it->second)); |
247 } | 272 } |
248 requests_.erase(it); | 273 requests_.erase(it); |
249 } | 274 } |
250 } | 275 } |
251 | 276 |
252 void MediaStreamManager::EnumerateDevices( | 277 void MediaStreamManager::EnumerateDevices( |
253 MediaStreamRequester* requester, | 278 MediaStreamRequester* requester, |
254 int render_process_id, | 279 int render_process_id, |
255 int render_view_id, | 280 int render_view_id, |
256 MediaStreamType type, | 281 MediaStreamType type, |
257 const GURL& security_origin, | 282 const GURL& security_origin, |
258 std::string* label) { | 283 std::string* label) { |
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
260 DCHECK(type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE || | 285 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE || |
261 type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE); | 286 type == content::MEDIA_DEVICE_VIDEO_CAPTURE); |
262 | 287 |
263 // Create a new request. | 288 // Create a new request. |
264 StreamOptions options; | 289 StreamOptions options; |
265 EnumerationCache* cache = NULL; | 290 EnumerationCache* cache = NULL; |
266 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 291 if (type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { |
267 options.audio = true; | 292 options.audio_type = type; |
268 cache = &audio_enumeration_cache_; | 293 cache = &audio_enumeration_cache_; |
294 } else if (type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { | |
295 options.video_type = type; | |
296 cache = &video_enumeration_cache_; | |
269 } else { | 297 } else { |
270 options.video = true; | 298 NOTREACHED(); |
271 cache = &video_enumeration_cache_; | 299 return; |
272 } | 300 } |
273 | 301 |
274 DeviceRequest new_request(requester, options, | 302 DeviceRequest new_request(requester, options, |
275 render_process_id, | 303 render_process_id, |
276 render_view_id, | 304 render_view_id, |
277 security_origin); | 305 security_origin); |
278 new_request.type = DeviceRequest::ENUMERATE_DEVICES; | 306 new_request.type = DeviceRequest::ENUMERATE_DEVICES; |
279 | 307 |
280 if (cache->valid) { | 308 if (cache->valid) { |
281 // Cached device list of this type exists. Just send it out. | 309 // Cached device list of this type exists. Just send it out. |
282 new_request.state[type] = DeviceRequest::STATE_REQUESTED; | 310 new_request.state[type] = DeviceRequest::STATE_REQUESTED; |
283 AddRequest(&new_request, label); | 311 AddRequest(new_request, label); |
284 // Need to post a task since the requester won't have label till | 312 // Need to post a task since the requester won't have label till |
285 // this function returns. | 313 // this function returns. |
286 BrowserThread::PostTask(BrowserThread::IO, | 314 BrowserThread::PostTask(BrowserThread::IO, |
287 FROM_HERE, | 315 FROM_HERE, |
288 base::Bind(&MediaStreamManager::SendCachedDeviceList, | 316 base::Bind(&MediaStreamManager::SendCachedDeviceList, |
289 base::Unretained(this), cache, *label)); | 317 base::Unretained(this), cache, *label)); |
290 } else { | 318 } else { |
291 StartEnumeration(&new_request, label); | 319 StartEnumeration(&new_request, label); |
292 StartMonitoring(); | 320 StartMonitoring(); |
293 } | 321 } |
(...skipping 14 matching lines...) Expand all Loading... | |
308 | 336 |
309 void MediaStreamManager::OpenDevice( | 337 void MediaStreamManager::OpenDevice( |
310 MediaStreamRequester* requester, | 338 MediaStreamRequester* requester, |
311 int render_process_id, | 339 int render_process_id, |
312 int render_view_id, | 340 int render_view_id, |
313 const std::string& device_id, | 341 const std::string& device_id, |
314 MediaStreamType type, | 342 MediaStreamType type, |
315 const GURL& security_origin, | 343 const GURL& security_origin, |
316 std::string* label) { | 344 std::string* label) { |
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
346 DCHECK(type == content::MEDIA_DEVICE_AUDIO_CAPTURE || | |
347 type == content::MEDIA_DEVICE_VIDEO_CAPTURE); | |
318 | 348 |
319 // Create a new request. | 349 // Create a new request. |
320 StreamOptions options; | 350 StreamOptions options; |
321 if (type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 351 if (content::IsAudioMediaType(type)) { |
322 options.audio = true; | 352 options.audio_type = type; |
323 else | 353 } else if (content::IsVideoMediaType(type)) { |
324 options.video = true; | 354 options.video_type = type; |
355 } else { | |
356 NOTREACHED(); | |
357 return; | |
358 } | |
325 | 359 |
326 DeviceRequest new_request(requester, options, | 360 DeviceRequest new_request(requester, options, |
327 render_process_id, | 361 render_process_id, |
328 render_view_id, | 362 render_view_id, |
329 security_origin); | 363 security_origin); |
330 new_request.type = DeviceRequest::OPEN_DEVICE; | 364 new_request.type = DeviceRequest::OPEN_DEVICE; |
331 new_request.requested_device_id = device_id; | 365 new_request.requested_device_id = device_id; |
332 | 366 |
333 StartEnumeration(&new_request, label); | 367 StartEnumeration(&new_request, label); |
334 } | 368 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
366 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { | 400 void MediaStreamManager::ClearEnumerationCache(EnumerationCache* cache) { |
367 DCHECK_EQ(MessageLoop::current(), io_loop_); | 401 DCHECK_EQ(MessageLoop::current(), io_loop_); |
368 cache->valid = false; | 402 cache->valid = false; |
369 } | 403 } |
370 | 404 |
371 void MediaStreamManager::StartEnumeration( | 405 void MediaStreamManager::StartEnumeration( |
372 DeviceRequest* new_request, | 406 DeviceRequest* new_request, |
373 std::string* label) { | 407 std::string* label) { |
374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
375 | 409 |
376 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | 410 for (int i = content::MEDIA_NO_SERVICE + 1; i < content::NUM_MEDIA_TYPES; |
377 if (Requested(new_request->options, stream_type)) { | 411 ++i) { |
378 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; | 412 const MediaStreamType stream_type = static_cast<MediaStreamType>(i); |
379 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 413 if (Requested(new_request->options, stream_type)) { |
380 if (!active_enumeration_ref_count_[stream_type]) { | 414 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; |
381 ++active_enumeration_ref_count_[stream_type]; | 415 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
382 GetDeviceManager(stream_type)->EnumerateDevices(); | 416 if (active_enumeration_ref_count_[stream_type] == 0) { |
383 } | 417 ++active_enumeration_ref_count_[stream_type]; |
384 } | 418 GetDeviceManager(stream_type)->EnumerateDevices(); |
385 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | 419 } |
386 if (Requested(new_request->options, stream_type)) { | |
387 new_request->state[stream_type] = DeviceRequest::STATE_REQUESTED; | |
388 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | |
389 if (!active_enumeration_ref_count_[stream_type]) { | |
390 ++active_enumeration_ref_count_[stream_type]; | |
391 GetDeviceManager(stream_type)->EnumerateDevices(); | |
392 } | 420 } |
393 } | 421 } |
394 | 422 |
395 AddRequest(new_request, label); | 423 AddRequest(*new_request, label); |
396 } | 424 } |
397 | 425 |
398 void MediaStreamManager::AddRequest( | 426 void MediaStreamManager::AddRequest( |
399 DeviceRequest* new_request, | 427 const DeviceRequest& new_request, |
400 std::string* label) { | 428 std::string* label) { |
401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
402 | 430 |
403 // Create a label for this request and verify it is unique. | 431 // Create a label for this request and verify it is unique. |
404 std::string request_label; | 432 std::string request_label; |
405 do { | 433 do { |
406 request_label = RandomLabel(); | 434 request_label = RandomLabel(); |
407 } while (requests_.find(request_label) != requests_.end()); | 435 } while (requests_.find(request_label) != requests_.end()); |
408 | 436 |
409 requests_.insert(std::make_pair(request_label, *new_request)); | 437 requests_.insert(std::make_pair(request_label, new_request)); |
410 | 438 |
411 (*label) = request_label; | 439 (*label) = request_label; |
412 } | 440 } |
413 | 441 |
414 void MediaStreamManager::EnsureDeviceThreadAndListener() { | 442 void MediaStreamManager::EnsureDeviceManagersStarted() { |
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 443 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
416 if (device_thread_.get()) | 444 if (device_thread_.get()) |
417 return; | 445 return; |
418 | 446 |
419 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); | 447 device_thread_.reset(new DeviceThread("MediaStreamDeviceThread")); |
420 CHECK(device_thread_->Start()); | 448 CHECK(device_thread_->Start()); |
421 | 449 |
450 audio_input_device_manager_ = | |
451 new media_stream::AudioInputDeviceManager(audio_manager_); | |
422 audio_input_device_manager_->Register(this, | 452 audio_input_device_manager_->Register(this, |
423 device_thread_->message_loop_proxy()); | 453 device_thread_->message_loop_proxy()); |
424 video_capture_manager_->Register(this, device_thread_->message_loop_proxy()); | 454 |
455 video_capture_manager_ = new media_stream::VideoCaptureManager(); | |
456 video_capture_manager_->Register(this, | |
457 device_thread_->message_loop_proxy()); | |
425 | 458 |
426 // We want to be notified of IO message loop destruction to delete the thread | 459 // We want to be notified of IO message loop destruction to delete the thread |
427 // and the device managers. | 460 // and the device managers. |
428 io_loop_ = MessageLoop::current(); | 461 io_loop_ = MessageLoop::current(); |
429 io_loop_->AddDestructionObserver(this); | 462 io_loop_->AddDestructionObserver(this); |
430 } | 463 } |
431 | 464 |
432 void MediaStreamManager::Opened(MediaStreamType stream_type, | 465 void MediaStreamManager::Opened(MediaStreamType stream_type, |
433 int capture_session_id) { | 466 int capture_session_id) { |
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
435 | 468 |
436 // Find the request containing this device and mark it as used. | 469 // Find the request containing this device and mark it as used. |
437 DeviceRequest* request = NULL; | 470 DeviceRequest* request = NULL; |
438 StreamDeviceInfoArray* devices = NULL; | 471 StreamDeviceInfoArray* devices = NULL; |
439 std::string label; | 472 std::string label; |
440 for (DeviceRequests::iterator request_it = requests_.begin(); | 473 for (DeviceRequests::iterator request_it = requests_.begin(); |
441 request_it != requests_.end() && request == NULL; ++request_it) { | 474 request_it != requests_.end() && request == NULL; ++request_it) { |
442 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 475 devices = &(request_it->second.devices); |
443 devices = &(request_it->second.audio_devices); | |
444 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | |
445 devices = &(request_it->second.video_devices); | |
446 } else { | |
447 NOTREACHED(); | |
448 } | |
449 | |
450 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 476 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
451 device_it != devices->end(); ++device_it) { | 477 device_it != devices->end(); ++device_it) { |
452 if (device_it->session_id == capture_session_id) { | 478 if (device_it->stream_type == stream_type && |
479 device_it->session_id == capture_session_id) { | |
453 // We've found the request. | 480 // We've found the request. |
454 device_it->in_use = true; | 481 device_it->in_use = true; |
455 label = request_it->first; | 482 label = request_it->first; |
456 request = &(request_it->second); | 483 request = &(request_it->second); |
457 break; | 484 break; |
458 } | 485 } |
459 } | 486 } |
460 } | 487 } |
461 if (request == NULL) { | 488 if (request == NULL) { |
462 // The request doesn't exist. | 489 // The request doesn't exist. |
463 return; | 490 return; |
464 } | 491 } |
465 | 492 |
466 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); | 493 DCHECK_NE(request->state[stream_type], DeviceRequest::STATE_REQUESTED); |
467 | 494 |
468 // Check if all devices for this stream type are opened. Update the state if | 495 // Check if all devices for this stream type are opened. Update the state if |
469 // they are. | 496 // they are. |
470 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 497 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); |
471 device_it != devices->end(); ++device_it) { | 498 device_it != devices->end(); ++device_it) { |
499 if (device_it->stream_type != stream_type) { | |
500 continue; | |
501 } | |
472 if (device_it->in_use == false) { | 502 if (device_it->in_use == false) { |
473 // Wait for more devices to be opened before we're done. | 503 // Wait for more devices to be opened before we're done. |
474 return; | 504 return; |
475 } | 505 } |
476 } | 506 } |
477 request->state[stream_type] = DeviceRequest::STATE_DONE; | 507 request->state[stream_type] = DeviceRequest::STATE_DONE; |
478 | 508 |
479 if (!RequestDone(*request)) { | 509 if (!RequestDone(*request)) { |
480 // This stream_type is done, but not the other type. | 510 // This stream_type is done, but not the other type. |
481 return; | 511 return; |
482 } | 512 } |
483 | 513 |
484 switch (request->type) { | 514 switch (request->type) { |
485 case DeviceRequest::OPEN_DEVICE: | 515 case DeviceRequest::OPEN_DEVICE: |
486 request->requester->DeviceOpened(label, (*devices)[0]); | 516 request->requester->DeviceOpened(label, devices->front()); |
487 break; | 517 break; |
488 case DeviceRequest::GENERATE_STREAM: | 518 case DeviceRequest::GENERATE_STREAM: { |
489 request->requester->StreamGenerated(label, request->audio_devices, | 519 // Partition the array of devices into audio vs video. |
490 request->video_devices); | 520 StreamDeviceInfoArray audio_devices, video_devices; |
521 for (StreamDeviceInfoArray::const_iterator device_it = devices->begin(); | |
522 device_it != devices->end(); ++device_it) { | |
523 if (content::IsAudioMediaType(device_it->stream_type)) { | |
524 audio_devices.push_back(*device_it); | |
525 } else if (content::IsVideoMediaType(device_it->stream_type)) { | |
526 video_devices.push_back(*device_it); | |
527 } else { | |
528 NOTREACHED(); | |
529 } | |
530 } | |
531 | |
532 request->requester->StreamGenerated(label, audio_devices, video_devices); | |
491 NotifyObserverDevicesOpened(request); | 533 NotifyObserverDevicesOpened(request); |
492 break; | 534 break; |
535 } | |
493 default: | 536 default: |
494 NOTREACHED(); | 537 NOTREACHED(); |
538 break; | |
495 } | 539 } |
496 } | 540 } |
497 | 541 |
498 void MediaStreamManager::Closed(MediaStreamType stream_type, | 542 void MediaStreamManager::Closed(MediaStreamType stream_type, |
499 int capture_session_id) { | 543 int capture_session_id) { |
500 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
501 } | 545 } |
502 | 546 |
503 void MediaStreamManager::DevicesEnumerated( | 547 void MediaStreamManager::DevicesEnumerated( |
504 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { | 548 MediaStreamType stream_type, const StreamDeviceInfoArray& devices) { |
505 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
506 | 550 |
507 // Only cache device list when there is EnumerateDevices request, since | 551 // Only cache the device list when there is an EnumerateDevices request, since |
508 // other requests don't turn on device monitoring. | 552 // other requests don't turn on device monitoring. |
509 bool need_update_clients = false; | 553 bool need_update_clients = false; |
510 EnumerationCache* cache = | 554 EnumerationCache* cache = |
511 (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE ? | 555 (stream_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ? |
512 &audio_enumeration_cache_ : &video_enumeration_cache_); | 556 &audio_enumeration_cache_ : &video_enumeration_cache_); |
513 if (HasEnumerationRequest(stream_type) && | 557 if (HasEnumerationRequest(stream_type) && |
514 (!cache->valid || | 558 (!cache->valid || |
515 devices.size() != cache->devices.size() || | 559 devices.size() != cache->devices.size() || |
516 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), | 560 !std::equal(devices.begin(), devices.end(), cache->devices.begin(), |
517 media_stream::StreamDeviceInfo::IsEqual))) { | 561 media_stream::StreamDeviceInfo::IsEqual))) { |
518 cache->valid = true; | 562 cache->valid = true; |
519 cache->devices = devices; | 563 cache->devices = devices; |
520 need_update_clients = true; | 564 need_update_clients = true; |
521 } | 565 } |
(...skipping 14 matching lines...) Expand all Loading... | |
536 } | 580 } |
537 for (std::list<std::string>::iterator it = label_list.begin(); | 581 for (std::list<std::string>::iterator it = label_list.begin(); |
538 it != label_list.end(); ++it) { | 582 it != label_list.end(); ++it) { |
539 DeviceRequest& request = requests_[*it]; | 583 DeviceRequest& request = requests_[*it]; |
540 switch (request.type) { | 584 switch (request.type) { |
541 case DeviceRequest::ENUMERATE_DEVICES: | 585 case DeviceRequest::ENUMERATE_DEVICES: |
542 if (need_update_clients) | 586 if (need_update_clients) |
543 request.requester->DevicesEnumerated(*it, devices); | 587 request.requester->DevicesEnumerated(*it, devices); |
544 break; | 588 break; |
545 case DeviceRequest::OPEN_DEVICE: | 589 case DeviceRequest::OPEN_DEVICE: |
590 DCHECK(!request.requested_device_id.empty()); | |
546 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 591 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); |
547 device_it != devices.end(); device_it++) { | 592 device_it != devices.end(); ++device_it) { |
548 if (request.requested_device_id == device_it->device_id) { | 593 if (request.requested_device_id == device_it->device_id) { |
549 StreamDeviceInfo device = *device_it; | 594 StreamDeviceInfo device = *device_it; |
550 device.in_use = false; | 595 device.in_use = false; |
551 device.session_id = | 596 device.session_id = |
552 GetDeviceManager(device_it->stream_type)->Open(device); | 597 GetDeviceManager(device_it->stream_type)->Open(device); |
553 request.state[device_it->stream_type] = | 598 request.state[device_it->stream_type] = |
554 DeviceRequest::STATE_OPENING; | 599 DeviceRequest::STATE_OPENING; |
555 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) | 600 request.devices.push_back(device); |
556 request.audio_devices.push_back(device); | |
557 else | |
558 request.video_devices.push_back(device); | |
559 break; | 601 break; |
560 } | 602 } |
561 } | 603 } |
562 break; | 604 break; |
563 default: | 605 default: |
564 device_settings_->AvailableDevices(*it, stream_type, devices); | 606 device_settings_->AvailableDevices(*it, stream_type, devices); |
607 break; | |
565 } | 608 } |
566 } | 609 } |
567 label_list.clear(); | 610 label_list.clear(); |
568 --active_enumeration_ref_count_[stream_type]; | 611 --active_enumeration_ref_count_[stream_type]; |
569 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); | 612 DCHECK_GE(active_enumeration_ref_count_[stream_type], 0); |
570 } | 613 } |
571 | 614 |
572 void MediaStreamManager::Error(MediaStreamType stream_type, | 615 void MediaStreamManager::Error(MediaStreamType stream_type, |
573 int capture_session_id, | 616 int capture_session_id, |
574 MediaStreamProviderError error) { | 617 MediaStreamProviderError error) { |
575 // Find the device for the error call. | 618 // Find the device for the error call. |
576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 619 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
620 | |
577 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); | 621 for (DeviceRequests::iterator it = requests_.begin(); it != requests_.end(); |
578 ++it) { | 622 ++it) { |
579 StreamDeviceInfoArray* devices = NULL; | 623 StreamDeviceInfoArray& devices = it->second.devices; |
580 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | |
581 devices = &(it->second.audio_devices); | |
582 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | |
583 devices = &(it->second.video_devices); | |
584 } else { | |
585 NOTREACHED(); | |
586 } | |
587 | 624 |
588 int device_idx = 0; | 625 int audio_device_idx = -1; |
589 for (StreamDeviceInfoArray::iterator device_it = devices->begin(); | 626 int video_device_idx = -1; |
590 device_it != devices->end(); ++device_it, ++device_idx) { | 627 for (StreamDeviceInfoArray::iterator device_it = devices.begin(); |
591 if (device_it->session_id == capture_session_id) { | 628 device_it != devices.end(); ++device_it) { |
592 // We've found the failing device. Find the error case: | 629 if (content::IsAudioMediaType(device_it->stream_type)) { |
593 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { | 630 ++audio_device_idx; |
594 // 1. Already opened -> signal device failure and close device. | 631 } else if (content::IsVideoMediaType(device_it->stream_type)) { |
595 // Use device_idx to signal which of the devices encountered an | 632 ++video_device_idx; |
596 // error. | 633 } else { |
597 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 634 NOTREACHED(); |
598 it->second.requester->AudioDeviceFailed(it->first, device_idx); | 635 continue; |
599 } else if (stream_type == | 636 } |
600 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 637 if (device_it->stream_type != stream_type || |
601 it->second.requester->VideoDeviceFailed(it->first, device_idx); | 638 device_it->session_id != capture_session_id) { |
602 } | 639 continue; |
603 GetDeviceManager(stream_type)->Close(capture_session_id); | 640 } |
604 // We don't erase the devices here so that we can update the UI | 641 // We've found the failing device. Find the error case: |
605 // properly in StopGeneratedStream(). | 642 if (it->second.state[stream_type] == DeviceRequest::STATE_DONE) { |
606 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | 643 // 1. Already opened -> signal device failure and close device. |
644 // Use device_idx to signal which of the devices encountered an | |
645 // error. | |
646 if (content::IsAudioMediaType(stream_type)) { | |
647 it->second.requester->AudioDeviceFailed(it->first, audio_device_idx); | |
tommi (sloooow) - chröme
2012/09/10 09:17:25
Using the index here seems to be a bug to me. May
no longer working on chromium
2012/09/10 11:00:17
I agree the code is quite messy here, probably a f
tommi (sloooow) - chröme
2012/09/10 11:29:01
I don't think so. Read through the example I gave
no longer working on chromium
2012/09/10 12:28:03
Thanks for the pointing it out. It is indeed a pro
miu
2012/09/10 21:24:38
This seemed funny to me. I had modified this code
| |
648 } else if (content::IsVideoMediaType(stream_type)) { | |
649 it->second.requester->VideoDeviceFailed(it->first, video_device_idx); | |
607 } else { | 650 } else { |
608 // Request is not done, devices are not opened in this case. | 651 NOTREACHED(); |
609 if ((it->second.audio_devices.size() + | 652 return; |
610 it->second.video_devices.size()) <= 1) { | |
611 // 2. Device not opened and no other devices for this request -> | |
612 // signal stream error and remove the request. | |
613 it->second.requester->StreamGenerationFailed(it->first); | |
614 requests_.erase(it); | |
615 } else { | |
616 // 3. Not opened but other devices exists for this request -> remove | |
617 // device from list, but don't signal an error. | |
618 devices->erase(device_it); | |
619 } | |
620 } | 653 } |
621 return; | 654 GetDeviceManager(stream_type)->Close(capture_session_id); |
655 // We don't erase the devices here so that we can update the UI | |
656 // properly in StopGeneratedStream(). | |
657 it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | |
658 } else { | |
659 // Request is not done, devices are not opened in this case. | |
660 if (devices.size() <= 1) { | |
661 // 2. Device not opened and no other devices for this request -> | |
662 // signal stream error and remove the request. | |
663 it->second.requester->StreamGenerationFailed(it->first); | |
664 requests_.erase(it); | |
665 } else { | |
666 // 3. Not opened but other devices exists for this request -> remove | |
667 // device from list, but don't signal an error. | |
668 devices.erase(device_it); // NOTE: This invalidates device_it! | |
669 } | |
622 } | 670 } |
671 return; | |
623 } | 672 } |
624 } | 673 } |
625 } | 674 } |
626 | 675 |
627 void MediaStreamManager::DevicesAccepted(const std::string& label, | 676 void MediaStreamManager::DevicesAccepted(const std::string& label, |
628 const StreamDeviceInfoArray& devices) { | 677 const StreamDeviceInfoArray& devices) { |
629 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
630 DeviceRequests::iterator request_it = requests_.find(label); | 679 DeviceRequests::iterator request_it = requests_.find(label); |
631 if (request_it != requests_.end()) { | 680 if (request_it == requests_.end()) { |
632 if (devices.empty()) { | 681 return; |
633 // No available devices or user didn't accept device usage. | 682 } |
634 request_it->second.requester->StreamGenerationFailed(request_it->first); | 683 |
635 requests_.erase(request_it); | 684 DeviceRequest& request = request_it->second; |
636 return; | 685 |
686 if (devices.empty()) { | |
687 // No available devices or user didn't accept device usage. | |
688 request.requester->StreamGenerationFailed(request_it->first); | |
689 requests_.erase(request_it); | |
690 return; | |
691 } | |
692 | |
693 // Process all newly-accepted devices for this request. | |
694 bool found_audio = false, found_video = false; | |
695 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | |
696 device_it != devices.end(); ++device_it) { | |
697 StreamDeviceInfo device_info = *device_it; // Make a copy. | |
698 | |
699 // Set in_use to false to be able to track if this device has been | |
700 // opened. in_use might be true if the device type can be used in more | |
701 // than one session. | |
702 DCHECK_EQ(request.state[device_it->stream_type], | |
703 DeviceRequest::STATE_PENDING_APPROVAL); | |
704 device_info.in_use = false; | |
705 device_info.session_id = | |
706 GetDeviceManager(device_info.stream_type)->Open(device_info); | |
707 request.state[device_it->stream_type] = DeviceRequest::STATE_OPENING; | |
708 request.devices.push_back(device_info); | |
709 | |
710 if (device_info.stream_type == request.options.audio_type) { | |
711 found_audio = true; | |
712 } else if (device_info.stream_type == request.options.video_type) { | |
713 found_video = true; | |
637 } | 714 } |
715 } | |
638 | 716 |
639 // Loop through all device types for this request. | 717 // Check whether we've received all stream types requested. |
640 for (StreamDeviceInfoArray::const_iterator device_it = devices.begin(); | 718 if (request.options.audio_type != content::MEDIA_NO_SERVICE && |
no longer working on chromium
2012/09/10 09:11:04
nit, using content::IsAudioMediaType(request.optio
miu
2012/09/10 21:24:38
Done.
| |
641 device_it != devices.end(); ++device_it) { | 719 !found_audio) { |
642 StreamDeviceInfo device_info = *device_it; | 720 request.state[request.options.audio_type] = DeviceRequest::STATE_ERROR; |
643 | 721 } |
644 // Set in_use to false to be able to track if this device has been | 722 if (request.options.video_type != content::MEDIA_NO_SERVICE && |
no longer working on chromium
2012/09/10 09:11:04
ditto
miu
2012/09/10 21:24:38
Done.
| |
645 // opened. in_use might be true if the device type can be used in more | 723 !found_video) { |
646 // than one session. | 724 request.state[request.options.video_type] = DeviceRequest::STATE_ERROR; |
647 DCHECK_EQ(request_it->second.state[device_it->stream_type], | |
648 DeviceRequest::STATE_PENDING_APPROVAL); | |
649 device_info.in_use = false; | |
650 device_info.session_id = | |
651 GetDeviceManager(device_info.stream_type)->Open(device_info); | |
652 request_it->second.state[device_it->stream_type] = | |
653 DeviceRequest::STATE_OPENING; | |
654 if (device_info.stream_type == | |
655 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | |
656 request_it->second.audio_devices.push_back(device_info); | |
657 } else if (device_info.stream_type == | |
658 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | |
659 request_it->second.video_devices.push_back(device_info); | |
660 } else { | |
661 NOTREACHED(); | |
662 } | |
663 } | |
664 // Check if we received all stream types requested. | |
665 MediaStreamType stream_type = | |
666 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | |
667 if (Requested(request_it->second.options, stream_type) && | |
668 request_it->second.audio_devices.size() == 0) { | |
669 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | |
670 } | |
671 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | |
672 if (Requested(request_it->second.options, stream_type) && | |
673 request_it->second.video_devices.size() == 0) { | |
674 request_it->second.state[stream_type] = DeviceRequest::STATE_ERROR; | |
675 } | |
676 return; | |
677 } | 725 } |
678 } | 726 } |
679 | 727 |
680 void MediaStreamManager::SettingsError(const std::string& label) { | 728 void MediaStreamManager::SettingsError(const std::string& label) { |
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 729 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
682 // Erase this request and report an error. | 730 // Erase this request and report an error. |
683 DeviceRequests::iterator it = requests_.find(label); | 731 DeviceRequests::iterator it = requests_.find(label); |
684 if (it != requests_.end()) { | 732 if (it != requests_.end()) { |
685 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); | 733 DCHECK_EQ(it->second.type, DeviceRequest::GENERATE_STREAM); |
686 it->second.requester->StreamGenerationFailed(label); | 734 it->second.requester->StreamGenerationFailed(label); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 DevicesFromRequest(request, &closed_devices); | 778 DevicesFromRequest(request, &closed_devices); |
731 if (closed_devices.empty()) | 779 if (closed_devices.empty()) |
732 return; | 780 return; |
733 media_observer->OnCaptureDevicesClosed(request->render_process_id, | 781 media_observer->OnCaptureDevicesClosed(request->render_process_id, |
734 request->render_view_id, | 782 request->render_view_id, |
735 closed_devices); | 783 closed_devices); |
736 } | 784 } |
737 | 785 |
738 void MediaStreamManager::DevicesFromRequest( | 786 void MediaStreamManager::DevicesFromRequest( |
739 DeviceRequest* request, content::MediaStreamDevices* devices) { | 787 DeviceRequest* request, content::MediaStreamDevices* devices) { |
740 StreamDeviceInfoArray::const_iterator it = request->audio_devices.begin(); | 788 for (StreamDeviceInfoArray::const_iterator it = request->devices.begin(); |
741 for (; it != request->audio_devices.end(); ++it) { | 789 it != request->devices.end(); ++it) { |
742 devices->push_back( | 790 devices->push_back(content::MediaStreamDevice( |
743 content::MediaStreamDevice( | 791 it->stream_type, it->device_id, it->name)); |
744 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, | |
745 it->device_id, | |
746 it->name)); | |
747 } | |
748 for (it = request->video_devices.begin(); it != request->video_devices.end(); | |
749 ++it) { | |
750 devices->push_back( | |
751 content::MediaStreamDevice( | |
752 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | |
753 it->device_id, | |
754 it->name)); | |
755 } | 792 } |
756 } | 793 } |
757 | 794 |
758 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { | 795 bool MediaStreamManager::RequestDone(const DeviceRequest& request) const { |
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 796 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
760 // Check if all devices are opened. | |
761 MediaStreamType stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | |
762 if (Requested(request.options, stream_type)) { | |
763 if (request.state[stream_type] != DeviceRequest::STATE_DONE && | |
764 request.state[stream_type] != DeviceRequest::STATE_ERROR) { | |
765 return false; | |
766 } | |
767 | 797 |
768 for (StreamDeviceInfoArray::const_iterator it = | 798 const bool requested_audio = |
769 request.audio_devices.begin(); it != request.audio_devices.end(); | 799 content::IsAudioMediaType(request.options.audio_type); |
770 ++it) { | 800 const bool requested_video = |
771 if (it->in_use == false) { | 801 content::IsVideoMediaType(request.options.video_type); |
772 return false; | 802 |
773 } | 803 const bool audio_done = |
774 } | 804 !requested_audio || |
805 request.state[request.options.audio_type] == DeviceRequest::STATE_DONE || | |
806 request.state[request.options.audio_type] == DeviceRequest::STATE_ERROR; | |
807 if (!audio_done) { | |
808 return false; | |
775 } | 809 } |
776 | 810 |
777 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | 811 const bool video_done = |
778 if (Requested(request.options, stream_type)) { | 812 !requested_video || |
779 if (request.state[stream_type] != DeviceRequest::STATE_DONE && | 813 request.state[request.options.video_type] == DeviceRequest::STATE_DONE || |
780 request.state[stream_type] != DeviceRequest::STATE_ERROR) { | 814 request.state[request.options.video_type] == DeviceRequest::STATE_ERROR; |
815 if (!video_done) { | |
816 return false; | |
817 } | |
818 | |
819 for (StreamDeviceInfoArray::const_iterator it = request.devices.begin(); | |
820 it != request.devices.end(); ++it) { | |
821 if (it->in_use == false) { | |
781 return false; | 822 return false; |
782 } | 823 } |
783 | |
784 for (StreamDeviceInfoArray::const_iterator it = | |
785 request.video_devices.begin(); it != request.video_devices.end(); | |
786 ++it) { | |
787 if (it->in_use == false) { | |
788 return false; | |
789 } | |
790 } | |
791 } | 824 } |
792 | 825 |
793 return true; | 826 return true; |
794 } | 827 } |
795 | 828 |
796 // Called to get media capture device manager of specified type. | |
797 MediaStreamProvider* MediaStreamManager::GetDeviceManager( | 829 MediaStreamProvider* MediaStreamManager::GetDeviceManager( |
798 MediaStreamType stream_type) { | 830 MediaStreamType stream_type) { |
799 if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) { | 831 if (content::IsVideoMediaType(stream_type)) { |
800 return video_capture_manager(); | 832 return video_capture_manager(); |
801 } else if (stream_type == content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) { | 833 } else if (content::IsAudioMediaType(stream_type)) { |
802 return audio_input_device_manager(); | 834 return audio_input_device_manager(); |
803 } | 835 } |
804 NOTREACHED(); | 836 NOTREACHED(); |
805 return NULL; | 837 return NULL; |
806 } | 838 } |
807 | 839 |
808 void MediaStreamManager::OnDevicesChanged( | 840 void MediaStreamManager::OnDevicesChanged( |
809 base::SystemMonitor::DeviceType device_type) { | 841 base::SystemMonitor::DeviceType device_type) { |
810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
843 | |
844 // NOTE: This method is only called in response to physical audio/video device | |
845 // changes (from the operating system). | |
846 | |
811 MediaStreamType stream_type; | 847 MediaStreamType stream_type; |
812 EnumerationCache* cache; | 848 EnumerationCache* cache; |
813 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { | 849 if (device_type == base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE) { |
814 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE; | 850 stream_type = content::MEDIA_DEVICE_AUDIO_CAPTURE; |
815 cache = &audio_enumeration_cache_; | 851 cache = &audio_enumeration_cache_; |
816 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { | 852 } else if (device_type == base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE) { |
817 stream_type = content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE; | 853 stream_type = content::MEDIA_DEVICE_VIDEO_CAPTURE; |
818 cache = &video_enumeration_cache_; | 854 cache = &video_enumeration_cache_; |
819 } else { | 855 } else { |
820 return; // Uninteresting device change. | 856 return; // Uninteresting device change. |
821 } | 857 } |
822 | 858 |
823 if (!HasEnumerationRequest(stream_type)) { | 859 if (!HasEnumerationRequest(stream_type)) { |
824 // There is no request for that type, No need to enumerate devices. | 860 // There is no request for that type, No need to enumerate devices. |
825 // Therefore, invalidate the cache of that type. | 861 // Therefore, invalidate the cache of that type. |
826 ClearEnumerationCache(cache); | 862 ClearEnumerationCache(cache); |
827 return; | 863 return; |
(...skipping 24 matching lines...) Expand all Loading... | |
852 it != requests_.end(); ++it) { | 888 it != requests_.end(); ++it) { |
853 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && | 889 if (it->second.type == DeviceRequest::ENUMERATE_DEVICES && |
854 Requested(it->second.options, stream_type)) { | 890 Requested(it->second.options, stream_type)) { |
855 return true; | 891 return true; |
856 } | 892 } |
857 } | 893 } |
858 return false; | 894 return false; |
859 } | 895 } |
860 | 896 |
861 } // namespace media_stream | 897 } // namespace media_stream |
OLD | NEW |