// // ObjectStore.mm // obs-mac-virtualcam // // Created by John Boiles on 4/10/20. // // obs-mac-virtualcam is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // obs-mac-virtualcam is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with obs-mac-virtualcam. If not, see . #import "OBSDALObjectStore.h" @interface OBSDALObjectStore () @property NSMutableDictionary *objectMap; @end @implementation OBSDALObjectStore // 4-byte selectors to string for easy debugging + (NSString *)StringFromPropertySelector:(CMIOObjectPropertySelector)selector { switch (selector) { case kCMIODevicePropertyPlugIn: return @"kCMIODevicePropertyPlugIn"; case kCMIODevicePropertyDeviceUID: return @"kCMIODevicePropertyDeviceUID"; case kCMIODevicePropertyModelUID: return @"kCMIODevicePropertyModelUID"; case kCMIODevicePropertyTransportType: return @"kCMIODevicePropertyTransportType"; case kCMIODevicePropertyDeviceIsAlive: return @"kCMIODevicePropertyDeviceIsAlive"; case kCMIODevicePropertyDeviceHasChanged: return @"kCMIODevicePropertyDeviceHasChanged"; case kCMIODevicePropertyDeviceIsRunning: return @"kCMIODevicePropertyDeviceIsRunning"; case kCMIODevicePropertyDeviceIsRunningSomewhere: return @"kCMIODevicePropertyDeviceIsRunningSomewhere"; case kCMIODevicePropertyDeviceCanBeDefaultDevice: return @"kCMIODevicePropertyDeviceCanBeDefaultDevice"; case kCMIODevicePropertyHogMode: return @"kCMIODevicePropertyHogMode"; case kCMIODevicePropertyLatency: return @"kCMIODevicePropertyLatency"; case kCMIODevicePropertyStreams: return @"kCMIODevicePropertyStreams"; case kCMIODevicePropertyStreamConfiguration: return @"kCMIODevicePropertyStreamConfiguration"; case kCMIODevicePropertyDeviceMaster: return @"kCMIODevicePropertyDeviceMaster"; case kCMIODevicePropertyExcludeNonDALAccess: return @"kCMIODevicePropertyExcludeNonDALAccess"; case kCMIODevicePropertyClientSyncDiscontinuity: return @"kCMIODevicePropertyClientSyncDiscontinuity"; case kCMIODevicePropertySMPTETimeCallback: return @"kCMIODevicePropertySMPTETimeCallback"; case kCMIODevicePropertyCanProcessAVCCommand: return @"kCMIODevicePropertyCanProcessAVCCommand"; case kCMIODevicePropertyAVCDeviceType: return @"kCMIODevicePropertyAVCDeviceType"; case kCMIODevicePropertyAVCDeviceSignalMode: return @"kCMIODevicePropertyAVCDeviceSignalMode"; case kCMIODevicePropertyCanProcessRS422Command: return @"kCMIODevicePropertyCanProcessRS422Command"; case kCMIODevicePropertyLinkedCoreAudioDeviceUID: return @"kCMIODevicePropertyLinkedCoreAudioDeviceUID"; case kCMIODevicePropertyVideoDigitizerComponents: return @"kCMIODevicePropertyVideoDigitizerComponents"; case kCMIODevicePropertySuspendedByUser: return @"kCMIODevicePropertySuspendedByUser"; case kCMIODevicePropertyLinkedAndSyncedCoreAudioDeviceUID: return @"kCMIODevicePropertyLinkedAndSyncedCoreAudioDeviceUID"; case kCMIODevicePropertyIIDCInitialUnitSpace: return @"kCMIODevicePropertyIIDCInitialUnitSpace"; case kCMIODevicePropertyIIDCCSRData: return @"kCMIODevicePropertyIIDCCSRData"; case kCMIODevicePropertyCanSwitchFrameRatesWithoutFrameDrops: return @"kCMIODevicePropertyCanSwitchFrameRatesWithoutFrameDrops"; case kCMIODevicePropertyLocation: return @"kCMIODevicePropertyLocation"; case kCMIODevicePropertyDeviceHasStreamingError: return @"kCMIODevicePropertyDeviceHasStreamingError"; case kCMIODevicePropertyScopeInput: return @"kCMIODevicePropertyScopeInput"; case kCMIODevicePropertyScopeOutput: return @"kCMIODevicePropertyScopeOutput"; case kCMIODevicePropertyScopePlayThrough: return @"kCMIODevicePropertyScopePlayThrough"; case kCMIOObjectPropertyClass: return @"kCMIOObjectPropertyClass"; case kCMIOObjectPropertyOwner: return @"kCMIOObjectPropertyOwner"; case kCMIOObjectPropertyCreator: return @"kCMIOObjectPropertyCreator"; case kCMIOObjectPropertyName: return @"kCMIOObjectPropertyName"; case kCMIOObjectPropertyManufacturer: return @"kCMIOObjectPropertyManufacturer"; case kCMIOObjectPropertyElementName: return @"kCMIOObjectPropertyElementName"; case kCMIOObjectPropertyElementCategoryName: return @"kCMIOObjectPropertyElementCategoryName"; case kCMIOObjectPropertyElementNumberName: return @"kCMIOObjectPropertyElementNumberName"; case kCMIOObjectPropertyOwnedObjects: return @"kCMIOObjectPropertyOwnedObjects"; case kCMIOObjectPropertyListenerAdded: return @"kCMIOObjectPropertyListenerAdded"; case kCMIOObjectPropertyListenerRemoved: return @"kCMIOObjectPropertyListenerRemoved"; case kCMIOStreamPropertyDirection: return @"kCMIOStreamPropertyDirection"; case kCMIOStreamPropertyTerminalType: return @"kCMIOStreamPropertyTerminalType"; case kCMIOStreamPropertyStartingChannel: return @"kCMIOStreamPropertyStartingChannel"; // Same value as kCMIODevicePropertyLatency // case kCMIOStreamPropertyLatency: // return @"kCMIOStreamPropertyLatency"; case kCMIOStreamPropertyFormatDescription: return @"kCMIOStreamPropertyFormatDescription"; case kCMIOStreamPropertyFormatDescriptions: return @"kCMIOStreamPropertyFormatDescriptions"; case kCMIOStreamPropertyStillImage: return @"kCMIOStreamPropertyStillImage"; case kCMIOStreamPropertyStillImageFormatDescriptions: return @"kCMIOStreamPropertyStillImageFormatDescriptions"; case kCMIOStreamPropertyFrameRate: return @"kCMIOStreamPropertyFrameRate"; case kCMIOStreamPropertyMinimumFrameRate: return @"kCMIOStreamPropertyMinimumFrameRate"; case kCMIOStreamPropertyFrameRates: return @"kCMIOStreamPropertyFrameRates"; case kCMIOStreamPropertyFrameRateRanges: return @"kCMIOStreamPropertyFrameRateRanges"; case kCMIOStreamPropertyNoDataTimeoutInMSec: return @"kCMIOStreamPropertyNoDataTimeoutInMSec"; case kCMIOStreamPropertyDeviceSyncTimeoutInMSec: return @"kCMIOStreamPropertyDeviceSyncTimeoutInMSec"; case kCMIOStreamPropertyNoDataEventCount: return @"kCMIOStreamPropertyNoDataEventCount"; case kCMIOStreamPropertyOutputBufferUnderrunCount: return @"kCMIOStreamPropertyOutputBufferUnderrunCount"; case kCMIOStreamPropertyOutputBufferRepeatCount: return @"kCMIOStreamPropertyOutputBufferRepeatCount"; case kCMIOStreamPropertyOutputBufferQueueSize: return @"kCMIOStreamPropertyOutputBufferQueueSize"; case kCMIOStreamPropertyOutputBuffersRequiredForStartup: return @"kCMIOStreamPropertyOutputBuffersRequiredForStartup"; case kCMIOStreamPropertyOutputBuffersNeededForThrottledPlayback: return @"kCMIOStreamPropertyOutputBuffersNeededForThrottledPlayback"; case kCMIOStreamPropertyFirstOutputPresentationTimeStamp: return @"kCMIOStreamPropertyFirstOutputPresentationTimeStamp"; case kCMIOStreamPropertyEndOfData: return @"kCMIOStreamPropertyEndOfData"; case kCMIOStreamPropertyClock: return @"kCMIOStreamPropertyClock"; case kCMIOStreamPropertyCanProcessDeckCommand: return @"kCMIOStreamPropertyCanProcessDeckCommand"; case kCMIOStreamPropertyDeck: return @"kCMIOStreamPropertyDeck"; case kCMIOStreamPropertyDeckFrameNumber: return @"kCMIOStreamPropertyDeckFrameNumber"; case kCMIOStreamPropertyDeckDropness: return @"kCMIOStreamPropertyDeckDropness"; case kCMIOStreamPropertyDeckThreaded: return @"kCMIOStreamPropertyDeckThreaded"; case kCMIOStreamPropertyDeckLocal: return @"kCMIOStreamPropertyDeckLocal"; case kCMIOStreamPropertyDeckCueing: return @"kCMIOStreamPropertyDeckCueing"; case kCMIOStreamPropertyInitialPresentationTimeStampForLinkedAndSyncedAudio: return @"kCMIOStreamPropertyInitialPresentationTimeStampForLinkedAndSyncedAudio"; case kCMIOStreamPropertyScheduledOutputNotificationProc: return @"kCMIOStreamPropertyScheduledOutputNotificationProc"; case kCMIOStreamPropertyPreferredFormatDescription: return @"kCMIOStreamPropertyPreferredFormatDescription"; case kCMIOStreamPropertyPreferredFrameRate: return @"kCMIOStreamPropertyPreferredFrameRate"; case kCMIOControlPropertyScope: return @"kCMIOControlPropertyScope"; case kCMIOControlPropertyElement: return @"kCMIOControlPropertyElement"; case kCMIOControlPropertyVariant: return @"kCMIOControlPropertyVariant"; case kCMIOHardwarePropertyProcessIsMaster: return @"kCMIOHardwarePropertyProcessIsMaster"; case kCMIOHardwarePropertyIsInitingOrExiting: return @"kCMIOHardwarePropertyIsInitingOrExiting"; case kCMIOHardwarePropertyDevices: return @"kCMIOHardwarePropertyDevices"; case kCMIOHardwarePropertyDefaultInputDevice: return @"kCMIOHardwarePropertyDefaultInputDevice"; case kCMIOHardwarePropertyDefaultOutputDevice: return @"kCMIOHardwarePropertyDefaultOutputDevice"; case kCMIOHardwarePropertyDeviceForUID: return @"kCMIOHardwarePropertyDeviceForUID"; case kCMIOHardwarePropertySleepingIsAllowed: return @"kCMIOHardwarePropertySleepingIsAllowed"; case kCMIOHardwarePropertyUnloadingIsAllowed: return @"kCMIOHardwarePropertyUnloadingIsAllowed"; case kCMIOHardwarePropertyPlugInForBundleID: return @"kCMIOHardwarePropertyPlugInForBundleID"; case kCMIOHardwarePropertyUserSessionIsActiveOrHeadless: return @"kCMIOHardwarePropertyUserSessionIsActiveOrHeadless"; case kCMIOHardwarePropertySuspendedBySystem: return @"kCMIOHardwarePropertySuspendedBySystem"; case kCMIOHardwarePropertyAllowScreenCaptureDevices: return @"kCMIOHardwarePropertyAllowScreenCaptureDevices"; case kCMIOHardwarePropertyAllowWirelessScreenCaptureDevices: return @"kCMIOHardwarePropertyAllowWirelessScreenCaptureDevices"; default: uint8_t *chars = (uint8_t *) &selector; return [NSString stringWithFormat:@"Unknown selector: %c%c%c%c", chars[0], chars[1], chars[2], chars[3]]; } } + (BOOL)IsBridgedTypeForSelector:(CMIOObjectPropertySelector)selector { switch (selector) { case kCMIOObjectPropertyName: case kCMIOObjectPropertyManufacturer: case kCMIOObjectPropertyElementName: case kCMIOObjectPropertyElementCategoryName: case kCMIOObjectPropertyElementNumberName: case kCMIODevicePropertyDeviceUID: case kCMIODevicePropertyModelUID: case kCMIOStreamPropertyFormatDescriptions: case kCMIOStreamPropertyFormatDescription: case kCMIOStreamPropertyClock: return YES; default: return NO; } } + (OBSDALObjectStore *)SharedObjectStore { static OBSDALObjectStore *sObjectStore = nil; static dispatch_once_t sOnceToken; dispatch_once(&sOnceToken, ^{ sObjectStore = [[self alloc] init]; }); return sObjectStore; } + (NSObject *)GetObjectWithId:(CMIOObjectID)objectId { return [[OBSDALObjectStore SharedObjectStore] getObject:objectId]; } - (id)init { if (self = [super init]) { self.objectMap = [[NSMutableDictionary alloc] init]; } return self; } - (NSObject *)getObject:(CMIOObjectID)objectID { return self.objectMap[@(objectID)]; } - (void)setObject:(id)object forObjectId:(CMIOObjectID)objectId { self.objectMap[@(objectId)] = object; } @end