mirror of
https://github.com/zakk4223/CocoaSplit.git
synced 2026-05-15 14:15:50 -06:00
Added XPC based helper process to handle 32-bit Quicktime based sources. Should allow lots of capture cards/cams AND Camtwist to work
This commit is contained in:
parent
e391580c21
commit
5f47d464c4
17 changed files with 933 additions and 115 deletions
16
CapturedFrameProtocol.h
Normal file
16
CapturedFrameProtocol.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// CapturedFrameProtocol.h
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 11/10/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol CapturedFrameProtocol
|
||||
|
||||
-(void) newCapturedFrame:(IOSurfaceID)ioxpc reply:(void (^)())reply;
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -38,6 +38,15 @@
|
|||
34792AF316103FF60065A859 /* DesktopCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 34792AF216103FF60065A859 /* DesktopCapture.m */; };
|
||||
34792AF616104AA70065A859 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34792AF516104AA70065A859 /* IOKit.framework */; };
|
||||
34792AFB1611A6B90065A859 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34792AFA1611A6B90065A859 /* IOSurface.framework */; };
|
||||
34AE3C30164E3E020052C95E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AE3C2F164E3E020052C95E /* Foundation.framework */; };
|
||||
34AE3C36164E3E020052C95E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 34AE3C34164E3E020052C95E /* InfoPlist.strings */; };
|
||||
34AE3C39164E3E020052C95E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AE3C38164E3E020052C95E /* main.m */; };
|
||||
34AE3C3F164E3F230052C95E /* zakk.lol.QTCaptureHelper.xpc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 34AE3C2E164E3E020052C95E /* zakk.lol.QTCaptureHelper.xpc */; };
|
||||
34AE3C44164E410D0052C95E /* XPCListenerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AE3C43164E410D0052C95E /* XPCListenerDelegate.m */; };
|
||||
34AE3C4B164E68820052C95E /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 340FE4E015F3581200E4CE4E /* QTKit.framework */; };
|
||||
34AE3C6B164F04B30052C95E /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AE3C6A164F04B30052C95E /* IOSurface.framework */; };
|
||||
34AE3C6D164F04C90052C95E /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AE3C6C164F04C90052C95E /* CoreVideo.framework */; };
|
||||
34B74BC91648D23B00818DE2 /* QTCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B74BC81648D23B00818DE2 /* QTCapture.m */; };
|
||||
34C6C3BF15FB5B440018A18B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34C6C3BE15FB5B440018A18B /* OpenGL.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
|
|
@ -49,6 +58,13 @@
|
|||
remoteGlobalIDString = 340FE49C15F3417E00E4CE4E;
|
||||
remoteInfo = CocoaSplit;
|
||||
};
|
||||
34AE3C40164E3FAD0052C95E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 340FE49415F3417E00E4CE4E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 34AE3C2D164E3E020052C95E;
|
||||
remoteInfo = QTCaptureHelper;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
|
|
@ -62,6 +78,16 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
34AE3C3E164E3EAE0052C95E /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = Contents/XPCServices;
|
||||
dstSubfolderSpec = 1;
|
||||
files = (
|
||||
34AE3C3F164E3F230052C95E /* zakk.lol.QTCaptureHelper.xpc in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
|
@ -112,6 +138,20 @@
|
|||
34792AF216103FF60065A859 /* DesktopCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DesktopCapture.m; sourceTree = "<group>"; };
|
||||
34792AF516104AA70065A859 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
34792AFA1611A6B90065A859 /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; };
|
||||
34AE3C2E164E3E020052C95E /* zakk.lol.QTCaptureHelper.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = zakk.lol.QTCaptureHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
34AE3C2F164E3E020052C95E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
34AE3C33164E3E020052C95E /* QTCaptureHelper-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "QTCaptureHelper-Info.plist"; sourceTree = "<group>"; };
|
||||
34AE3C35164E3E020052C95E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
34AE3C37164E3E020052C95E /* QTCaptureHelper-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "QTCaptureHelper-Prefix.pch"; sourceTree = "<group>"; };
|
||||
34AE3C38164E3E020052C95E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
34AE3C42164E410D0052C95E /* XPCListenerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XPCListenerDelegate.h; sourceTree = "<group>"; };
|
||||
34AE3C43164E410D0052C95E /* XPCListenerDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XPCListenerDelegate.m; sourceTree = "<group>"; };
|
||||
34AE3C46164E560C0052C95E /* QTHelperProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QTHelperProtocol.h; sourceTree = "<group>"; };
|
||||
34AE3C69164F01800052C95E /* CapturedFrameProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CapturedFrameProtocol.h; sourceTree = "<group>"; };
|
||||
34AE3C6A164F04B30052C95E /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = ../../../../System/Library/Frameworks/IOSurface.framework; sourceTree = "<group>"; };
|
||||
34AE3C6C164F04C90052C95E /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = ../../../../System/Library/Frameworks/CoreVideo.framework; sourceTree = "<group>"; };
|
||||
34B74BC71648D23B00818DE2 /* QTCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QTCapture.h; sourceTree = "<group>"; };
|
||||
34B74BC81648D23B00818DE2 /* QTCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QTCapture.m; sourceTree = "<group>"; };
|
||||
34C6C3BE15FB5B440018A18B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
|
@ -145,12 +185,26 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
34AE3C2B164E3E020052C95E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34AE3C6D164F04C90052C95E /* CoreVideo.framework in Frameworks */,
|
||||
34AE3C6B164F04B30052C95E /* IOSurface.framework in Frameworks */,
|
||||
34AE3C4B164E68820052C95E /* QTKit.framework in Frameworks */,
|
||||
34AE3C30164E3E020052C95E /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
340FE49215F3417E00E4CE4E = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
34AE3C6C164F04C90052C95E /* CoreVideo.framework */,
|
||||
34AE3C6A164F04B30052C95E /* IOSurface.framework */,
|
||||
34AE3C45164E53D00052C95E /* XPCShared */,
|
||||
34792AFA1611A6B90065A859 /* IOSurface.framework */,
|
||||
34792AF516104AA70065A859 /* IOKit.framework */,
|
||||
34C6C3BE15FB5B440018A18B /* OpenGL.framework */,
|
||||
|
|
@ -160,6 +214,7 @@
|
|||
340FE4E015F3581200E4CE4E /* QTKit.framework */,
|
||||
340FE4A715F3417E00E4CE4E /* CocoaSplit */,
|
||||
340FE4C415F3417E00E4CE4E /* CocoaSplitTests */,
|
||||
34AE3C31164E3E020052C95E /* QTCaptureHelper */,
|
||||
340FE4A015F3417E00E4CE4E /* Frameworks */,
|
||||
340FE49E15F3417E00E4CE4E /* Products */,
|
||||
);
|
||||
|
|
@ -170,6 +225,7 @@
|
|||
children = (
|
||||
340FE49D15F3417E00E4CE4E /* CocoaSplit.app */,
|
||||
340FE4BE15F3417E00E4CE4E /* CocoaSplitTests.octest */,
|
||||
34AE3C2E164E3E020052C95E /* zakk.lol.QTCaptureHelper.xpc */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -184,6 +240,7 @@
|
|||
340FE4D815F346CC00E4CE4E /* AVFoundation.framework */,
|
||||
340FE4A115F3417E00E4CE4E /* Cocoa.framework */,
|
||||
340FE4BF15F3417E00E4CE4E /* SenTestingKit.framework */,
|
||||
34AE3C2F164E3E020052C95E /* Foundation.framework */,
|
||||
340FE4A315F3417E00E4CE4E /* Other Frameworks */,
|
||||
);
|
||||
name = Frameworks;
|
||||
|
|
@ -212,6 +269,8 @@
|
|||
342346D415FA301600C8C77E /* SyphonCapture.m */,
|
||||
342346CD15F9F07E00C8C77E /* AbstractCaptureDevice.h */,
|
||||
342346CE15F9F07E00C8C77E /* AbstractCaptureDevice.m */,
|
||||
34B74BC71648D23B00818DE2 /* QTCapture.h */,
|
||||
34B74BC81648D23B00818DE2 /* QTCapture.m */,
|
||||
342346CC15F9D52000C8C77E /* CaptureSessionProtocol.h */,
|
||||
342346BC15F6103D00C8C77E /* FFMpegTask.h */,
|
||||
342346BD15F6103D00C8C77E /* FFMpegTask.m */,
|
||||
|
|
@ -258,6 +317,36 @@
|
|||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
34AE3C31164E3E020052C95E /* QTCaptureHelper */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
34AE3C38164E3E020052C95E /* main.m */,
|
||||
34AE3C42164E410D0052C95E /* XPCListenerDelegate.h */,
|
||||
34AE3C43164E410D0052C95E /* XPCListenerDelegate.m */,
|
||||
34AE3C32164E3E020052C95E /* Supporting Files */,
|
||||
);
|
||||
path = QTCaptureHelper;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
34AE3C32164E3E020052C95E /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
34AE3C33164E3E020052C95E /* QTCaptureHelper-Info.plist */,
|
||||
34AE3C34164E3E020052C95E /* InfoPlist.strings */,
|
||||
34AE3C37164E3E020052C95E /* QTCaptureHelper-Prefix.pch */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
34AE3C45164E53D00052C95E /* XPCShared */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
34AE3C46164E560C0052C95E /* QTHelperProtocol.h */,
|
||||
34AE3C69164F01800052C95E /* CapturedFrameProtocol.h */,
|
||||
);
|
||||
name = XPCShared;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
|
@ -269,10 +358,12 @@
|
|||
340FE49A15F3417E00E4CE4E /* Frameworks */,
|
||||
340FE49B15F3417E00E4CE4E /* Resources */,
|
||||
342346DC15FA34B400C8C77E /* CopyFiles */,
|
||||
34AE3C3E164E3EAE0052C95E /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
34AE3C41164E3FAD0052C95E /* PBXTargetDependency */,
|
||||
);
|
||||
name = CocoaSplit;
|
||||
productName = CocoaSplit;
|
||||
|
|
@ -298,6 +389,23 @@
|
|||
productReference = 340FE4BE15F3417E00E4CE4E /* CocoaSplitTests.octest */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
34AE3C2D164E3E020052C95E /* QTCaptureHelper */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 34AE3C3C164E3E020052C95E /* Build configuration list for PBXNativeTarget "QTCaptureHelper" */;
|
||||
buildPhases = (
|
||||
34AE3C2A164E3E020052C95E /* Sources */,
|
||||
34AE3C2B164E3E020052C95E /* Frameworks */,
|
||||
34AE3C2C164E3E020052C95E /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = QTCaptureHelper;
|
||||
productName = QTCaptureHelper;
|
||||
productReference = 34AE3C2E164E3E020052C95E /* zakk.lol.QTCaptureHelper.xpc */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
|
|
@ -321,6 +429,7 @@
|
|||
targets = (
|
||||
340FE49C15F3417E00E4CE4E /* CocoaSplit */,
|
||||
340FE4BD15F3417E00E4CE4E /* CocoaSplitTests */,
|
||||
34AE3C2D164E3E020052C95E /* QTCaptureHelper */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
|
@ -346,6 +455,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
34AE3C2C164E3E020052C95E /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34AE3C36164E3E020052C95E /* InfoPlist.strings in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
|
|
@ -378,6 +495,7 @@
|
|||
342346D515FA301600C8C77E /* SyphonCapture.m in Sources */,
|
||||
34210B3E1606001200362FC8 /* OutputDestination.m in Sources */,
|
||||
34792AF316103FF60065A859 /* DesktopCapture.m in Sources */,
|
||||
34B74BC91648D23B00818DE2 /* QTCapture.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -389,6 +507,15 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
34AE3C2A164E3E020052C95E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34AE3C39164E3E020052C95E /* main.m in Sources */,
|
||||
34AE3C44164E410D0052C95E /* XPCListenerDelegate.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
|
|
@ -397,6 +524,11 @@
|
|||
target = 340FE49C15F3417E00E4CE4E /* CocoaSplit */;
|
||||
targetProxy = 340FE4C215F3417E00E4CE4E /* PBXContainerItemProxy */;
|
||||
};
|
||||
34AE3C41164E3FAD0052C95E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 34AE3C2D164E3E020052C95E /* QTCaptureHelper */;
|
||||
targetProxy = 34AE3C40164E3FAD0052C95E /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
|
|
@ -432,6 +564,14 @@
|
|||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
34AE3C34164E3E020052C95E /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
34AE3C35164E3E020052C95E /* en */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
|
|
@ -555,6 +695,49 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
34AE3C3A164E3E020052C95E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "QTCaptureHelper/QTCaptureHelper-Prefix.pch";
|
||||
INFOPLIST_FILE = "QTCaptureHelper/QTCaptureHelper-Info.plist";
|
||||
MACH_O_TYPE = mh_execute;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "zakk.lol.$(TARGET_NAME:rfc1034identifier)";
|
||||
SDKROOT = "";
|
||||
VALID_ARCHS = "i386 x86_64";
|
||||
WRAPPER_EXTENSION = xpc;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
34AE3C3B164E3E020052C95E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "QTCaptureHelper/QTCaptureHelper-Prefix.pch";
|
||||
INFOPLIST_FILE = "QTCaptureHelper/QTCaptureHelper-Info.plist";
|
||||
MACH_O_TYPE = mh_execute;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
PRODUCT_NAME = "zakk.lol.$(TARGET_NAME:rfc1034identifier)";
|
||||
SDKROOT = "";
|
||||
VALID_ARCHS = "i386 x86_64";
|
||||
WRAPPER_EXTENSION = xpc;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
|
|
@ -585,6 +768,15 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
34AE3C3C164E3E020052C95E /* Build configuration list for PBXNativeTarget "QTCaptureHelper" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
34AE3C3A164E3E020052C95E /* Debug */,
|
||||
34AE3C3B164E3E020052C95E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 340FE49415F3417E00E4CE4E /* Project object */;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
for(devinstance in devices)
|
||||
{
|
||||
|
||||
NSLog(@"Inputs %@", devinstance.linkedDevices);
|
||||
[retArray addObject:[[AbstractCaptureDevice alloc] initWithName:[devinstance localizedName] device:devinstance uniqueID:devinstance.uniqueID]];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <VideoToolbox/VideoToolbox.h>
|
||||
#import "AVFCapture.h"
|
||||
#import "QTCapture.h"
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
#import "FFMpegTask.h"
|
||||
#import "CaptureSessionProtocol.h"
|
||||
|
|
|
|||
|
|
@ -30,12 +30,12 @@
|
|||
self.streamingDestination = nil;
|
||||
|
||||
|
||||
if ([self.selectedDestinationType isEqualToString:@"file"])
|
||||
{
|
||||
//if ([self.selectedDestinationType isEqualToString:@"file"])
|
||||
//{
|
||||
panelName = @"FilePanel";
|
||||
} else {
|
||||
panelName = @"StreamServicePanel";
|
||||
}
|
||||
//} else {
|
||||
// panelName = @"StreamServicePanel";
|
||||
//}
|
||||
|
||||
[NSBundle loadNibNamed:panelName owner:self];
|
||||
}
|
||||
|
|
@ -106,6 +106,8 @@
|
|||
_video_capture_session = [[DesktopCapture alloc ] init];
|
||||
} else if ([selectedVideoType isEqualToString:@"AVFoundation"]) {
|
||||
_video_capture_session = [[AVFCapture alloc] init];
|
||||
} else if ([selectedVideoType isEqualToString:@"QTCapture"]) {
|
||||
_video_capture_session = [[QTCapture alloc] init];
|
||||
} else {
|
||||
_video_capture_session = nil;
|
||||
}
|
||||
|
|
@ -150,8 +152,9 @@
|
|||
@"rtmp" : @"RTMP Stream"};
|
||||
|
||||
|
||||
self.videoTypes = @[@"Desktop", @"AVFoundation"];
|
||||
self.videoTypes = @[@"Desktop", @"AVFoundation", @"QTCapture"];
|
||||
self.selectedVideoType = [self.videoTypes objectAtIndex:0];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
|
|||
|
|
@ -150,8 +150,12 @@ void getAudioExtradata(char *cookie, char **buffer, size_t *size)
|
|||
AVOutputFormat *av_out_fmt;
|
||||
|
||||
|
||||
if (_stream_format) {
|
||||
avformat_alloc_output_context2(&_av_fmt_ctx, NULL, [_stream_format UTF8String], [_stream_output UTF8String]);
|
||||
} else {
|
||||
avformat_alloc_output_context2(&_av_fmt_ctx, NULL, NULL, [_stream_output UTF8String]);
|
||||
}
|
||||
|
||||
avformat_alloc_output_context2(&_av_fmt_ctx, NULL, [_stream_format UTF8String], [_stream_output UTF8String]);
|
||||
if (!_av_fmt_ctx)
|
||||
{
|
||||
NSLog(@"No av_fmt_ctx");
|
||||
|
|
@ -171,7 +175,6 @@ void getAudioExtradata(char *cookie, char **buffer, size_t *size)
|
|||
|
||||
AVCodecContext *c_ctx = _av_video_stream->codec;
|
||||
|
||||
|
||||
c_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
c_ctx->codec_id = AV_CODEC_ID_H264;
|
||||
c_ctx->width = _width;
|
||||
|
|
@ -198,6 +201,7 @@ void getAudioExtradata(char *cookie, char **buffer, size_t *size)
|
|||
a_ctx->channels = 2;
|
||||
a_ctx->extradata = (unsigned char *)_audio_extradata;
|
||||
a_ctx->extradata_size = (int)_audio_extradata_size;
|
||||
a_ctx->frame_size = (_samplerate * 2 * 2) / _framerate;
|
||||
|
||||
|
||||
CMFormatDescriptionRef fmt;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
if (_destination)
|
||||
return _destination;
|
||||
|
||||
|
||||
if ([_type_name isEqualToString:@"rtmp"])
|
||||
{
|
||||
_destination = [NSString stringWithFormat:@"%@/%@", self.server_name, self.stream_key];
|
||||
|
|
@ -66,6 +67,10 @@
|
|||
{
|
||||
|
||||
NSLog(@"Destination set to %@", destination);
|
||||
if ([destination hasPrefix:@"rtmp://"])
|
||||
{
|
||||
self.output_format = @"FLV";
|
||||
}
|
||||
_destination = destination;
|
||||
|
||||
}
|
||||
|
|
@ -74,13 +79,8 @@
|
|||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
self.output_format = @"FLV";
|
||||
//self.output_format = @"FLV";
|
||||
self.type_name = type;
|
||||
if ([type isEqualToString:@"twitchtv"])
|
||||
{
|
||||
self.output_format = @"FLV";
|
||||
self.name = @"Twitch.TV";
|
||||
}
|
||||
|
||||
}
|
||||
return self;
|
||||
|
|
|
|||
36
CocoaSplit/QTCapture.h
Normal file
36
CocoaSplit/QTCapture.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// QTCapture.h
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 11/6/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <VideoToolbox/VideoToolbox.h>
|
||||
#import <QTKit/QTKit.h>
|
||||
#import "CaptureSessionProtocol.h"
|
||||
#import "CapturedFrameProtocol.h"
|
||||
#import "QTHelperProtocol.h"
|
||||
|
||||
@interface QTCapture : NSObject <CaptureSessionProtocol, CapturedFrameProtocol>
|
||||
{
|
||||
NSXPCConnection *_xpcConnection;
|
||||
id <QTHelperProtocol> _xpcProxy;
|
||||
IOSurfaceRef _currentFrame;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@property (strong) id videoInputDevice;
|
||||
@property (strong) id videoDelegate;
|
||||
@property (assign) int videoCaptureFPS;
|
||||
|
||||
|
||||
-(bool) startCaptureSession:(NSError **)error;
|
||||
-(bool) stopCaptureSession;
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
||||
330
CocoaSplit/QTCapture.m
Normal file
330
CocoaSplit/QTCapture.m
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
//
|
||||
// QTCapture.m
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 11/6/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "QTCapture.h"
|
||||
#import "AbstractCaptureDevice.h"
|
||||
#import "QTHelperProtocol.h"
|
||||
#import "CapturedFrameProtocol.h"
|
||||
|
||||
@implementation QTCapture
|
||||
|
||||
|
||||
-(id) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
NSXPCInterface *xpcInterface = [NSXPCInterface interfaceWithProtocol:@protocol(QTHelperProtocol)];
|
||||
NSXPCInterface *xpcCallbackInterface = [NSXPCInterface interfaceWithProtocol:@protocol(CapturedFrameProtocol)];
|
||||
|
||||
_xpcConnection = [[NSXPCConnection alloc] initWithServiceName:@"zakk.lol.QTCaptureHelper"];
|
||||
|
||||
[_xpcConnection setRemoteObjectInterface:xpcInterface];
|
||||
[_xpcConnection setExportedInterface:xpcCallbackInterface];
|
||||
[_xpcConnection setExportedObject:self];
|
||||
|
||||
NSLog(@"SETUP CONNECTION TO LISTENER");
|
||||
[_xpcConnection resume];
|
||||
_xpcProxy = [_xpcConnection remoteObjectProxy];
|
||||
NSLog(@"GOT PROXY OBJECT");
|
||||
|
||||
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void) setVideoDimensions:(int)width height:(int)height
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
-(bool) providesVideo
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(bool) providesAudio
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-(bool) setActiveVideoDevice:(AbstractCaptureDevice *)newDev
|
||||
{
|
||||
NSLog(@"SET VIDEO DEVICE TO %@", [newDev uniqueID]);
|
||||
_videoInputDevice = [newDev uniqueID];
|
||||
return YES;
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(NSArray *) availableVideoDevices
|
||||
{
|
||||
|
||||
dispatch_semaphore_t reply_s = dispatch_semaphore_create(0);
|
||||
|
||||
NSMutableArray *__block retArray;
|
||||
NSLog(@"PROXY %@", _xpcProxy);
|
||||
NSLog(@"CONNECTION %@", _xpcConnection);
|
||||
[_xpcProxy testMethod];
|
||||
NSLog(@"CALLED TEST METHOD FROM SPLIT");
|
||||
|
||||
[_xpcProxy listCaptureDevices:^(NSArray *r_devices) {
|
||||
NSLog(@"REMOTE DEVICES %@", r_devices);
|
||||
retArray = [[NSMutableArray alloc] init];
|
||||
NSDictionary *devinstance;
|
||||
for (devinstance in r_devices)
|
||||
{
|
||||
[retArray addObject:[[AbstractCaptureDevice alloc] initWithName:[devinstance valueForKey:@"name"] device:[devinstance valueForKey:@"id"] uniqueID:[devinstance valueForKey:@"id"]]];
|
||||
}
|
||||
dispatch_semaphore_signal(reply_s);
|
||||
}];
|
||||
NSLog(@"SEMAPHORE WAIT");
|
||||
dispatch_semaphore_wait(reply_s, DISPATCH_TIME_FOREVER);
|
||||
reply_s = nil;
|
||||
return (NSArray *)retArray;
|
||||
|
||||
}
|
||||
|
||||
-(void) newCapturedFrame:(IOSurfaceID)ioxpc reply:(void (^)())reply
|
||||
{
|
||||
|
||||
IOSurfaceRef frameIOref = IOSurfaceLookup(ioxpc);
|
||||
if (frameIOref)
|
||||
{
|
||||
|
||||
@synchronized(self) {
|
||||
if (_currentFrame)
|
||||
{
|
||||
IOSurfaceDecrementUseCount(_currentFrame);
|
||||
//CFRelease(_currentFrame);
|
||||
}
|
||||
|
||||
_currentFrame = frameIOref;
|
||||
IOSurfaceIncrementUseCount(_currentFrame);
|
||||
//CFRetain(_currentFrame);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// ALWAYS reply
|
||||
reply();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-(bool) stopCaptureSession
|
||||
{
|
||||
[_xpcProxy stopXPCCaptureSession];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
-(bool) startCaptureSession:(NSError **)error
|
||||
{
|
||||
|
||||
NSLog(@"CALLING STARTXPC WITH %@", _videoInputDevice);
|
||||
[_xpcProxy startXPCCaptureSession:_videoInputDevice];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
-(bool) setupCaptureSession:(NSError *__autoreleasing *)therror
|
||||
{
|
||||
|
||||
return YES;
|
||||
|
||||
}
|
||||
/*
|
||||
-(bool) setupCaptureSession:(NSError **)therror
|
||||
{
|
||||
|
||||
|
||||
AVCaptureDeviceInput *video_capture_input;
|
||||
AVCaptureDeviceInput *audio_capture_input;
|
||||
|
||||
if (_capture_session)
|
||||
return YES;
|
||||
|
||||
|
||||
NSLog(@"Starting setup capture");
|
||||
if (_videoDelegate || _audioDelegate)
|
||||
{
|
||||
_capture_session = [[AVCaptureSession alloc] init];
|
||||
}
|
||||
|
||||
if (_videoDelegate)
|
||||
{
|
||||
if (!_videoInputDevice)
|
||||
{
|
||||
NSLog(@"No video input device");
|
||||
*therror = [NSError errorWithDomain:@"videoCapture" code:100 userInfo:@{NSLocalizedDescriptionKey : @"Must select video capture device first"}];
|
||||
return NO;
|
||||
}
|
||||
|
||||
_capture_session = [[AVCaptureSession alloc] init];
|
||||
|
||||
|
||||
video_capture_input = [AVCaptureDeviceInput deviceInputWithDevice:_videoInputDevice error:therror];
|
||||
|
||||
if (!video_capture_input)
|
||||
{
|
||||
NSLog(@"No video capture input?");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([_capture_session canAddInput:video_capture_input])
|
||||
{
|
||||
[_capture_session addInput:video_capture_input];
|
||||
|
||||
} else {
|
||||
NSLog(@"Can't add video_capture_input");
|
||||
*therror = [NSError errorWithDomain:@"videoCapture" code:120 userInfo:@{NSLocalizedDescriptionKey : @"Could not add video input to capture session"}];
|
||||
return NO;
|
||||
}
|
||||
|
||||
_video_capture_output = [[AVCaptureVideoDataOutput alloc] init];
|
||||
|
||||
|
||||
if ([_capture_session canAddOutput:_video_capture_output])
|
||||
{
|
||||
[_capture_session addOutput:_video_capture_output];
|
||||
} else {
|
||||
NSLog(@"Can't add video capture output");
|
||||
*therror = [NSError errorWithDomain:@"videoCapture" code:130 userInfo:@{NSLocalizedDescriptionKey : @"Could not add video output to capture session"}];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (_audioDelegate)
|
||||
{
|
||||
|
||||
if (_audioInputDevice)
|
||||
{
|
||||
audio_capture_input = [AVCaptureDeviceInput deviceInputWithDevice:_audioInputDevice error:therror];
|
||||
|
||||
if (!audio_capture_input)
|
||||
{
|
||||
NSLog(@"No audio capture input?");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([_capture_session canAddInput:audio_capture_input])
|
||||
{
|
||||
[_capture_session addInput:audio_capture_input];
|
||||
|
||||
} else {
|
||||
NSLog(@"Can't add audio input?");
|
||||
*therror = [NSError errorWithDomain:@"audioCapture" code:220 userInfo:@{NSLocalizedDescriptionKey : @"Could not add audio input to capture session"}];
|
||||
return NO;
|
||||
}
|
||||
|
||||
_audio_capture_output = [[AVCaptureAudioDataOutput alloc] init];
|
||||
|
||||
|
||||
|
||||
_audio_capture_output.audioSettings = @{AVFormatIDKey: [NSNumber numberWithInt:kAudioFormatMPEG4AAC],
|
||||
AVSampleRateKey: [NSNumber numberWithFloat: 44100.0],
|
||||
AVEncoderBitRateKey: [NSNumber numberWithInt:_audioBitrate*1000 ],
|
||||
AVNumberOfChannelsKey: @2
|
||||
|
||||
};
|
||||
|
||||
|
||||
if ([_capture_session canAddOutput:_audio_capture_output])
|
||||
{
|
||||
[_capture_session addOutput:_audio_capture_output];
|
||||
} else {
|
||||
NSLog(@"Can't add audio capture output");
|
||||
*therror = [NSError errorWithDomain:@"audioCapture" code:230 userInfo:@{NSLocalizedDescriptionKey : @"Could not add audio output to capture session"}];
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
NSLog(@"No audio device?");
|
||||
*therror = [NSError errorWithDomain:@"audioCapture" code:240 userInfo:@{NSLocalizedDescriptionKey : @"Must select audio capture device first"}];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
void QTPixelBufferRelease(void *releaseRefCon, const void *baseAddress)
|
||||
{
|
||||
|
||||
if (baseAddress)
|
||||
free((void *)baseAddress);
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (CVImageBufferRef) getCurrentFrame
|
||||
{
|
||||
|
||||
CVImageBufferRef newbuf = NULL;
|
||||
|
||||
@synchronized(self)
|
||||
{
|
||||
if (_currentFrame)
|
||||
{
|
||||
CVPixelBufferCreateWithIOSurface(NULL, _currentFrame, NULL, &newbuf);
|
||||
return newbuf;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return newbuf;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
|
||||
{
|
||||
|
||||
if (connection.output == _video_capture_output)
|
||||
{
|
||||
CVImageBufferRef videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer);
|
||||
|
||||
|
||||
|
||||
@synchronized(self)
|
||||
{
|
||||
if (_currentFrame)
|
||||
{
|
||||
CVPixelBufferRelease(_currentFrame);
|
||||
}
|
||||
|
||||
CVPixelBufferRetain(videoFrame);
|
||||
_currentFrame = videoFrame;
|
||||
}
|
||||
} else if (connection.output == _audio_capture_output) {
|
||||
|
||||
|
||||
[_audioDelegate captureOutputAudio:self didOutputSampleBuffer:sampleBuffer];
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
|
|
@ -1321,7 +1321,7 @@
|
|||
<nil key="NSViewClass"/>
|
||||
<nil key="NSUserInterfaceItemIdentifier"/>
|
||||
<object class="NSView" key="NSWindowView" id="439893737">
|
||||
<nil key="NSNextResponder"/>
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSButton" id="389308716">
|
||||
|
|
@ -1329,6 +1329,7 @@
|
|||
<int key="NSvFlags">268</int>
|
||||
<string key="NSFrame">{{250, 25}, {82, 32}}</string>
|
||||
<reference key="NSSuperview" ref="439893737"/>
|
||||
<reference key="NSNextKeyView"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<object class="NSButtonCell" key="NSCell" id="454886443">
|
||||
|
|
@ -1357,12 +1358,13 @@
|
|||
<int key="NSvFlags">12</int>
|
||||
<string key="NSFrame">{{-1, 53}, {584, 329}}</string>
|
||||
<reference key="NSSuperview" ref="439893737"/>
|
||||
<reference key="NSNextKeyView" ref="107286857"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<array class="NSMutableArray" key="NSTabViewItems">
|
||||
<object class="NSTabViewItem" id="302448651">
|
||||
<string key="NSIdentifier">1</string>
|
||||
<object class="NSView" key="NSView" id="460084472">
|
||||
<reference key="NSNextResponder" ref="569688021"/>
|
||||
<nil key="NSNextResponder"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSPopUpButton" id="889564284">
|
||||
|
|
@ -1911,7 +1913,6 @@
|
|||
</object>
|
||||
</array>
|
||||
<string key="NSFrame">{{10, 33}, {564, 283}}</string>
|
||||
<reference key="NSSuperview" ref="569688021"/>
|
||||
<reference key="NSNextKeyView" ref="321001671"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:11</string>
|
||||
</object>
|
||||
|
|
@ -2177,7 +2178,7 @@
|
|||
<object class="NSTabViewItem" id="155388920">
|
||||
<string key="NSIdentifier">2</string>
|
||||
<object class="NSView" key="NSView" id="107286857">
|
||||
<nil key="NSNextResponder"/>
|
||||
<reference key="NSNextResponder" ref="569688021"/>
|
||||
<int key="NSvFlags">256</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="NSScrollView" id="710299427">
|
||||
|
|
@ -2194,7 +2195,7 @@
|
|||
<array class="NSMutableArray" key="NSSubviews"/>
|
||||
<string key="NSFrameSize">{478, 190}</string>
|
||||
<reference key="NSSuperview" ref="842508660"/>
|
||||
<reference key="NSNextKeyView" ref="598397452"/>
|
||||
<reference key="NSNextKeyView" ref="548143049"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:13</string>
|
||||
<bool key="NSEnabled">YES</bool>
|
||||
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
|
||||
|
|
@ -2208,11 +2209,10 @@
|
|||
<string key="NSReuseIdentifierKey">_NS:16</string>
|
||||
<reference key="NSTableView" ref="953940268"/>
|
||||
</object>
|
||||
<object class="_NSCornerView" key="NSCornerView" id="1050868349">
|
||||
<reference key="NSNextResponder" ref="710299427"/>
|
||||
<object class="_NSCornerView" key="NSCornerView">
|
||||
<nil key="NSNextResponder"/>
|
||||
<int key="NSvFlags">-2147483392</int>
|
||||
<string key="NSFrame">{{224, 0}, {16, 17}}</string>
|
||||
<reference key="NSSuperview" ref="710299427"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:19</string>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="NSTableColumns">
|
||||
|
|
@ -2388,11 +2388,10 @@
|
|||
<reference key="NSBGColor" ref="574509101"/>
|
||||
<int key="NScvFlags">4</int>
|
||||
</object>
|
||||
<reference ref="1050868349"/>
|
||||
</array>
|
||||
<string key="NSFrame">{{42, 31}, {480, 208}}</string>
|
||||
<reference key="NSSuperview" ref="107286857"/>
|
||||
<reference key="NSNextKeyView" ref="842508660"/>
|
||||
<reference key="NSNextKeyView" ref="598397452"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<string key="NSAntiCompressionPriority">{750, 750}</string>
|
||||
<int key="NSsFlags">133682</int>
|
||||
|
|
@ -2524,6 +2523,7 @@
|
|||
</object>
|
||||
</array>
|
||||
<string key="NSFrame">{{10, 33}, {564, 283}}</string>
|
||||
<reference key="NSSuperview" ref="569688021"/>
|
||||
<reference key="NSNextKeyView" ref="449329695"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:28</string>
|
||||
</object>
|
||||
|
|
@ -2532,20 +2532,21 @@
|
|||
<reference key="NSTabView" ref="569688021"/>
|
||||
</object>
|
||||
</array>
|
||||
<reference key="NSSelectedTabViewItem" ref="302448651"/>
|
||||
<reference key="NSSelectedTabViewItem" ref="155388920"/>
|
||||
<reference key="NSFont" ref="582680700"/>
|
||||
<int key="NSTvFlags">0</int>
|
||||
<bool key="NSAllowTruncatedLabels">YES</bool>
|
||||
<bool key="NSDrawsBackground">YES</bool>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<reference ref="460084472"/>
|
||||
<reference ref="107286857"/>
|
||||
</array>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSFrameSize">{582, 388}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSNextKeyView" ref="569688021"/>
|
||||
</object>
|
||||
<string key="NSScreenRect">{{0, 0}, {1920, 1058}}</string>
|
||||
<string key="NSScreenRect">{{0, 0}, {1680, 1028}}</string>
|
||||
<string key="NSMaxSize">{10000000000000, 10000000000000}</string>
|
||||
<bool key="NSWindowIsRestorable">YES</bool>
|
||||
</object>
|
||||
|
|
@ -7335,93 +7336,7 @@
|
|||
<nil key="sourceID"/>
|
||||
<int key="maxID">1844</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">AppDelegate</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<dictionary class="NSMutableDictionary" key="outlets">
|
||||
<string key="captureController">CaptureController</string>
|
||||
<string key="window">NSWindow</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<object class="IBToOneOutletInfo" key="captureController">
|
||||
<string key="name">captureController</string>
|
||||
<string key="candidateClassName">CaptureController</string>
|
||||
</object>
|
||||
<object class="IBToOneOutletInfo" key="window">
|
||||
<string key="name">window</string>
|
||||
<string key="candidateClassName">NSWindow</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/AppDelegate.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">CaptureController</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<dictionary class="NSMutableDictionary" key="actions">
|
||||
<string key="addStreamingService:">id</string>
|
||||
<string key="closeCreateSheet:">id</string>
|
||||
<string key="openCreateSheet:">id</string>
|
||||
<string key="removeDestination:">id</string>
|
||||
<string key="streamButtonPushed:">id</string>
|
||||
<string key="videoRefresh:">id</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="actionInfosByName">
|
||||
<object class="IBActionInfo" key="addStreamingService:">
|
||||
<string key="name">addStreamingService:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="closeCreateSheet:">
|
||||
<string key="name">closeCreateSheet:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="openCreateSheet:">
|
||||
<string key="name">openCreateSheet:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="removeDestination:">
|
||||
<string key="name">removeDestination:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="streamButtonPushed:">
|
||||
<string key="name">streamButtonPushed:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
<object class="IBActionInfo" key="videoRefresh:">
|
||||
<string key="name">videoRefresh:</string>
|
||||
<string key="candidateClassName">id</string>
|
||||
</object>
|
||||
</dictionary>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">createSheet</string>
|
||||
<string key="NS.object.0">NSWindow</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<string key="NS.key.0">createSheet</string>
|
||||
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||
<string key="name">createSheet</string>
|
||||
<string key="candidateClassName">NSWindow</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/CaptureController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">NSLayoutConstraint</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/NSLayoutConstraint.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes"/>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
|
|
|
|||
35
QTCaptureHelper/QTCaptureHelper-Info.plist
Normal file
35
QTCaptureHelper/QTCaptureHelper-Info.plist
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2012 Zakk. All rights reserved.</string>
|
||||
<key>LSBackgroundOnly</key>
|
||||
<true/>
|
||||
<key>XPCService</key>
|
||||
<dict>
|
||||
<key>RunLoopType</key>
|
||||
<string>NSRunLoop</string>
|
||||
<key>ServiceType</key>
|
||||
<string>Application</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
4
QTCaptureHelper/QTCaptureHelper-Prefix.pch
Normal file
4
QTCaptureHelper/QTCaptureHelper-Prefix.pch
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'QTCaptureHelper' target in the 'QTCaptureHelper' project
|
||||
//
|
||||
|
||||
35
QTCaptureHelper/XPCListenerDelegate.h
Normal file
35
QTCaptureHelper/XPCListenerDelegate.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// XPCListenerDelegate.h
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 11/10/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "QTHelperProtocol.h"
|
||||
#import "CapturedFrameProtocol.h"
|
||||
#import <QTKit/QTKit.h>
|
||||
|
||||
@interface XPCListenerDelegate : NSObject <NSXPCListenerDelegate, QTHelperProtocol>
|
||||
{
|
||||
QTCaptureDevice *captureDevice;
|
||||
QTCaptureSession *captureSession;
|
||||
QTCaptureDeviceInput *captureInput;
|
||||
QTCaptureDecompressedVideoOutput *captureOutput;
|
||||
id <CapturedFrameProtocol> xpcProxy;
|
||||
dispatch_queue_t frameQueue;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@property (strong) QTCaptureDevice *captureDevice;
|
||||
@property (strong) QTCaptureSession *captureSession;
|
||||
@property (strong) QTCaptureDeviceInput *captureInput;
|
||||
@property (strong) QTCaptureDecompressedVideoOutput *captureOutput;
|
||||
@property (strong) id xpcProxy;
|
||||
|
||||
|
||||
- (BOOL) listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection;
|
||||
@end
|
||||
198
QTCaptureHelper/XPCListenerDelegate.m
Normal file
198
QTCaptureHelper/XPCListenerDelegate.m
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
//
|
||||
// XPCListenerDelegate.m
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 11/10/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "XPCListenerDelegate.h"
|
||||
#import "QTHelperProtocol.h"
|
||||
#import <QTKit/QTKit.h>
|
||||
#import <IOSurface/IOSurfaceAPI.h>
|
||||
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
#import <QuickTime/QuickTime.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation XPCListenerDelegate
|
||||
|
||||
|
||||
@synthesize captureDevice;
|
||||
@synthesize captureSession;
|
||||
@synthesize captureInput;
|
||||
@synthesize captureOutput;
|
||||
@synthesize xpcProxy;
|
||||
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
|
||||
if (self.xpcProxy)
|
||||
{
|
||||
[self.xpcProxy release];
|
||||
|
||||
}
|
||||
[super dealloc];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (BOOL) listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
|
||||
{
|
||||
|
||||
NSXPCInterface *helperInterface = [[NSXPCInterface interfaceWithProtocol:@protocol(QTHelperProtocol)] retain];
|
||||
NSXPCInterface *masterInterface = [[NSXPCInterface interfaceWithProtocol:@protocol(CapturedFrameProtocol)] retain];
|
||||
|
||||
|
||||
[newConnection setExportedInterface:helperInterface];
|
||||
[newConnection setExportedObject:self];
|
||||
|
||||
[newConnection setRemoteObjectInterface:masterInterface];
|
||||
self.xpcProxy = [newConnection remoteObjectProxy];
|
||||
[self.xpcProxy retain];
|
||||
|
||||
|
||||
|
||||
[newConnection resume];
|
||||
[helperInterface release];
|
||||
[masterInterface release];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void) listCaptureDevices:(void (^)(NSArray *r_devices))reply
|
||||
{
|
||||
NSArray *devices = [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
|
||||
|
||||
NSMutableArray *retArray = [[NSMutableArray alloc] init];
|
||||
QTCaptureDevice *devinstance;
|
||||
|
||||
for(devinstance in devices)
|
||||
{
|
||||
[retArray addObject: @{@"name" : [devinstance localizedDisplayName], @"id":devinstance.uniqueID}];
|
||||
|
||||
|
||||
}
|
||||
|
||||
[devices release];
|
||||
reply((NSArray *)retArray);
|
||||
[retArray release];
|
||||
}
|
||||
|
||||
|
||||
- (void) stopXPCCaptureSession
|
||||
{
|
||||
if (self.captureSession)
|
||||
{
|
||||
[self.captureSession stopRunning];
|
||||
[self.captureSession release];
|
||||
}
|
||||
|
||||
if (self.captureDevice)
|
||||
{
|
||||
[self.captureDevice close];
|
||||
[self.captureDevice release];
|
||||
}
|
||||
|
||||
if (self.captureInput)
|
||||
{
|
||||
[self.captureInput release];
|
||||
}
|
||||
|
||||
if (self.captureOutput)
|
||||
{
|
||||
[self.captureOutput release];
|
||||
}
|
||||
|
||||
if (frameQueue)
|
||||
{
|
||||
dispatch_release(frameQueue);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void) startXPCCaptureSession:(NSString *)captureID
|
||||
{
|
||||
frameQueue = dispatch_queue_create("zakk.lol.frameQueue", NULL);
|
||||
|
||||
self.captureSession = [[[QTCaptureSession alloc] init] retain];
|
||||
self.captureDevice = [[QTCaptureDevice deviceWithUniqueID:captureID] retain];
|
||||
[self.captureDevice open:nil];
|
||||
self.captureInput = [[[QTCaptureDeviceInput alloc] initWithDevice:self.captureDevice] retain];
|
||||
|
||||
|
||||
NSError *error;
|
||||
|
||||
[self.captureSession addInput:self.captureInput error:&error];
|
||||
|
||||
self.captureOutput = [[[QTCaptureDecompressedVideoOutput alloc] init] retain];
|
||||
|
||||
|
||||
NSDictionary *ioAttrs = [NSDictionary dictionaryWithObject: [NSNumber numberWithBool: YES]
|
||||
forKey: (NSString *)kIOSurfaceIsGlobal];
|
||||
|
||||
NSMutableDictionary *pbAttrs = [NSMutableDictionary dictionaryWithObject:ioAttrs
|
||||
forKey: (NSString*)kCVPixelBufferIOSurfacePropertiesKey];
|
||||
|
||||
[pbAttrs setObject:
|
||||
[NSNumber numberWithInt:kCVPixelFormatType_422YpCbCr8]
|
||||
forKey:(NSString *)kCVPixelBufferPixelFormatTypeKey];
|
||||
|
||||
[self.captureOutput setPixelBufferAttributes:pbAttrs];
|
||||
|
||||
[self.captureOutput setDelegate:self];
|
||||
[self.captureSession addOutput:self.captureOutput error:nil];
|
||||
|
||||
|
||||
[self.captureSession startRunning];
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void) sendFrame:(CVImageBufferRef)newFrame
|
||||
{
|
||||
|
||||
if (newFrame)
|
||||
{
|
||||
dispatch_semaphore_t reply_s = dispatch_semaphore_create(0);
|
||||
IOSurfaceRef frameIOSurface = CVPixelBufferGetIOSurface(newFrame);
|
||||
IOSurfaceID frameID = IOSurfaceGetID(frameIOSurface);
|
||||
[self.xpcProxy newCapturedFrame:frameID reply:^{
|
||||
dispatch_semaphore_signal(reply_s);
|
||||
}];
|
||||
dispatch_semaphore_wait(reply_s, DISPATCH_TIME_FOREVER);
|
||||
CVPixelBufferRelease(newFrame);
|
||||
dispatch_release(reply_s);
|
||||
}
|
||||
|
||||
}
|
||||
- (void)captureOutput:(QTCaptureOutput *)captureOutput didOutputVideoFrame:(CVImageBufferRef)videoFrame withSampleBuffer:(QTSampleBuffer *)sampleBuffer fromConnection:(QTCaptureConnection *)connection
|
||||
{
|
||||
|
||||
CVPixelBufferRetain(videoFrame);
|
||||
dispatch_async(frameQueue, ^{
|
||||
[self sendFrame:videoFrame];
|
||||
});
|
||||
|
||||
//IOSurfaceIncrementUseCount(frameIORef);
|
||||
|
||||
//[self.xpcProxy newCapturedFrame:IOSurfaceCreateXPCObject(frameIORef)];
|
||||
//mach_port_deallocate(mach_task_self(), framePort);
|
||||
//CVPixelBufferRelease(videoFrame);
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void) testMethod
|
||||
{
|
||||
NSLog(@"CALLED TEST METHOD");
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
2
QTCaptureHelper/en.lproj/InfoPlist.strings
Normal file
2
QTCaptureHelper/en.lproj/InfoPlist.strings
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/* Localized versions of Info.plist keys */
|
||||
|
||||
28
QTCaptureHelper/main.m
Normal file
28
QTCaptureHelper/main.m
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// main.m
|
||||
// QTCaptureHelper
|
||||
//
|
||||
// Created by Zakk on 11/10/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#import "XPCListenerDelegate.h"
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
|
||||
XPCListenerDelegate *listenDelegate = [[XPCListenerDelegate new] retain];
|
||||
NSLog(@"LISTEN DELEGATE %@", listenDelegate);
|
||||
|
||||
NSXPCListener *listener = [[NSXPCListener serviceListener] retain];
|
||||
|
||||
//NSString *bundleId = [[NSBundle mainBundle] bundleIdentifier];
|
||||
//NSXPCListener *listener = [[NSXPCListener alloc] initWithMachServiceName:bundleId];
|
||||
|
||||
NSLog(@"LISTENER %@", listener);
|
||||
listener.delegate = listenDelegate;
|
||||
|
||||
[listener resume];
|
||||
NSLog(@"SETUP XPC LISTENER");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
19
QTHelperProtocol.h
Normal file
19
QTHelperProtocol.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// QTHelperProtocol.h
|
||||
// CocoaSplit
|
||||
//
|
||||
// Created by Zakk on 11/10/12.
|
||||
// Copyright (c) 2012 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol QTHelperProtocol
|
||||
- (void)listCaptureDevices:(void (^)(NSArray *r_devices))reply;
|
||||
- (void)startXPCCaptureSession:(NSString *)captureID;
|
||||
- (void)stopXPCCaptureSession;
|
||||
|
||||
|
||||
- (void)testMethod;
|
||||
|
||||
@end
|
||||
Loading…
Add table
Add a link
Reference in a new issue