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/bind_helpers.h" | |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/task_runner_util.h" | 14 #include "base/task_runner_util.h" |
14 #include "base/threading/sequenced_worker_pool.h" | 15 #include "base/threading/sequenced_worker_pool.h" |
15 #include "content/browser/media/capture/web_contents_video_capture_device.h" | 16 #include "content/browser/media/capture/web_contents_video_capture_device.h" |
16 #include "content/browser/renderer_host/media/video_capture_controller.h" | 17 #include "content/browser/renderer_host/media/video_capture_controller.h" |
17 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" | 18 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" |
18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
19 #include "content/public/browser/desktop_media_id.h" | 20 #include "content/public/browser/desktop_media_id.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
115 | 116 |
116 void VideoCaptureManager::Unregister() { | 117 void VideoCaptureManager::Unregister() { |
117 DCHECK(listener_); | 118 DCHECK(listener_); |
118 listener_ = NULL; | 119 listener_ = NULL; |
119 } | 120 } |
120 | 121 |
121 void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) { | 122 void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) { |
122 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 123 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
123 DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type; | 124 DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type; |
124 DCHECK(listener_); | 125 DCHECK(listener_); |
125 base::PostTaskAndReplyWithResult( | 126 if (stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
perkj_chrome
2014/05/26 11:49:42
THis looks weird. Why return devices_info_cache_
mcasas
2014/05/26 13:00:18
This was a cleanup of previous code, where
GetAva
| |
126 device_task_runner_, FROM_HERE, | 127 OnDevicesInfoEnumerated(stream_type, devices_info_cache_); |
127 base::Bind(&VideoCaptureManager::GetAvailableDevicesInfoOnDeviceThread, | 128 return; |
128 this, stream_type, devices_info_cache_), | 129 } |
129 base::Bind(&VideoCaptureManager::OnDevicesInfoEnumerated, this, | 130 DCHECK_EQ(stream_type, MEDIA_DEVICE_VIDEO_CAPTURE); |
130 stream_type)); | 131 |
132 // TODO(mcasas): replace previous SCOPED_UMA_HISTOGRAM_TIMER( | |
133 // "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime"); | |
perkj_chrome
2014/05/26 11:49:42
this does not seem to have anything to do with wha
mcasas
2014/05/26 13:00:18
Yes, this is an open question.
Before this CL, th
perkj_chrome
2014/05/27 12:15:08
Was that something you added because you wanted it
| |
134 // with a base/timer/elapsed_timer.h ElapsedTime, constructed here and | |
135 // measured in OnDevicesInfoEnumerated() | |
136 | |
137 base::Callback<void(media::VideoCaptureDevice::Names&)> | |
138 devices_enumerated_callback = | |
139 base::Bind(&VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, | |
perkj_chrome
2014/05/26 11:49:42
To avoid the raw message loop pointer - how about
mcasas
2014/05/26 13:00:18
Done.
| |
140 this, | |
141 base::MessageLoop::current(), | |
142 stream_type, | |
143 devices_info_cache_); | |
144 // OK to use base::Unretained() since we own the VCDFactory. | |
perkj_chrome
2014/05/26 11:49:42
What guarantee that the video capture manager is n
mcasas
2014/05/26 13:00:18
VCM outlives the VCDF, plus is reference counted v
| |
145 device_task_runner_->PostTask(FROM_HERE, | |
146 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceNames, | |
147 base::Unretained(video_capture_device_factory_.get()), | |
148 devices_enumerated_callback)); | |
131 } | 149 } |
132 | 150 |
133 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) { | 151 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) { |
134 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 152 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
135 DCHECK(listener_); | 153 DCHECK(listener_); |
136 | 154 |
137 // Generate a new id for the session being opened. | 155 // Generate a new id for the session being opened. |
138 const media::VideoCaptureSessionId capture_session_id = | 156 const media::VideoCaptureSessionId capture_session_id = |
139 new_capture_session_id_++; | 157 new_capture_session_id_++; |
140 | 158 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 | 211 |
194 scoped_ptr<media::VideoCaptureDevice> video_capture_device; | 212 scoped_ptr<media::VideoCaptureDevice> video_capture_device; |
195 switch (entry->stream_type) { | 213 switch (entry->stream_type) { |
196 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 214 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
197 // We look up the device id from the renderer in our local enumeration | 215 // We look up the device id from the renderer in our local enumeration |
198 // since the renderer does not have all the information that might be | 216 // since the renderer does not have all the information that might be |
199 // held in the browser-side VideoCaptureDevice::Name structure. | 217 // held in the browser-side VideoCaptureDevice::Name structure. |
200 DeviceInfo* found = FindDeviceInfoById(entry->id, devices_info_cache_); | 218 DeviceInfo* found = FindDeviceInfoById(entry->id, devices_info_cache_); |
201 if (found) { | 219 if (found) { |
202 video_capture_device = | 220 video_capture_device = |
203 video_capture_device_factory_->Create( | 221 video_capture_device_factory_->Create(found->name); |
204 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI), | |
205 found->name); | |
206 } | 222 } |
207 break; | 223 break; |
208 } | 224 } |
209 case MEDIA_TAB_VIDEO_CAPTURE: { | 225 case MEDIA_TAB_VIDEO_CAPTURE: { |
210 video_capture_device.reset( | 226 video_capture_device.reset( |
211 WebContentsVideoCaptureDevice::Create(entry->id)); | 227 WebContentsVideoCaptureDevice::Create(entry->id)); |
212 break; | 228 break; |
213 } | 229 } |
214 case MEDIA_DESKTOP_VIDEO_CAPTURE: { | 230 case MEDIA_DESKTOP_VIDEO_CAPTURE: { |
215 #if defined(ENABLE_SCREEN_CAPTURE) | 231 #if defined(ENABLE_SCREEN_CAPTURE) |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
427 // Listener has been removed. | 443 // Listener has been removed. |
428 return; | 444 return; |
429 } | 445 } |
430 listener_->Closed(stream_type, capture_session_id); | 446 listener_->Closed(stream_type, capture_session_id); |
431 } | 447 } |
432 | 448 |
433 void VideoCaptureManager::OnDevicesInfoEnumerated( | 449 void VideoCaptureManager::OnDevicesInfoEnumerated( |
434 MediaStreamType stream_type, | 450 MediaStreamType stream_type, |
435 const DeviceInfos& new_devices_info_cache) { | 451 const DeviceInfos& new_devices_info_cache) { |
436 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 452 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
437 | |
438 if (!listener_) { | 453 if (!listener_) { |
439 // Listener has been removed. | 454 // Listener has been removed. |
440 return; | 455 return; |
441 } | 456 } |
442 devices_info_cache_ = new_devices_info_cache; | 457 devices_info_cache_ = new_devices_info_cache; |
443 | 458 |
444 // Walk the |devices_info_cache_| and transform from VCD::Name to | 459 // Walk the |devices_info_cache_| and transform from VCD::Name to |
445 // StreamDeviceInfo for return purposes. | 460 // StreamDeviceInfo for return purposes. |
446 StreamDeviceInfoArray devices; | 461 StreamDeviceInfoArray devices; |
447 for (DeviceInfos::const_iterator it = devices_info_cache_.begin(); | 462 for (DeviceInfos::const_iterator it = devices_info_cache_.begin(); |
448 it != devices_info_cache_.end(); ++it) { | 463 it != devices_info_cache_.end(); ++it) { |
449 devices.push_back(StreamDeviceInfo( | 464 devices.push_back(StreamDeviceInfo( |
450 stream_type, it->name.GetNameAndModel(), it->name.id())); | 465 stream_type, it->name.GetNameAndModel(), it->name.id())); |
451 } | 466 } |
452 listener_->DevicesEnumerated(stream_type, devices); | 467 listener_->DevicesEnumerated(stream_type, devices); |
453 } | 468 } |
454 | 469 |
455 bool VideoCaptureManager::IsOnDeviceThread() const { | 470 bool VideoCaptureManager::IsOnDeviceThread() const { |
456 return device_task_runner_->BelongsToCurrentThread(); | 471 return device_task_runner_->BelongsToCurrentThread(); |
457 } | 472 } |
458 | 473 |
459 VideoCaptureManager::DeviceInfos | 474 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( |
460 VideoCaptureManager::GetAvailableDevicesInfoOnDeviceThread( | 475 base::MessageLoop* io_loop, |
461 MediaStreamType stream_type, | 476 MediaStreamType stream_type, |
462 const DeviceInfos& old_device_info_cache) { | 477 const DeviceInfos& old_device_info_cache, |
463 SCOPED_UMA_HISTOGRAM_TIMER( | 478 media::VideoCaptureDevice::Names& names_snapshot) { |
464 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime"); | |
465 DCHECK(IsOnDeviceThread()); | 479 DCHECK(IsOnDeviceThread()); |
466 media::VideoCaptureDevice::Names names_snapshot; | |
467 switch (stream_type) { | |
468 case MEDIA_DEVICE_VIDEO_CAPTURE: | |
469 // Cache the latest enumeration of video capture devices. | |
470 // We'll refer to this list again in OnOpen to avoid having to | |
471 // enumerate the devices again. | |
472 video_capture_device_factory_->GetDeviceNames(&names_snapshot); | |
473 break; | |
474 case MEDIA_DESKTOP_VIDEO_CAPTURE: | |
475 // Do nothing. | |
476 break; | |
477 default: | |
478 NOTREACHED(); | |
479 break; | |
480 } | |
481 | |
482 // Construct |new_devices_info_cache| with the cached devices that are still | 480 // Construct |new_devices_info_cache| with the cached devices that are still |
483 // present in the system, and remove their names from |names_snapshot|, so we | 481 // present in the system, and remove their names from |names_snapshot|, so we |
484 // keep there the truly new devices. | 482 // keep there the truly new devices. |
485 DeviceInfos new_devices_info_cache; | 483 DeviceInfos new_devices_info_cache; |
486 for (DeviceInfos::const_iterator it_device_info = | 484 for (DeviceInfos::const_iterator it_device_info = |
487 old_device_info_cache.begin(); | 485 old_device_info_cache.begin(); |
488 it_device_info != old_device_info_cache.end(); ++it_device_info) { | 486 it_device_info != old_device_info_cache.end(); ++it_device_info) { |
489 for (media::VideoCaptureDevice::Names::iterator it = | 487 for (media::VideoCaptureDevice::Names::iterator it = |
490 names_snapshot.begin(); | 488 names_snapshot.begin(); |
491 it != names_snapshot.end(); ++it) { | 489 it != names_snapshot.end(); ++it) { |
492 if (it_device_info->name.id() == it->id()) { | 490 if (it_device_info->name.id() == it->id()) { |
493 new_devices_info_cache.push_back(*it_device_info); | 491 new_devices_info_cache.push_back(*it_device_info); |
494 names_snapshot.erase(it); | 492 names_snapshot.erase(it); |
495 break; | 493 break; |
496 } | 494 } |
497 } | 495 } |
498 } | 496 } |
499 | 497 |
500 // Get the supported capture formats for the new devices in |names_snapshot|. | 498 // Get the supported capture formats for the new devices in |names_snapshot|. |
501 for (media::VideoCaptureDevice::Names::const_iterator it = | 499 for (media::VideoCaptureDevice::Names::const_iterator it = |
502 names_snapshot.begin(); | 500 names_snapshot.begin(); |
503 it != names_snapshot.end(); ++it) { | 501 it != names_snapshot.end(); ++it) { |
504 media::VideoCaptureFormats supported_formats; | 502 media::VideoCaptureFormats supported_formats; |
505 DeviceInfo device_info(*it, media::VideoCaptureFormats()); | 503 DeviceInfo device_info(*it, media::VideoCaptureFormats()); |
506 video_capture_device_factory_->GetDeviceSupportedFormats( | 504 video_capture_device_factory_->GetDeviceSupportedFormats( |
507 *it, &(device_info.supported_formats)); | 505 *it, &(device_info.supported_formats)); |
508 ConsolidateCaptureFormats(&device_info.supported_formats); | 506 ConsolidateCaptureFormats(&device_info.supported_formats); |
509 new_devices_info_cache.push_back(device_info); | 507 new_devices_info_cache.push_back(device_info); |
510 } | 508 } |
511 return new_devices_info_cache; | 509 |
510 io_loop->PostTask(FROM_HERE, | |
perkj_chrome
2014/05/26 11:49:42
Use a callback as input parameter instead and just
mcasas
2014/05/26 13:00:18
Done.
| |
511 base::Bind(&VideoCaptureManager::OnDevicesInfoEnumerated, | |
512 this, stream_type, new_devices_info_cache)); | |
512 } | 513 } |
513 | 514 |
514 VideoCaptureManager::DeviceEntry* | 515 VideoCaptureManager::DeviceEntry* |
515 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( | 516 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( |
516 const MediaStreamDevice& device_info) { | 517 const MediaStreamDevice& device_info) { |
517 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 518 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
518 | 519 |
519 for (DeviceEntries::iterator it = devices_.begin(); | 520 for (DeviceEntries::iterator it = devices_.begin(); |
520 it != devices_.end(); ++it) { | 521 it != devices_.end(); ++it) { |
521 DeviceEntry* device = *it; | 522 DeviceEntry* device = *it; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
614 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread( | 615 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread( |
615 media::VideoCaptureSessionId session_id, | 616 media::VideoCaptureSessionId session_id, |
616 gfx::NativeViewId window_id) { | 617 gfx::NativeViewId window_id) { |
617 DCHECK(IsOnDeviceThread()); | 618 DCHECK(IsOnDeviceThread()); |
618 DCHECK(notification_window_ids_.find(session_id) == | 619 DCHECK(notification_window_ids_.find(session_id) == |
619 notification_window_ids_.end()); | 620 notification_window_ids_.end()); |
620 notification_window_ids_[session_id] = window_id; | 621 notification_window_ids_[session_id] = window_id; |
621 } | 622 } |
622 | 623 |
623 } // namespace content | 624 } // namespace content |
OLD | NEW |