Commit 79bde7a0 authored by mcasas@chromium.org's avatar mcasas@chromium.org

Mac VideoCapture: return empty GetModel() for non-USB non-built-in cameras.

This CL adds support for storage of the camera connection
information in the devices' names enumeration and subsequently
in the VideoCaptureDevice::Name structure.

-[AVCaptureDevice transportType] indicates the connection type 
to the camera: USB, Built-in, PCI, etc. Note that this info is only 
available for AVFoundation API and not for QTKit. 

Chromium style check forces to move complex constructors
and destructors from video_capture_device.h to .cc.

TEST: Verify that the FaceTime Built-in HD (USB) used in 
MBA >=2013 does not show incorrect modelID and vendorID
in the camera name -- those fields should be empty since
they only exist for USB or built-in cameras..

BUG=336651

Review URL: https://codereview.chromium.org/366593003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282063 0039d316-1c4b-4281-b951-d872f2087c98
parent 74791a73
...@@ -29,8 +29,14 @@ void FakeVideoCaptureDeviceFactory::GetDeviceNames( ...@@ -29,8 +29,14 @@ void FakeVideoCaptureDeviceFactory::GetDeviceNames(
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(device_names->empty()); DCHECK(device_names->empty());
for (int n = 0; n < number_of_devices_; ++n) { for (int n = 0; n < number_of_devices_; ++n) {
#if !defined(OS_MACOSX)
VideoCaptureDevice::Name name(base::StringPrintf("fake_device_%d", n), VideoCaptureDevice::Name name(base::StringPrintf("fake_device_%d", n),
base::StringPrintf("/dev/video%d", n)); base::StringPrintf("/dev/video%d", n));
#else
VideoCaptureDevice::Name name(base::StringPrintf("fake_device_%d", n),
base::StringPrintf("/dev/video%d", n),
VideoCaptureDevice::Name::AVFOUNDATION);
#endif
device_names->push_back(name); device_names->push_back(name);
} }
} }
......
...@@ -45,6 +45,11 @@ void FileVideoCaptureDeviceFactory::GetDeviceNames( ...@@ -45,6 +45,11 @@ void FileVideoCaptureDeviceFactory::GetDeviceNames(
device_names->push_back(VideoCaptureDevice::Name( device_names->push_back(VideoCaptureDevice::Name(
base::SysWideToUTF8(command_line_file_path.value()), base::SysWideToUTF8(command_line_file_path.value()),
kFileVideoCaptureDeviceName)); kFileVideoCaptureDeviceName));
#elif defined(OS_MACOSX)
device_names->push_back(VideoCaptureDevice::Name(
command_line_file_path.value(),
kFileVideoCaptureDeviceName,
VideoCaptureDevice::Name::AVFOUNDATION));
#else #else
device_names->push_back(VideoCaptureDevice::Name( device_names->push_back(VideoCaptureDevice::Name(
command_line_file_path.value(), command_line_file_path.value(),
......
...@@ -62,6 +62,7 @@ MEDIA_EXPORT ...@@ -62,6 +62,7 @@ MEDIA_EXPORT
- (NSString*)localizedName; - (NSString*)localizedName;
- (BOOL)isSuspended; - (BOOL)isSuspended;
- (NSArray*)formats; - (NSArray*)formats;
- (int32_t)transportType;
@end @end
......
...@@ -23,7 +23,11 @@ ...@@ -23,7 +23,11 @@
if (([device hasMediaType:AVFoundationGlue::AVMediaTypeVideo()] || if (([device hasMediaType:AVFoundationGlue::AVMediaTypeVideo()] ||
[device hasMediaType:AVFoundationGlue::AVMediaTypeMuxed()]) && [device hasMediaType:AVFoundationGlue::AVMediaTypeMuxed()]) &&
![device isSuspended]) { ![device isSuspended]) {
[deviceNames setObject:[device localizedName] DeviceNameAndTransportType* nameAndTransportType =
[[[DeviceNameAndTransportType alloc]
initWithName:[device localizedName]
transportType:[device transportType]] autorelease];
[deviceNames setObject:nameAndTransportType
forKey:[device uniqueID]]; forKey:[device uniqueID]];
} }
} }
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "media/video/capture/mac/video_capture_device_factory_mac.h" #include "media/video/capture/mac/video_capture_device_factory_mac.h"
#import <IOKit/audio/IOAudioTypes.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/location.h" #include "base/location.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -32,7 +34,7 @@ EnumerateDevicesUsingQTKit() { ...@@ -32,7 +34,7 @@ EnumerateDevicesUsingQTKit() {
[VideoCaptureDeviceQTKit getDeviceNames:capture_devices]; [VideoCaptureDeviceQTKit getDeviceNames:capture_devices];
for (NSString* key in capture_devices) { for (NSString* key in capture_devices) {
VideoCaptureDevice::Name name( VideoCaptureDevice::Name name(
[[capture_devices valueForKey:key] UTF8String], [[[capture_devices valueForKey:key] deviceName] UTF8String],
[key UTF8String], VideoCaptureDevice::Name::QTKIT); [key UTF8String], VideoCaptureDevice::Name::QTKIT);
device_names->push_back(name); device_names->push_back(name);
} }
...@@ -103,9 +105,17 @@ void VideoCaptureDeviceFactoryMac::GetDeviceNames( ...@@ -103,9 +105,17 @@ void VideoCaptureDeviceFactoryMac::GetDeviceNames(
// Enumerate all devices found by AVFoundation, translate the info for each // Enumerate all devices found by AVFoundation, translate the info for each
// to class Name and add it to |device_names|. // to class Name and add it to |device_names|.
for (NSString* key in capture_devices) { for (NSString* key in capture_devices) {
int transport_type = [[capture_devices valueForKey:key] transportType];
// Transport types are defined for Audio devices and reused for video.
VideoCaptureDevice::Name::TransportType device_transport_type =
(transport_type == kIOAudioDeviceTransportTypeBuiltIn ||
transport_type == kIOAudioDeviceTransportTypeUSB)
? VideoCaptureDevice::Name::USB_OR_BUILT_IN
: VideoCaptureDevice::Name::OTHER_TRANSPORT;
VideoCaptureDevice::Name name( VideoCaptureDevice::Name name(
[[capture_devices valueForKey:key] UTF8String], [[[capture_devices valueForKey:key] deviceName] UTF8String],
[key UTF8String], VideoCaptureDevice::Name::AVFOUNDATION); [key UTF8String], VideoCaptureDevice::Name::AVFOUNDATION,
device_transport_type);
device_names->push_back(name); device_names->push_back(name);
for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) {
is_any_device_blacklisted = EndsWith(name.id(), is_any_device_blacklisted = EndsWith(name.id(),
...@@ -121,7 +131,7 @@ void VideoCaptureDeviceFactoryMac::GetDeviceNames( ...@@ -121,7 +131,7 @@ void VideoCaptureDeviceFactoryMac::GetDeviceNames(
if (is_any_device_blacklisted) { if (is_any_device_blacklisted) {
capture_devices = [VideoCaptureDeviceQTKit deviceNames]; capture_devices = [VideoCaptureDeviceQTKit deviceNames];
for (NSString* key in capture_devices) { for (NSString* key in capture_devices) {
NSString* device_name = [capture_devices valueForKey:key]; NSString* device_name = [[capture_devices valueForKey:key] deviceName];
for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) {
if ([device_name rangeOfString:@(kBlacklistedCameras[i].name) if ([device_name rangeOfString:@(kBlacklistedCameras[i].name)
options:NSCaseInsensitiveSearch].length != 0) { options:NSCaseInsensitiveSearch].length != 0) {
......
...@@ -10,9 +10,12 @@ ...@@ -10,9 +10,12 @@
#ifndef MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ #ifndef MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
#define MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ #define MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
#import <Foundation/Foundation.h>
#include <string> #include <string>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/mac/scoped_nsobject.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "media/video/capture/video_capture_device.h" #include "media/video/capture/video_capture_device.h"
...@@ -24,8 +27,30 @@ namespace base { ...@@ -24,8 +27,30 @@ namespace base {
class SingleThreadTaskRunner; class SingleThreadTaskRunner;
} }
// Small class to bundle device name and connection type into a dictionary.
MEDIA_EXPORT
@interface DeviceNameAndTransportType : NSObject {
@private
base::scoped_nsobject<NSString> deviceName_;
// The transport type of the device (USB, PCI, etc), values are defined in
// <IOKit/audio/IOAudioTypes.h> as kIOAudioDeviceTransportType*.
int32_t transportType_;
}
- (id)initWithName:(NSString*)name transportType:(int32_t)transportType;
- (NSString*)deviceName;
- (int32_t)transportType;
@end
namespace media { namespace media {
enum {
// Unknown transport type, addition to the kIOAudioDeviceTransportType*
// family for QTKit devices where this attribute isn't published.
kIOAudioDeviceTransportTypeUnknown = 'unkn'
};
// Called by VideoCaptureManager to open, close and start, stop Mac video // Called by VideoCaptureManager to open, close and start, stop Mac video
// capture devices. // capture devices.
class VideoCaptureDeviceMac : public VideoCaptureDevice { class VideoCaptureDeviceMac : public VideoCaptureDevice {
......
...@@ -21,6 +21,26 @@ ...@@ -21,6 +21,26 @@
#import "media/video/capture/mac/video_capture_device_avfoundation_mac.h" #import "media/video/capture/mac/video_capture_device_avfoundation_mac.h"
#import "media/video/capture/mac/video_capture_device_qtkit_mac.h" #import "media/video/capture/mac/video_capture_device_qtkit_mac.h"
@implementation DeviceNameAndTransportType
- (id)initWithName:(NSString*)deviceName transportType:(int32_t)transportType {
if (self = [super init]) {
deviceName_.reset([deviceName copy]);
transportType_ = transportType;
}
return self;
}
- (NSString*)deviceName {
return deviceName_;
}
- (int32_t)transportType {
return transportType_;
}
@end // @implementation DeviceNameAndTransportType
namespace media { namespace media {
const int kMinFrameRate = 1; const int kMinFrameRate = 1;
...@@ -307,10 +327,12 @@ static void SetAntiFlickerInUsbDevice(const int vendor_id, ...@@ -307,10 +327,12 @@ static void SetAntiFlickerInUsbDevice(const int vendor_id,
} }
const std::string VideoCaptureDevice::Name::GetModel() const { const std::string VideoCaptureDevice::Name::GetModel() const {
// Skip the AVFoundation's not USB nor built-in devices.
if (capture_api_type() == AVFOUNDATION && transport_type() != USB_OR_BUILT_IN)
return "";
// Both PID and VID are 4 characters. // Both PID and VID are 4 characters.
if (unique_id_.size() < 2 * kVidPidSize) { if (unique_id_.size() < 2 * kVidPidSize)
return ""; return "";
}
// The last characters of device id is a concatenation of VID and then PID. // The last characters of device id is a concatenation of VID and then PID.
const size_t vid_location = unique_id_.size() - 2 * kVidPidSize; const size_t vid_location = unique_id_.size() - 2 * kVidPidSize;
......
...@@ -29,9 +29,15 @@ ...@@ -29,9 +29,15 @@
}); });
for (QTCaptureDevice* device in captureDevices) { for (QTCaptureDevice* device in captureDevices) {
if (![[device attributeForKey:QTCaptureDeviceSuspendedAttribute] boolValue]) if ([[device attributeForKey:QTCaptureDeviceSuspendedAttribute] boolValue])
[deviceNames setObject:[device localizedDisplayName] continue;
forKey:[device uniqueID]]; DeviceNameAndTransportType* nameAndTransportType =
[[[DeviceNameAndTransportType alloc]
initWithName:[device localizedDisplayName]
transportType:media::kIOAudioDeviceTransportTypeUnknown]
autorelease];
[deviceNames setObject:nameAndTransportType
forKey:[device uniqueID]];
} }
} }
......
...@@ -19,6 +19,39 @@ const std::string VideoCaptureDevice::Name::GetNameAndModel() const { ...@@ -19,6 +19,39 @@ const std::string VideoCaptureDevice::Name::GetNameAndModel() const {
return device_name_ + suffix; return device_name_ + suffix;
} }
VideoCaptureDevice::Name::Name() {}
VideoCaptureDevice::Name::Name(const std::string& name, const std::string& id)
: device_name_(name), unique_id_(id) {}
#if defined(OS_WIN)
VideoCaptureDevice::Name::Name(const std::string& name,
const std::string& id,
const CaptureApiType api_type)
: device_name_(name), unique_id_(id), capture_api_class_(api_type) {}
#endif
#if defined(OS_MACOSX)
VideoCaptureDevice::Name::Name(const std::string& name,
const std::string& id,
const CaptureApiType api_type)
: device_name_(name),
unique_id_(id),
capture_api_class_(api_type),
transport_type_(OTHER_TRANSPORT) {}
VideoCaptureDevice::Name::Name(const std::string& name,
const std::string& id,
const CaptureApiType api_type,
const TransportType transport_type)
: device_name_(name),
unique_id_(id),
capture_api_class_(api_type),
transport_type_(transport_type) {}
#endif
VideoCaptureDevice::Name::~Name() {}
VideoCaptureDevice::~VideoCaptureDevice() {} VideoCaptureDevice::~VideoCaptureDevice() {}
int VideoCaptureDevice::GetPowerLineFrequencyForLocation() const { int VideoCaptureDevice::GetPowerLineFrequencyForLocation() const {
......
...@@ -38,9 +38,8 @@ class MEDIA_EXPORT VideoCaptureDevice { ...@@ -38,9 +38,8 @@ class MEDIA_EXPORT VideoCaptureDevice {
// VideoCaptureDevice::Create. // VideoCaptureDevice::Create.
class MEDIA_EXPORT Name { class MEDIA_EXPORT Name {
public: public:
Name() {} Name();
Name(const std::string& name, const std::string& id) Name(const std::string& name, const std::string& id);
: device_name_(name), unique_id_(id) {}
#if defined(OS_WIN) #if defined(OS_WIN)
// Windows targets Capture Api type: it can only be set on construction. // Windows targets Capture Api type: it can only be set on construction.
...@@ -57,14 +56,24 @@ class MEDIA_EXPORT VideoCaptureDevice { ...@@ -57,14 +56,24 @@ class MEDIA_EXPORT VideoCaptureDevice {
QTKIT, QTKIT,
API_TYPE_UNKNOWN API_TYPE_UNKNOWN
}; };
// For AVFoundation Api, identify devices that are built-in or USB.
enum TransportType {
USB_OR_BUILT_IN,
OTHER_TRANSPORT
};
#endif #endif
#if defined(OS_WIN) || defined(OS_MACOSX) #if defined(OS_WIN) || defined(OS_MACOSX)
Name(const std::string& name, Name(const std::string& name,
const std::string& id, const std::string& id,
const CaptureApiType api_type) const CaptureApiType api_type);
: device_name_(name), unique_id_(id), capture_api_class_(api_type) {} #endif
#if defined(OS_MACOSX)
Name(const std::string& name,
const std::string& id,
const CaptureApiType api_type,
const TransportType transport_type);
#endif #endif
~Name() {} ~Name();
// Friendly name of a device // Friendly name of a device
const std::string& name() const { return device_name_; } const std::string& name() const { return device_name_; }
...@@ -95,6 +104,11 @@ class MEDIA_EXPORT VideoCaptureDevice { ...@@ -95,6 +104,11 @@ class MEDIA_EXPORT VideoCaptureDevice {
CaptureApiType capture_api_type() const { CaptureApiType capture_api_type() const {
return capture_api_class_.capture_api_type(); return capture_api_class_.capture_api_type();
} }
#endif
#if defined(OS_MACOSX)
TransportType transport_type() const {
return transport_type_;
}
#endif // if defined(OS_WIN) #endif // if defined(OS_WIN)
private: private:
...@@ -117,6 +131,9 @@ class MEDIA_EXPORT VideoCaptureDevice { ...@@ -117,6 +131,9 @@ class MEDIA_EXPORT VideoCaptureDevice {
}; };
CaptureApiClass capture_api_class_; CaptureApiClass capture_api_class_;
#endif
#if defined(OS_MACOSX)
TransportType transport_type_;
#endif #endif
// Allow generated copy constructor and assignment. // Allow generated copy constructor and assignment.
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment