objective-ccmacosavfoundationiokit

USB interface of an AVCaptureDevice


If I have an AVCaptureDevice, how can I get the related USB interface so I can access the underlying hardware via IOKit?

I've tried finding it via vid & pid, but this won't work if I plug in two devices with the same vid, pid. Here's the code I use to extract vid and pid from AVCaptureDevice:

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithDeviceType:AVMediaTypeVideo];
NSString *modelID = [device modelID];

NSRange vidRange = [modelID rangeOfString:@"VendorID_"];
int vid = [[modelID substringWithRange:NSMakeRange(vidRange.location + 9, 5)] intValue];

NSRange pidRange = [modelID rangeOfString:@"ProductID_"];
int vid = [[modelID substringWithRange:NSMakeRange(pidRange.location + 10, 5)] intValue];

And then I search for a matching IOService:

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
CFNumberRef numberRef;

numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vid);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef);

numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pid);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef);

io_service_t camera = IOServiceGetMatchingService(kIOMasterPortDefault, matchingDict);

Solution

  • Maybe a combination of AVCaptureDevice modelID and uniqueID could help you find the matching IOService. The formatting of the two IDs looks to be both undocumented and dependent on transport and media-type, but you should be able to figure something out. Here is a tentative mapping for USB audio (because I don't have any USB cameras), based on two devices:

    modelID: USB Headphone Set:0C76:1607
    uniqueID: AppleUSBAudioEngine:Unknown Manufacturer:USB Headphone Set:14200000:2,1,
        USB Headphone Set:
    
        Product ID: 0x1607
        Vendor ID:  0x0c76  (Solid State System Co., Ltd.)
    Version:    1.00
    Speed:  Up to 12 Mb/sec
        Location ID:    0x14200000 / 9
        Current Available (mA): 1000
        Current Required (mA):  100
        Extra Operating Current (mA):   0
    
    
    uniqueID: AppleUSBAudioEngine:Burr-Brown from TI              :USB Audio CODEC :14200000:2,
    modelID: USB Audio CODEC :08BB:2902
        USB Audio CODEC :
    
        Product ID: 0x2902
        Vendor ID:  0x08bb  (Texas Instruments Japan)
    Version:    1.00
    Speed:  Up to 12 Mb/sec
    Manufacturer:   Burr-Brown from TI
        Location ID:    0x14200000 / 10
        Current Available (mA): 1000
        Current Required (mA):  100
        Extra Operating Current (mA):   0
    

    The (usb audio) format is something like

    modelID: name:vendorID:productID
    uniqueID: AppleUSBAudioEngine:Manufacturer or Unknown Manufacturer:location ID:???
    

    If USB video's uniqueID is similar, then the combination of productID, vendorID and locationID (which USB port) should be enough to uniquely identify the underlying device's hardware, albeit in a fragile and undocumented way.