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

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

Issue 294893006: VideoCaptureDeviceFactory: Change device enumeration to callback + QTKit enumerates in UI thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: perkj@s comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/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"
20 #include "content/public/common/content_switches.h" 21 #include "content/public/common/content_switches.h"
21 #include "content/public/common/media_stream_request.h" 22 #include "content/public/common/media_stream_request.h"
23 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/scoped_histogram_timer.h" 24 #include "media/base/scoped_histogram_timer.h"
23 #include "media/video/capture/video_capture_device.h" 25 #include "media/video/capture/video_capture_device.h"
24 #include "media/video/capture/video_capture_device_factory.h" 26 #include "media/video/capture/video_capture_device_factory.h"
25 27
26 #if defined(ENABLE_SCREEN_CAPTURE) 28 #if defined(ENABLE_SCREEN_CAPTURE)
27 #include "content/browser/media/capture/desktop_capture_device.h" 29 #include "content/browser/media/capture/desktop_capture_device.h"
28 #if defined(USE_AURA) 30 #if defined(USE_AURA)
29 #include "content/browser/media/capture/desktop_capture_device_aura.h" 31 #include "content/browser/media/capture/desktop_capture_device_aura.h"
30 #endif 32 #endif
31 #endif 33 #endif
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 117
116 void VideoCaptureManager::Unregister() { 118 void VideoCaptureManager::Unregister() {
117 DCHECK(listener_); 119 DCHECK(listener_);
118 listener_ = NULL; 120 listener_ = NULL;
119 } 121 }
120 122
121 void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) { 123 void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) {
122 DCHECK_CURRENTLY_ON(BrowserThread::IO); 124 DCHECK_CURRENTLY_ON(BrowserThread::IO);
123 DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type; 125 DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type;
124 DCHECK(listener_); 126 DCHECK(listener_);
125 base::PostTaskAndReplyWithResult( 127 DCHECK_EQ(stream_type, MEDIA_DEVICE_VIDEO_CAPTURE);
126 device_task_runner_, FROM_HERE, 128
127 base::Bind(&VideoCaptureManager::GetAvailableDevicesInfoOnDeviceThread, 129 // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument
128 this, stream_type, devices_info_cache_), 130 // for another callback to OnDevicesInfoEnumerated() to be run in the current
129 base::Bind(&VideoCaptureManager::OnDevicesInfoEnumerated, this, 131 // loop, i.e. IO loop. Pass a timer for UMA histogram collection.
130 stream_type)); 132 base::Callback<void(media::VideoCaptureDevice::Names&)>
tommi (sloooow) - chröme 2014/05/30 12:37:51 either const& or *
mcasas 2014/05/30 14:08:50 const&, done.
133 devices_enumerated_callback =
134 base::Bind(&VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread,
135 this,
136 media::BindToCurrentLoop(base::Bind(
137 &VideoCaptureManager::OnDevicesInfoEnumerated,
138 this,
139 stream_type,
140 base::Owned(new base::ElapsedTimer()))),
141 stream_type,
142 devices_info_cache_);
143 // OK to use base::Unretained() since we own the VCDFactory and |this| is
144 // bound in |devices_enumerated_callback|.
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
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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 DCHECK_CURRENTLY_ON(BrowserThread::IO); 441 DCHECK_CURRENTLY_ON(BrowserThread::IO);
426 if (!listener_) { 442 if (!listener_) {
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,
451 base::ElapsedTimer* timer,
435 const DeviceInfos& new_devices_info_cache) { 452 const DeviceInfos& new_devices_info_cache) {
436 DCHECK_CURRENTLY_ON(BrowserThread::IO); 453 DCHECK_CURRENTLY_ON(BrowserThread::IO);
437 454 UMA_HISTOGRAM_TIMES(
455 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime",
456 timer->Elapsed());
438 if (!listener_) { 457 if (!listener_) {
439 // Listener has been removed. 458 // Listener has been removed.
440 return; 459 return;
441 } 460 }
442 devices_info_cache_ = new_devices_info_cache; 461 devices_info_cache_ = new_devices_info_cache;
443 462
444 // Walk the |devices_info_cache_| and transform from VCD::Name to 463 // Walk the |devices_info_cache_| and transform from VCD::Name to
445 // StreamDeviceInfo for return purposes. 464 // StreamDeviceInfo for return purposes.
446 StreamDeviceInfoArray devices; 465 StreamDeviceInfoArray devices;
447 for (DeviceInfos::const_iterator it = devices_info_cache_.begin(); 466 for (DeviceInfos::const_iterator it = devices_info_cache_.begin();
448 it != devices_info_cache_.end(); ++it) { 467 it != devices_info_cache_.end(); ++it) {
449 devices.push_back(StreamDeviceInfo( 468 devices.push_back(StreamDeviceInfo(
450 stream_type, it->name.GetNameAndModel(), it->name.id())); 469 stream_type, it->name.GetNameAndModel(), it->name.id()));
451 } 470 }
452 listener_->DevicesEnumerated(stream_type, devices); 471 listener_->DevicesEnumerated(stream_type, devices);
453 } 472 }
454 473
455 bool VideoCaptureManager::IsOnDeviceThread() const { 474 bool VideoCaptureManager::IsOnDeviceThread() const {
456 return device_task_runner_->BelongsToCurrentThread(); 475 return device_task_runner_->BelongsToCurrentThread();
457 } 476 }
458 477
459 VideoCaptureManager::DeviceInfos 478 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread(
460 VideoCaptureManager::GetAvailableDevicesInfoOnDeviceThread( 479 base::Callback<void(const DeviceInfos&)> on_devices_enumerated_callback,
461 MediaStreamType stream_type, 480 MediaStreamType stream_type,
462 const DeviceInfos& old_device_info_cache) { 481 const DeviceInfos& old_device_info_cache,
463 SCOPED_UMA_HISTOGRAM_TIMER( 482 media::VideoCaptureDevice::Names& names_snapshot) {
464 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime");
465 DCHECK(IsOnDeviceThread()); 483 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 484 // 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 485 // present in the system, and remove their names from |names_snapshot|, so we
484 // keep there the truly new devices. 486 // keep there the truly new devices.
485 DeviceInfos new_devices_info_cache; 487 DeviceInfos new_devices_info_cache;
486 for (DeviceInfos::const_iterator it_device_info = 488 for (DeviceInfos::const_iterator it_device_info =
487 old_device_info_cache.begin(); 489 old_device_info_cache.begin();
488 it_device_info != old_device_info_cache.end(); ++it_device_info) { 490 it_device_info != old_device_info_cache.end(); ++it_device_info) {
489 for (media::VideoCaptureDevice::Names::iterator it = 491 for (media::VideoCaptureDevice::Names::iterator it =
490 names_snapshot.begin(); 492 names_snapshot.begin();
491 it != names_snapshot.end(); ++it) { 493 it != names_snapshot.end(); ++it) {
492 if (it_device_info->name.id() == it->id()) { 494 if (it_device_info->name.id() == it->id()) {
493 new_devices_info_cache.push_back(*it_device_info); 495 new_devices_info_cache.push_back(*it_device_info);
494 names_snapshot.erase(it); 496 names_snapshot.erase(it);
495 break; 497 break;
496 } 498 }
497 } 499 }
498 } 500 }
499 501
500 // Get the supported capture formats for the new devices in |names_snapshot|. 502 // Get the supported capture formats for the new devices in |names_snapshot|.
501 for (media::VideoCaptureDevice::Names::const_iterator it = 503 for (media::VideoCaptureDevice::Names::const_iterator it =
502 names_snapshot.begin(); 504 names_snapshot.begin();
503 it != names_snapshot.end(); ++it) { 505 it != names_snapshot.end(); ++it) {
504 media::VideoCaptureFormats supported_formats; 506 media::VideoCaptureFormats supported_formats;
505 DeviceInfo device_info(*it, media::VideoCaptureFormats()); 507 DeviceInfo device_info(*it, media::VideoCaptureFormats());
506 video_capture_device_factory_->GetDeviceSupportedFormats( 508 video_capture_device_factory_->GetDeviceSupportedFormats(
507 *it, &(device_info.supported_formats)); 509 *it, &(device_info.supported_formats));
508 ConsolidateCaptureFormats(&device_info.supported_formats); 510 ConsolidateCaptureFormats(&device_info.supported_formats);
509 new_devices_info_cache.push_back(device_info); 511 new_devices_info_cache.push_back(device_info);
510 } 512 }
511 return new_devices_info_cache; 513
514 on_devices_enumerated_callback.Run(new_devices_info_cache);
512 } 515 }
513 516
514 VideoCaptureManager::DeviceEntry* 517 VideoCaptureManager::DeviceEntry*
515 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( 518 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice(
516 const MediaStreamDevice& device_info) { 519 const MediaStreamDevice& device_info) {
517 DCHECK_CURRENTLY_ON(BrowserThread::IO); 520 DCHECK_CURRENTLY_ON(BrowserThread::IO);
518 521
519 for (DeviceEntries::iterator it = devices_.begin(); 522 for (DeviceEntries::iterator it = devices_.begin();
520 it != devices_.end(); ++it) { 523 it != devices_.end(); ++it) {
521 DeviceEntry* device = *it; 524 DeviceEntry* device = *it;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread( 617 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread(
615 media::VideoCaptureSessionId session_id, 618 media::VideoCaptureSessionId session_id,
616 gfx::NativeViewId window_id) { 619 gfx::NativeViewId window_id) {
617 DCHECK(IsOnDeviceThread()); 620 DCHECK(IsOnDeviceThread());
618 DCHECK(notification_window_ids_.find(session_id) == 621 DCHECK(notification_window_ids_.find(session_id) ==
619 notification_window_ids_.end()); 622 notification_window_ids_.end());
620 notification_window_ids_[session_id] = window_id; 623 notification_window_ids_[session_id] = window_id;
621 } 624 }
622 625
623 } // namespace content 626 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698