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/video_capture_manager.h" | 5 #include "content/browser/renderer_host/media/video_capture_manager.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
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 21 matching lines...) Expand all Loading... | |
32 VideoCaptureManager::DeviceEntry::DeviceEntry( | 32 VideoCaptureManager::DeviceEntry::DeviceEntry( |
33 MediaStreamType stream_type, | 33 MediaStreamType stream_type, |
34 const std::string& id, | 34 const std::string& id, |
35 scoped_ptr<VideoCaptureController> controller) | 35 scoped_ptr<VideoCaptureController> controller) |
36 : stream_type(stream_type), | 36 : stream_type(stream_type), |
37 id(id), | 37 id(id), |
38 video_capture_controller(controller.Pass()) {} | 38 video_capture_controller(controller.Pass()) {} |
39 | 39 |
40 VideoCaptureManager::DeviceEntry::~DeviceEntry() {} | 40 VideoCaptureManager::DeviceEntry::~DeviceEntry() {} |
41 | 41 |
42 VideoCaptureManager::DeviceInfo::DeviceInfo() {} | |
43 | |
44 VideoCaptureManager::DeviceInfo::DeviceInfo( | |
45 const media::VideoCaptureDevice::Name& name, | |
46 const media::VideoCaptureCapabilities& capabilities) | |
47 : name_(name), capabilities_(capabilities) {} | |
48 | |
49 VideoCaptureManager::DeviceInfo::~DeviceInfo() {} | |
50 | |
42 VideoCaptureManager::VideoCaptureManager() | 51 VideoCaptureManager::VideoCaptureManager() |
43 : listener_(NULL), | 52 : listener_(NULL), |
44 new_capture_session_id_(1), | 53 new_capture_session_id_(1), |
45 use_fake_device_(false) { | 54 use_fake_device_(false) { |
46 } | 55 } |
47 | 56 |
48 VideoCaptureManager::~VideoCaptureManager() { | 57 VideoCaptureManager::~VideoCaptureManager() { |
49 DCHECK(devices_.empty()); | 58 DCHECK(devices_.empty()); |
50 } | 59 } |
51 | 60 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
137 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { | 146 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { |
138 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 147 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
139 DCHECK(IsOnDeviceThread()); | 148 DCHECK(IsOnDeviceThread()); |
140 | 149 |
141 scoped_ptr<media::VideoCaptureDevice> video_capture_device; | 150 scoped_ptr<media::VideoCaptureDevice> video_capture_device; |
142 switch (entry->stream_type) { | 151 switch (entry->stream_type) { |
143 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 152 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
144 // We look up the device id from the renderer in our local enumeration | 153 // We look up the device id from the renderer in our local enumeration |
145 // since the renderer does not have all the information that might be | 154 // since the renderer does not have all the information that might be |
146 // held in the browser-side VideoCaptureDevice::Name structure. | 155 // held in the browser-side VideoCaptureDevice::Name structure. |
147 media::VideoCaptureDevice::Name* found = | 156 class DeviceInfo* found = FindDeviceInfoById(entry->id); |
148 video_capture_devices_.FindById(entry->id); | |
149 if (found) { | 157 if (found) { |
150 video_capture_device.reset(use_fake_device_ ? | 158 video_capture_device.reset(use_fake_device_ ? |
151 media::FakeVideoCaptureDevice::Create(*found) : | 159 media::FakeVideoCaptureDevice::Create(found->name_) : |
152 media::VideoCaptureDevice::Create(*found)); | 160 media::VideoCaptureDevice::Create(found->name_)); |
161 | |
162 // After opening a device, we currently assume that it cannot be opened | |
163 // in any other format than the actual, so we clear the capabilities. | |
164 found->capabilities_.clear(); | |
165 found->capabilities_.push_back(capture_params); | |
153 } | 166 } |
154 break; | 167 break; |
155 } | 168 } |
156 case MEDIA_TAB_VIDEO_CAPTURE: { | 169 case MEDIA_TAB_VIDEO_CAPTURE: { |
157 video_capture_device.reset( | 170 video_capture_device.reset( |
158 WebContentsVideoCaptureDevice::Create(entry->id)); | 171 WebContentsVideoCaptureDevice::Create(entry->id)); |
159 break; | 172 break; |
160 } | 173 } |
161 case MEDIA_DESKTOP_VIDEO_CAPTURE: { | 174 case MEDIA_DESKTOP_VIDEO_CAPTURE: { |
162 #if defined(ENABLE_SCREEN_CAPTURE) | 175 #if defined(ENABLE_SCREEN_CAPTURE) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 | 258 |
246 // Detach client from controller. | 259 // Detach client from controller. |
247 int session_id = controller->RemoveClient(client_id, client_handler); | 260 int session_id = controller->RemoveClient(client_id, client_handler); |
248 DVLOG(1) << "VideoCaptureManager::StopCaptureForClient, session_id = " | 261 DVLOG(1) << "VideoCaptureManager::StopCaptureForClient, session_id = " |
249 << session_id; | 262 << session_id; |
250 | 263 |
251 // If controller has no more clients, delete controller and device. | 264 // If controller has no more clients, delete controller and device. |
252 DestroyDeviceEntryIfNoClients(entry); | 265 DestroyDeviceEntryIfNoClients(entry); |
253 } | 266 } |
254 | 267 |
268 void VideoCaptureManager::EnumerateDeviceCapabilities( | |
269 const StreamDeviceInfo& device_info) { | |
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
271 DVLOG(1) << "EnumerateDeviceCapabilites for: " << device_info.device.name; | |
272 DCHECK(listener_); | |
273 base::PostTaskAndReplyWithResult( | |
274 device_loop_, | |
275 FROM_HERE, | |
276 base::Bind(&VideoCaptureManager::GetDeviceCapabilitiesOnDeviceThread, | |
277 this, | |
278 device_info), | |
279 base::Bind(&VideoCaptureManager::OnDeviceCapabilitiesEnumerated, | |
280 this, | |
281 device_info)); | |
282 } | |
283 | |
255 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { | 284 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { |
256 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); | 285 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
257 DCHECK(IsOnDeviceThread()); | 286 DCHECK(IsOnDeviceThread()); |
258 if (entry->video_capture_device) { | 287 if (entry->video_capture_device) { |
259 entry->video_capture_device->StopAndDeAllocate(); | 288 entry->video_capture_device->StopAndDeAllocate(); |
289 // When the device is closed, its capabilities are reread from the device | |
290 // to reflect that all are possible. | |
291 class DeviceInfo* device_info = FindDeviceInfoById(entry->id); | |
292 if (device_info) { | |
293 if (!use_fake_device_) { | |
294 media::VideoCaptureDevice::GetDeviceSupportedFormats( | |
295 device_info->name_, &(device_info->capabilities_)); | |
296 } else { | |
297 media::FakeVideoCaptureDevice::GetDeviceSupportedFormats( | |
298 device_info->name_, &(device_info->capabilities_)); | |
299 } | |
300 } | |
260 } | 301 } |
261 entry->video_capture_device.reset(); | 302 entry->video_capture_device.reset(); |
262 } | 303 } |
263 | 304 |
264 void VideoCaptureManager::OnOpened(MediaStreamType stream_type, | 305 void VideoCaptureManager::OnOpened(MediaStreamType stream_type, |
265 int capture_session_id) { | 306 int capture_session_id) { |
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
267 if (!listener_) { | 308 if (!listener_) { |
268 // Listener has been removed. | 309 // Listener has been removed. |
269 return; | 310 return; |
270 } | 311 } |
271 listener_->Opened(stream_type, capture_session_id); | 312 listener_->Opened(stream_type, capture_session_id); |
272 } | 313 } |
273 | 314 |
274 void VideoCaptureManager::OnClosed(MediaStreamType stream_type, | 315 void VideoCaptureManager::OnClosed(MediaStreamType stream_type, |
275 int capture_session_id) { | 316 int capture_session_id) { |
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
277 if (!listener_) { | 318 if (!listener_) { |
278 // Listener has been removed. | 319 // Listener has been removed. |
279 return; | 320 return; |
280 } | 321 } |
281 listener_->Closed(stream_type, capture_session_id); | 322 listener_->Closed(stream_type, capture_session_id); |
282 } | 323 } |
283 | 324 |
284 void VideoCaptureManager::OnDevicesEnumerated( | 325 void VideoCaptureManager::OnDevicesEnumerated( |
285 MediaStreamType stream_type, | 326 MediaStreamType stream_type, |
286 const media::VideoCaptureDevice::Names& device_names) { | 327 const media::VideoCaptureDevice::Names& device_names) { |
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
288 | |
289 if (!listener_) { | 329 if (!listener_) { |
290 // Listener has been removed. | 330 // Listener has been removed. |
291 return; | 331 return; |
292 } | 332 } |
293 | 333 |
294 // Transform from VCD::Name to StreamDeviceInfo. | 334 // Transform from VCD::Name to StreamDeviceInfo. |
295 StreamDeviceInfoArray devices; | 335 StreamDeviceInfoArray devices; |
296 for (media::VideoCaptureDevice::Names::const_iterator it = | 336 for (media::VideoCaptureDevice::Names::const_iterator it = |
297 device_names.begin(); it != device_names.end(); ++it) { | 337 device_names.begin(); it != device_names.end(); ++it) { |
298 devices.push_back(StreamDeviceInfo( | 338 devices.push_back(StreamDeviceInfo( |
299 stream_type, it->GetNameAndModel(), it->id())); | 339 stream_type, it->GetNameAndModel(), it->id())); |
300 } | 340 } |
301 | 341 |
302 listener_->DevicesEnumerated(stream_type, devices); | 342 listener_->DevicesEnumerated(stream_type, devices); |
303 } | 343 } |
304 | 344 |
345 void VideoCaptureManager::OnDeviceCapabilitiesEnumerated( | |
346 const StreamDeviceInfo& device_info, | |
347 const media::VideoCaptureCapabilities& capabilities) { | |
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
349 if (!listener_) { | |
350 // Listener has been removed. | |
351 return; | |
352 } | |
353 listener_->DeviceCapabilitiesEnumerated(device_info, capabilities); | |
354 } | |
355 | |
305 bool VideoCaptureManager::IsOnDeviceThread() const { | 356 bool VideoCaptureManager::IsOnDeviceThread() const { |
306 return device_loop_->BelongsToCurrentThread(); | 357 return device_loop_->BelongsToCurrentThread(); |
307 } | 358 } |
308 | 359 |
309 media::VideoCaptureDevice::Names | 360 media::VideoCaptureDevice::Names |
310 VideoCaptureManager::GetAvailableDevicesOnDeviceThread( | 361 VideoCaptureManager::GetAvailableDevicesOnDeviceThread( |
311 MediaStreamType stream_type) { | 362 MediaStreamType stream_type) { |
312 SCOPED_UMA_HISTOGRAM_TIMER( | 363 SCOPED_UMA_HISTOGRAM_TIMER( |
313 "Media.VideoCaptureManager.GetAvailableDevicesTime"); | 364 "Media.VideoCaptureManager.GetAvailableDevicesTime"); |
314 DCHECK(IsOnDeviceThread()); | 365 DCHECK(IsOnDeviceThread()); |
315 media::VideoCaptureDevice::Names result; | 366 media::VideoCaptureDevice::Names names; |
316 | 367 |
317 switch (stream_type) { | 368 switch (stream_type) { |
318 case MEDIA_DEVICE_VIDEO_CAPTURE: | 369 case MEDIA_DEVICE_VIDEO_CAPTURE: |
319 // Cache the latest enumeration of video capture devices. | 370 // Cache the latest enumeration of video capture devices. |
320 // We'll refer to this list again in OnOpen to avoid having to | 371 // We'll refer to this list again in OnOpen to avoid having to |
321 // enumerate the devices again. | 372 // enumerate the devices again. |
322 if (!use_fake_device_) { | 373 if (!use_fake_device_) { |
323 media::VideoCaptureDevice::GetDeviceNames(&result); | 374 media::VideoCaptureDevice::GetDeviceNames(&names); |
375 // Walk the |names|, retrieve the capabilities and add all information | |
376 // to the local device info cache. | |
377 media::VideoCaptureCapabilities capabilities; | |
378 media::VideoCaptureDevice::Names::iterator name_it; | |
379 for (name_it = names.begin(); name_it != names.end(); ++name_it) { | |
380 media::VideoCaptureDevice::GetDeviceSupportedFormats(*name_it, | |
perkj_chrome
2013/10/29 12:13:36
In the previous Cl we said that media::VideoCaptur
| |
381 &capabilities); | |
382 devices_info_cache_.push_back(DeviceInfo(*name_it, capabilities)); | |
383 } | |
324 } else { | 384 } else { |
325 media::FakeVideoCaptureDevice::GetDeviceNames(&result); | 385 media::FakeVideoCaptureDevice::GetDeviceNames(&names); |
386 // Walk the |names|, retrieve the capabilities and add all information | |
387 // to the local device info cache. | |
388 media::VideoCaptureCapabilities capabilities; | |
389 media::VideoCaptureDevice::Names::iterator name_it; | |
390 for (name_it = names.begin(); name_it != names.end(); ++name_it) { | |
391 media::FakeVideoCaptureDevice::GetDeviceSupportedFormats( | |
392 *name_it, &capabilities); | |
393 devices_info_cache_.push_back(DeviceInfo(*name_it, capabilities)); | |
394 } | |
326 } | 395 } |
327 | 396 |
328 // TODO(nick): The correctness of device start depends on this cache being | 397 // TODO(nick): The correctness of device start depends on the cache being |
329 // maintained, but it seems a little odd to keep a cache here. Can we | 398 // maintained, but it seems a little odd to keep a cache here. Can we |
330 // eliminate it? | 399 // eliminate it? |
331 video_capture_devices_ = result; | |
332 break; | 400 break; |
333 | 401 |
334 case MEDIA_DESKTOP_VIDEO_CAPTURE: | 402 case MEDIA_DESKTOP_VIDEO_CAPTURE: |
335 // Do nothing. | 403 // Do nothing. |
336 break; | 404 break; |
337 | 405 |
338 default: | 406 default: |
339 NOTREACHED(); | 407 NOTREACHED(); |
340 break; | 408 break; |
341 } | 409 } |
342 return result; | 410 return names; |
411 } | |
412 | |
413 media::VideoCaptureCapabilities | |
414 VideoCaptureManager::GetDeviceCapabilitiesOnDeviceThread( | |
415 const StreamDeviceInfo& device_info) { | |
416 DCHECK(IsOnDeviceThread()); | |
417 | |
418 // Find the device we are looking for and return its associated capabilities. | |
419 class DeviceInfo* device = FindDeviceInfoById(device_info.device.id); | |
420 if (device) | |
421 return device->capabilities_; | |
422 return media::VideoCaptureCapabilities(); | |
343 } | 423 } |
344 | 424 |
345 VideoCaptureManager::DeviceEntry* | 425 VideoCaptureManager::DeviceEntry* |
346 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( | 426 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( |
347 const MediaStreamDevice& device_info) { | 427 const MediaStreamDevice& device_info) { |
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
349 | 429 |
350 for (DeviceEntries::iterator it = devices_.begin(); | 430 for (DeviceEntries::iterator it = devices_.begin(); |
351 it != devices_.end(); ++it) { | 431 it != devices_.end(); ++it) { |
352 DeviceEntry* device = *it; | 432 DeviceEntry* device = *it; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 | 493 |
414 scoped_ptr<VideoCaptureController> video_capture_controller( | 494 scoped_ptr<VideoCaptureController> video_capture_controller( |
415 new VideoCaptureController()); | 495 new VideoCaptureController()); |
416 DeviceEntry* new_device = new DeviceEntry(device_info.type, | 496 DeviceEntry* new_device = new DeviceEntry(device_info.type, |
417 device_info.id, | 497 device_info.id, |
418 video_capture_controller.Pass()); | 498 video_capture_controller.Pass()); |
419 devices_.insert(new_device); | 499 devices_.insert(new_device); |
420 return new_device; | 500 return new_device; |
421 } | 501 } |
422 | 502 |
503 class VideoCaptureManager::DeviceInfo* | |
perkj_chrome
2013/10/29 12:13:36
remove class
| |
504 VideoCaptureManager::FindDeviceInfoById(const std::string& id) { | |
505 std::vector<class DeviceInfo>::iterator it; | |
506 for (it = devices_info_cache_.begin(); | |
507 it != devices_info_cache_.end(); | |
508 ++it) { | |
509 if (it->name_.id() == id) | |
510 return &(*it); | |
511 } | |
512 return NULL; | |
513 } | |
514 | |
423 } // namespace content | 515 } // namespace content |
OLD | NEW |