1 /* -LICENSE-START- 2 ** Copyright (c) 2009 Blackmagic Design 3 ** 4 ** Permission is hereby granted, free of charge, to any person or organization 5 ** obtaining a copy of the software and accompanying documentation covered by 6 ** this license (the "Software") to use, reproduce, display, distribute, 7 ** execute, and transmit the Software, and to prepare derivative works of the 8 ** Software, and to permit third-parties to whom the Software is furnished to 9 ** do so, all subject to the following: 10 ** 11 ** The copyright notices in the Software and this entire statement, including 12 ** the above license grant, this restriction and the following disclaimer, 13 ** must be included in all copies of the Software, in whole or in part, and 14 ** all derivative works of the Software, unless such copies or derivative 15 ** works are solely in the form of machine-executable object code generated by 16 ** a source language processor. 17 ** 18 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 ** DEALINGS IN THE SOFTWARE. 25 ** -LICENSE-END- 26 */ 27 /* DeckLinkAPIDispatch.cpp */ 28 29 #include "DeckLinkAPI.h" 30 #include <pthread.h> 31 32 #if BLACKMAGIC_DECKLINK_API_MAGIC != 1 33 #error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h 34 #endif 35 36 #define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" 37 38 39 typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); 40 typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); 41 typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); 42 typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); 43 typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); 44 typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); 45 46 static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; 47 static CFBundleRef gDeckLinkAPIBundleRef = NULL; 48 static CreateIteratorFunc gCreateIteratorFunc = NULL; 49 static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; 50 static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; 51 static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; 52 static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; 53 static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc= NULL; 54 55 56 void InitDeckLinkAPI (void) 57 { 58 CFURLRef bundleURL; 59 60 bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); 61 if (bundleURL != NULL) 62 { 63 gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); 64 if (gDeckLinkAPIBundleRef != NULL) 65 { 66 gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0002")); 67 gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); 68 gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); 69 gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); 70 gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); 71 gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0001")); 72 } 73 CFRelease(bundleURL); 74 } 75 } 76 77 bool IsDeckLinkAPIPresent (void) 78 { 79 // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller 80 if (gDeckLinkAPIBundleRef != NULL) 81 return true; 82 83 return false; 84 } 85 86 IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) 87 { 88 pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); 89 90 if (gCreateIteratorFunc == NULL) 91 return NULL; 92 93 return gCreateIteratorFunc(); 94 } 95 96 IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) 97 { 98 pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); 99 100 if (gCreateAPIInformationFunc == NULL) 101 return NULL; 102 103 return gCreateAPIInformationFunc(); 104 } 105 106 IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) 107 { 108 pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); 109 110 if (gCreateOpenGLPreviewFunc == NULL) 111 return NULL; 112 113 return gCreateOpenGLPreviewFunc(); 114 } 115 116 IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* parentView) 117 { 118 pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); 119 120 if (gCreateCocoaPreviewFunc == NULL) 121 return NULL; 122 123 return gCreateCocoaPreviewFunc(parentView); 124 } 125 126 IDeckLinkVideoConversion* CreateVideoConversionInstance (void) 127 { 128 pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); 129 130 if (gCreateVideoConversionFunc == NULL) 131 return NULL; 132 133 return gCreateVideoConversionFunc(); 134 } 135 136 IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void) 137 { 138 pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); 139 140 if (gCreateDeckLinkDiscoveryFunc == NULL) 141 return NULL; 142 143 return gCreateDeckLinkDiscoveryFunc(); 144 } 145 146 147 #define kBMDStreamingAPI_BundlePath "/Library/Application Support/Blackmagic Design/Streaming/BMDStreamingAPI.bundle" 148 149 typedef IBMDStreamingDiscovery* (*CreateDiscoveryFunc)(void); 150 typedef IBMDStreamingH264NALParser* (*CreateNALParserFunc)(void); 151 152 static pthread_once_t gBMDStreamingOnceControl = PTHREAD_ONCE_INIT; 153 static CFBundleRef gBMDStreamingAPIBundleRef = NULL; 154 static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL; 155 static CreateNALParserFunc gCreateNALParserFunc = NULL; 156 157 void InitBMDStreamingAPI(void) 158 { 159 CFURLRef bundleURL; 160 161 bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kBMDStreamingAPI_BundlePath), kCFURLPOSIXPathStyle, true); 162 if (bundleURL != NULL) 163 { 164 gBMDStreamingAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); 165 if (gBMDStreamingAPIBundleRef != NULL) 166 { 167 gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0001")); 168 gCreateNALParserFunc = (CreateNALParserFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingH264NALParser_0001")); 169 } 170 171 CFRelease(bundleURL); 172 } 173 } 174 175 IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance() 176 { 177 pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); 178 179 if (gCreateDiscoveryFunc == NULL) 180 return NULL; 181 182 return gCreateDiscoveryFunc(); 183 } 184 185 IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser() 186 { 187 pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); 188 189 if (gCreateNALParserFunc == NULL) 190 return NULL; 191 192 return gCreateNALParserFunc(); 193 } 194