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

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: Adapted VCD unittests to enumeration via callback. Created 6 years, 7 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"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698