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

Side by Side Diff: media/video/capture/mac/video_capture_device_factory_mac.mm

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: QTKit/AVFoundation Factory create of inexistent device and associated unit tests 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "media/video/capture/mac/video_capture_device_factory_mac.h" 5 #include "media/video/capture/mac/video_capture_device_factory_mac.h"
6 6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/task_runner_util.h"
7 #import "media/video/capture/mac/avfoundation_glue.h" 10 #import "media/video/capture/mac/avfoundation_glue.h"
8 #include "media/video/capture/mac/video_capture_device_mac.h" 11 #include "media/video/capture/mac/video_capture_device_mac.h"
9 #import "media/video/capture/mac/video_capture_device_avfoundation_mac.h" 12 #import "media/video/capture/mac/video_capture_device_avfoundation_mac.h"
10 #import "media/video/capture/mac/video_capture_device_qtkit_mac.h" 13 #import "media/video/capture/mac/video_capture_device_qtkit_mac.h"
11 14
12 namespace media { 15 namespace media {
13 16
14 // Some devices are not correctly supported in AVFoundation, f.i. Blackmagic, 17 // Some devices are not correctly supported in AVFoundation, f.i. Blackmagic,
15 // see http://crbug.com/347371. The devices are identified by USB Vendor ID and 18 // see http://crbug.com/347371. The devices are identified by USB Vendor ID and
16 // by a characteristic substring of the name, usually the vendor's name. 19 // by a characteristic substring of the name, usually the vendor's name.
17 const struct NameAndVid { 20 const struct NameAndVid {
18 const char* vid; 21 const char* vid;
19 const char* name; 22 const char* name;
20 } kBlacklistedCameras[] = { { "a82c", "Blackmagic" } }; 23 } kBlacklistedCameras[] = { { "a82c", "Blackmagic" } };
21 24
22 // In device identifiers, the USB VID and PID are stored in 4 bytes each. 25 // In device identifiers, the USB VID and PID are stored in 4 bytes each.
23 const size_t kVidPidSize = 4; 26 const size_t kVidPidSize = 4;
24 27
25 VideoCaptureDeviceFactoryMac::VideoCaptureDeviceFactoryMac() { 28 static scoped_ptr<media::VideoCaptureDevice::Names>
29 EnumerateDevicesUsingQTKit() {
30 scoped_ptr<VideoCaptureDevice::Names> device_names(
31 new VideoCaptureDevice::Names());
32 NSMutableDictionary* capture_devices =
33 [[[NSMutableDictionary alloc] init] autorelease];
34 [VideoCaptureDeviceQTKit getDeviceNames:capture_devices];
35 for (NSString* key in capture_devices) {
36 VideoCaptureDevice::Name name(
37 [[capture_devices valueForKey:key] UTF8String],
38 [key UTF8String], VideoCaptureDevice::Name::QTKIT);
39 device_names->push_back(name);
40 }
41 return device_names.Pass();
42 }
43
44 static void RunDevicesEnumeratedCallback(
45 const base::Callback<void(scoped_ptr<media::VideoCaptureDevice::Names>)>&
46 callback,
47 scoped_ptr<media::VideoCaptureDevice::Names> device_names) {
48 callback.Run(device_names.Pass());
49 }
50
51 // static
52 bool VideoCaptureDeviceFactoryMac::PlatformSupportsAVFoundation() {
53 return AVFoundationGlue::IsAVFoundationSupported();
54 }
55
56 VideoCaptureDeviceFactoryMac::VideoCaptureDeviceFactoryMac(
57 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
58 : ui_task_runner_(ui_task_runner) {
26 thread_checker_.DetachFromThread(); 59 thread_checker_.DetachFromThread();
27 } 60 }
28 61
62 VideoCaptureDeviceFactoryMac::~VideoCaptureDeviceFactoryMac() {}
63
29 scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryMac::Create( 64 scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryMac::Create(
30 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
31 const VideoCaptureDevice::Name& device_name) { 65 const VideoCaptureDevice::Name& device_name) {
32 DCHECK(thread_checker_.CalledOnValidThread()); 66 DCHECK(thread_checker_.CalledOnValidThread());
33 DCHECK_NE(device_name.capture_api_type(), 67 DCHECK_NE(device_name.capture_api_type(),
34 VideoCaptureDevice::Name::API_TYPE_UNKNOWN); 68 VideoCaptureDevice::Name::API_TYPE_UNKNOWN);
35 69
36 VideoCaptureDevice::Names device_names; 70 // Check device presence only for AVFoundation API, since it is too expensive
37 GetDeviceNames(&device_names); 71 // and brittle for QTKit. The actual initialization at device level will fail
38 VideoCaptureDevice::Names::iterator it = device_names.begin(); 72 // subsequently if the device is not present.
39 for (; it != device_names.end(); ++it) { 73 if (AVFoundationGlue::IsAVFoundationSupported()) {
40 if (it->id() == device_name.id()) 74 scoped_ptr<VideoCaptureDevice::Names> device_names(
41 break; 75 new VideoCaptureDevice::Names());
76 GetDeviceNames(device_names.get());
tommi (sloooow) - chröme 2014/06/01 11:25:22 Doesn't this also enumerate QTKit devices? (Blackm
mcasas 2014/06/02 13:19:04 Yes, if present in the system.
77
78 VideoCaptureDevice::Names::iterator it = device_names->begin();
79 for (; it != device_names->end(); ++it) {
80 if (it->id() == device_name.id())
81 break;
82 }
83 if (it == device_names->end())
84 return scoped_ptr<VideoCaptureDevice>();
tommi (sloooow) - chröme 2014/06/01 11:25:22 If this check indeed only looks at devices from av
mcasas 2014/06/02 13:19:04 Just to be clear of the process, there are current
tommi (sloooow) - chröme 2014/06/03 08:52:11 OK, thanks. So just to recap and verify that my u
mcasas 2014/06/03 13:56:46 That's correct.
42 } 85 }
43 if (it == device_names.end())
44 return scoped_ptr<VideoCaptureDevice>();
45 86
46 scoped_ptr<VideoCaptureDeviceMac> capture_device( 87 scoped_ptr<VideoCaptureDeviceMac> capture_device(
47 new VideoCaptureDeviceMac(device_name)); 88 new VideoCaptureDeviceMac(device_name));
48 if (!capture_device->Init(device_name.capture_api_type())) { 89 if (!capture_device->Init(device_name.capture_api_type())) {
49 LOG(ERROR) << "Could not initialize VideoCaptureDevice."; 90 LOG(ERROR) << "Could not initialize VideoCaptureDevice.";
50 capture_device.reset(); 91 capture_device.reset();
51 } 92 }
52 return scoped_ptr<VideoCaptureDevice>(capture_device.Pass()); 93 return scoped_ptr<VideoCaptureDevice>(capture_device.Pass());
53 } 94 }
54 95
55 void VideoCaptureDeviceFactoryMac::GetDeviceNames( 96 void VideoCaptureDeviceFactoryMac::GetDeviceNames(
56 VideoCaptureDevice::Names* const device_names) { 97 VideoCaptureDevice::Names* device_names) {
57 DCHECK(thread_checker_.CalledOnValidThread()); 98 DCHECK(thread_checker_.CalledOnValidThread());
58 // Loop through all available devices and add to |device_names|. 99 // Loop through all available devices and add to |device_names|.
59 NSDictionary* capture_devices; 100 NSDictionary* capture_devices;
60 if (AVFoundationGlue::IsAVFoundationSupported()) { 101 if (AVFoundationGlue::IsAVFoundationSupported()) {
61 bool is_any_device_blacklisted = false; 102 bool is_any_device_blacklisted = false;
62 DVLOG(1) << "Enumerating video capture devices using AVFoundation"; 103 DVLOG(1) << "Enumerating video capture devices using AVFoundation";
63 capture_devices = [VideoCaptureDeviceAVFoundation deviceNames]; 104 capture_devices = [VideoCaptureDeviceAVFoundation deviceNames];
64 std::string device_vid; 105 std::string device_vid;
65 // Enumerate all devices found by AVFoundation, translate the info for each 106 // Enumerate all devices found by AVFoundation, translate the info for each
66 // to class Name and add it to |device_names|. 107 // to class Name and add it to |device_names|.
(...skipping 25 matching lines...) Expand all
92 DVLOG(1) << "Enumerated blacklisted " << [device_name UTF8String]; 133 DVLOG(1) << "Enumerated blacklisted " << [device_name UTF8String];
93 VideoCaptureDevice::Name name( 134 VideoCaptureDevice::Name name(
94 "QTKit " + std::string([device_name UTF8String]), 135 "QTKit " + std::string([device_name UTF8String]),
95 [key UTF8String], VideoCaptureDevice::Name::QTKIT); 136 [key UTF8String], VideoCaptureDevice::Name::QTKIT);
96 device_names->push_back(name); 137 device_names->push_back(name);
97 } 138 }
98 } 139 }
99 } 140 }
100 } 141 }
101 } else { 142 } else {
102 DVLOG(1) << "Enumerating video capture devices using QTKit"; 143 // We should not enumerate QTKit devices in Device Thread;
103 capture_devices = [VideoCaptureDeviceQTKit deviceNames]; 144 NOTREACHED();
104 for (NSString* key in capture_devices) {
105 VideoCaptureDevice::Name name(
106 [[capture_devices valueForKey:key] UTF8String],
107 [key UTF8String], VideoCaptureDevice::Name::QTKIT);
108 device_names->push_back(name);
109 }
110 } 145 }
111 } 146 }
112 147
148 void VideoCaptureDeviceFactoryMac::EnumerateDeviceNames(const base::Callback<
149 void(scoped_ptr<media::VideoCaptureDevice::Names>)>& callback) {
150 DCHECK(thread_checker_.CalledOnValidThread());
151 if (AVFoundationGlue::IsAVFoundationSupported()) {
152 scoped_ptr<VideoCaptureDevice::Names> device_names(
153 new VideoCaptureDevice::Names());
154 GetDeviceNames(device_names.get());
155 callback.Run(device_names.Pass());
156 } else {
157 DVLOG(1) << "Enumerating video capture devices using QTKit";
158 base::PostTaskAndReplyWithResult(ui_task_runner_, FROM_HERE,
159 base::Bind(&EnumerateDevicesUsingQTKit),
160 base::Bind(&RunDevicesEnumeratedCallback, callback));
161 }
162 }
163
113 void VideoCaptureDeviceFactoryMac::GetDeviceSupportedFormats( 164 void VideoCaptureDeviceFactoryMac::GetDeviceSupportedFormats(
114 const VideoCaptureDevice::Name& device, 165 const VideoCaptureDevice::Name& device,
115 VideoCaptureFormats* supported_formats) { 166 VideoCaptureFormats* supported_formats) {
116 DCHECK(thread_checker_.CalledOnValidThread()); 167 DCHECK(thread_checker_.CalledOnValidThread());
117 if (device.capture_api_type() == VideoCaptureDevice::Name::AVFOUNDATION) { 168 if (device.capture_api_type() == VideoCaptureDevice::Name::AVFOUNDATION) {
118 DVLOG(1) << "Enumerating video capture capabilities, AVFoundation"; 169 DVLOG(1) << "Enumerating video capture capabilities, AVFoundation";
119 [VideoCaptureDeviceAVFoundation getDevice:device 170 [VideoCaptureDeviceAVFoundation getDevice:device
120 supportedFormats:supported_formats]; 171 supportedFormats:supported_formats];
121 } else { 172 } else {
122 NOTIMPLEMENTED(); 173 NOTIMPLEMENTED();
123 } 174 }
124 } 175 }
125 176
126 } // namespace media 177 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698