mirror of
https://github.com/zakk4223/CocoaSplit.git
synced 2026-05-21 06:46:14 -06:00
Merge branch '2.0UI'
This commit is contained in:
commit
8eba5fa9b2
474 changed files with 22414 additions and 6244 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -0,0 +1,340 @@
|
|||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
343C79EC1D0C76C700B36EEC /* CSFFMpegCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 343C79EB1D0C76C700B36EEC /* CSFFMpegCapture.m */; };
|
||||
343C79F01D0CF3C100B36EEC /* CSFFMpegInput.m in Sources */ = {isa = PBXBuildFile; fileRef = 343C79EF1D0CF3C100B36EEC /* CSFFMpegInput.m */; };
|
||||
34BDCD651D10F4E100F51996 /* CSFFMpegCaptureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BDCD631D10F4E100F51996 /* CSFFMpegCaptureViewController.m */; };
|
||||
34BDCD661D10F4E100F51996 /* CSFFMpegCaptureViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34BDCD641D10F4E100F51996 /* CSFFMpegCaptureViewController.xib */; };
|
||||
34BDCD7D1D14178800F51996 /* CSFFMpegPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34BDCD7C1D14178800F51996 /* CSFFMpegPlayer.m */; };
|
||||
34EA820A1D2AB65300928A06 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 34BDCD7E1D1FE4A700F51996 /* Media.xcassets */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
343C79BA1D0C763A00B36EEC /* CSFFMpegCapturePlugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CSFFMpegCapturePlugin.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
343C79BD1D0C763A00B36EEC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
343C79DC1D0C769100B36EEC /* CSPluginServices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSPluginServices.h; path = PluginHeaders/CSPluginServices.h; sourceTree = "<group>"; };
|
||||
343C79DD1D0C769100B36EEC /* CSIOSurfaceLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSIOSurfaceLayer.h; path = PluginHeaders/CSIOSurfaceLayer.h; sourceTree = "<group>"; };
|
||||
343C79DE1D0C769100B36EEC /* CSPcmPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSPcmPlayer.h; path = PluginHeaders/CSPcmPlayer.h; sourceTree = "<group>"; };
|
||||
343C79DF1D0C769100B36EEC /* CAMultiAudioPCM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAMultiAudioPCM.h; path = PluginHeaders/CAMultiAudioPCM.h; sourceTree = "<group>"; };
|
||||
343C79E01D0C769100B36EEC /* CSAbstractCaptureDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSAbstractCaptureDevice.h; path = PluginHeaders/CSAbstractCaptureDevice.h; sourceTree = "<group>"; };
|
||||
343C79E11D0C769100B36EEC /* CSTextCaptureBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSTextCaptureBase.h; path = PluginHeaders/CSTextCaptureBase.h; sourceTree = "<group>"; };
|
||||
343C79E21D0C769100B36EEC /* CSTextCaptureViewControllerBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSTextCaptureViewControllerBase.h; path = PluginHeaders/CSTextCaptureViewControllerBase.h; sourceTree = "<group>"; };
|
||||
343C79E31D0C769100B36EEC /* CSCaptureBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSCaptureBase.h; path = PluginHeaders/CSCaptureBase.h; sourceTree = "<group>"; };
|
||||
343C79E41D0C769100B36EEC /* CSCaptureSourceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSCaptureSourceProtocol.h; path = PluginHeaders/CSCaptureSourceProtocol.h; sourceTree = "<group>"; };
|
||||
343C79E51D0C769100B36EEC /* CSStreamServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSStreamServiceProtocol.h; path = PluginHeaders/CSStreamServiceProtocol.h; sourceTree = "<group>"; };
|
||||
343C79E61D0C769100B36EEC /* CSPluginFactoryProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSPluginFactoryProtocol.h; path = PluginHeaders/CSPluginFactoryProtocol.h; sourceTree = "<group>"; };
|
||||
343C79E71D0C769100B36EEC /* CSExtraPluginProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSExtraPluginProtocol.h; path = PluginHeaders/CSExtraPluginProtocol.h; sourceTree = "<group>"; };
|
||||
343C79E81D0C769100B36EEC /* CSNotifications.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSNotifications.h; path = PluginHeaders/CSNotifications.h; sourceTree = "<group>"; };
|
||||
343C79EA1D0C76C700B36EEC /* CSFFMpegCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSFFMpegCapture.h; sourceTree = "<group>"; };
|
||||
343C79EB1D0C76C700B36EEC /* CSFFMpegCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSFFMpegCapture.m; sourceTree = "<group>"; };
|
||||
343C79EE1D0CF3C100B36EEC /* CSFFMpegInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSFFMpegInput.h; sourceTree = "<group>"; };
|
||||
343C79EF1D0CF3C100B36EEC /* CSFFMpegInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSFFMpegInput.m; sourceTree = "<group>"; };
|
||||
34BDCD621D10F4E100F51996 /* CSFFMpegCaptureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSFFMpegCaptureViewController.h; sourceTree = "<group>"; };
|
||||
34BDCD631D10F4E100F51996 /* CSFFMpegCaptureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSFFMpegCaptureViewController.m; sourceTree = "<group>"; };
|
||||
34BDCD641D10F4E100F51996 /* CSFFMpegCaptureViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CSFFMpegCaptureViewController.xib; sourceTree = "<group>"; };
|
||||
34BDCD7B1D14178800F51996 /* CSFFMpegPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSFFMpegPlayer.h; sourceTree = "<group>"; };
|
||||
34BDCD7C1D14178800F51996 /* CSFFMpegPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSFFMpegPlayer.m; sourceTree = "<group>"; };
|
||||
34BDCD7E1D1FE4A700F51996 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
343C79B71D0C763A00B36EEC /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
343C79B11D0C763A00B36EEC = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
34BDCD7E1D1FE4A700F51996 /* Media.xcassets */,
|
||||
343C79E91D0C769100B36EEC /* PluginHeaders */,
|
||||
343C79BC1D0C763A00B36EEC /* CSFFMpegCapturePlugin */,
|
||||
343C79BB1D0C763A00B36EEC /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
343C79BB1D0C763A00B36EEC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
343C79BA1D0C763A00B36EEC /* CSFFMpegCapturePlugin.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
343C79BC1D0C763A00B36EEC /* CSFFMpegCapturePlugin */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
343C79BD1D0C763A00B36EEC /* Info.plist */,
|
||||
343C79EA1D0C76C700B36EEC /* CSFFMpegCapture.h */,
|
||||
343C79EB1D0C76C700B36EEC /* CSFFMpegCapture.m */,
|
||||
343C79EE1D0CF3C100B36EEC /* CSFFMpegInput.h */,
|
||||
343C79EF1D0CF3C100B36EEC /* CSFFMpegInput.m */,
|
||||
34BDCD621D10F4E100F51996 /* CSFFMpegCaptureViewController.h */,
|
||||
34BDCD631D10F4E100F51996 /* CSFFMpegCaptureViewController.m */,
|
||||
34BDCD641D10F4E100F51996 /* CSFFMpegCaptureViewController.xib */,
|
||||
34BDCD7B1D14178800F51996 /* CSFFMpegPlayer.h */,
|
||||
34BDCD7C1D14178800F51996 /* CSFFMpegPlayer.m */,
|
||||
);
|
||||
path = CSFFMpegCapturePlugin;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
343C79E91D0C769100B36EEC /* PluginHeaders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
343C79DC1D0C769100B36EEC /* CSPluginServices.h */,
|
||||
343C79DD1D0C769100B36EEC /* CSIOSurfaceLayer.h */,
|
||||
343C79DE1D0C769100B36EEC /* CSPcmPlayer.h */,
|
||||
343C79DF1D0C769100B36EEC /* CAMultiAudioPCM.h */,
|
||||
343C79E01D0C769100B36EEC /* CSAbstractCaptureDevice.h */,
|
||||
343C79E11D0C769100B36EEC /* CSTextCaptureBase.h */,
|
||||
343C79E21D0C769100B36EEC /* CSTextCaptureViewControllerBase.h */,
|
||||
343C79E31D0C769100B36EEC /* CSCaptureBase.h */,
|
||||
343C79E41D0C769100B36EEC /* CSCaptureSourceProtocol.h */,
|
||||
343C79E51D0C769100B36EEC /* CSStreamServiceProtocol.h */,
|
||||
343C79E61D0C769100B36EEC /* CSPluginFactoryProtocol.h */,
|
||||
343C79E71D0C769100B36EEC /* CSExtraPluginProtocol.h */,
|
||||
343C79E81D0C769100B36EEC /* CSNotifications.h */,
|
||||
);
|
||||
name = PluginHeaders;
|
||||
path = ../CocoaSplit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
343C79B91D0C763A00B36EEC /* CSFFMpegCapturePlugin */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 343C79C01D0C763A00B36EEC /* Build configuration list for PBXNativeTarget "CSFFMpegCapturePlugin" */;
|
||||
buildPhases = (
|
||||
343C79B61D0C763A00B36EEC /* Sources */,
|
||||
343C79B71D0C763A00B36EEC /* Frameworks */,
|
||||
343C79B81D0C763A00B36EEC /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = CSFFMpegCapturePlugin;
|
||||
productName = CSFFMpegCapturePlugin;
|
||||
productReference = 343C79BA1D0C763A00B36EEC /* CSFFMpegCapturePlugin.bundle */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
343C79B21D0C763A00B36EEC /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0730;
|
||||
ORGANIZATIONNAME = Zakk;
|
||||
TargetAttributes = {
|
||||
343C79B91D0C763A00B36EEC = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 343C79B51D0C763A00B36EEC /* Build configuration list for PBXProject "CSFFMpegCapturePlugin" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 343C79B11D0C763A00B36EEC;
|
||||
productRefGroup = 343C79BB1D0C763A00B36EEC /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
343C79B91D0C763A00B36EEC /* CSFFMpegCapturePlugin */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
343C79B81D0C763A00B36EEC /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34EA820A1D2AB65300928A06 /* Media.xcassets in Resources */,
|
||||
34BDCD661D10F4E100F51996 /* CSFFMpegCaptureViewController.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
343C79B61D0C763A00B36EEC /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34BDCD651D10F4E100F51996 /* CSFFMpegCaptureViewController.m in Sources */,
|
||||
343C79EC1D0C76C700B36EEC /* CSFFMpegCapture.m in Sources */,
|
||||
343C79F01D0CF3C100B36EEC /* CSFFMpegInput.m in Sources */,
|
||||
34BDCD7D1D14178800F51996 /* CSFFMpegPlayer.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
343C79BE1D0C763A00B36EEC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
343C79BF1D0C763A00B36EEC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
343C79C11D0C763A00B36EEC /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
HEADER_SEARCH_PATHS = /usr/local/include;
|
||||
INFOPLIST_FILE = CSFFMpegCapturePlugin/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
suppress,
|
||||
"-flat_namespace",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = zakk.lol.CSFFMpegCapturePlugin;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
343C79C21D0C763A00B36EEC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_WARN_OBJC_EXPLICIT_OWNERSHIP_TYPE = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
HEADER_SEARCH_PATHS = /usr/local/include;
|
||||
INFOPLIST_FILE = CSFFMpegCapturePlugin/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
suppress,
|
||||
"-flat_namespace",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = zakk.lol.CSFFMpegCapturePlugin;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
343C79B51D0C763A00B36EEC /* Build configuration list for PBXProject "CSFFMpegCapturePlugin" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
343C79BE1D0C763A00B36EEC /* Debug */,
|
||||
343C79BF1D0C763A00B36EEC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
343C79C01D0C763A00B36EEC /* Build configuration list for PBXNativeTarget "CSFFMpegCapturePlugin" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
343C79C11D0C763A00B36EEC /* Debug */,
|
||||
343C79C21D0C763A00B36EEC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 343C79B21D0C763A00B36EEC /* Project object */;
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "343C79B91D0C763A00B36EEC"
|
||||
BuildableName = "CSFFMpegCapturePlugin.bundle"
|
||||
BlueprintName = "CSFFMpegCapturePlugin"
|
||||
ReferencedContainer = "container:CSFFMpegCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "343C79B91D0C763A00B36EEC"
|
||||
BuildableName = "CSFFMpegCapturePlugin.bundle"
|
||||
BlueprintName = "CSFFMpegCapturePlugin"
|
||||
ReferencedContainer = "container:CSFFMpegCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "343C79B91D0C763A00B36EEC"
|
||||
BuildableName = "CSFFMpegCapturePlugin.bundle"
|
||||
BlueprintName = "CSFFMpegCapturePlugin"
|
||||
ReferencedContainer = "container:CSFFMpegCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>CSFFMpegCapturePlugin.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>24</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>343C79B91D0C763A00B36EEC</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// CSFFMpegCapture.h
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/11/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "CSCaptureBase.h"
|
||||
#import "CSCaptureSourceProtocol.h"
|
||||
#import "CSFFMpegInput.h"
|
||||
#import "CSIOSurfaceLayer.h"
|
||||
#import "CAMultiAudioPCM.h"
|
||||
#import "CSPcmPlayer.h"
|
||||
#import "CSPluginServices.h"
|
||||
#import "CSFFMpegPlayer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#import "libavformat/avformat.h"
|
||||
#import "libavcodec/avcodec.h"
|
||||
#import "libavutil/threadmessage.h"
|
||||
#import "libavutil/pixfmt.h"
|
||||
#import "libavutil/pixdesc.h"
|
||||
|
||||
|
||||
@interface CSFFMpegCapture : CSCaptureBase <CSCaptureSourceProtocol>
|
||||
{
|
||||
AVFormatContext *_avFmtCtx;
|
||||
AVThreadMessageQueue *_video_msg_queue;
|
||||
AVThreadMessageQueue *_audio_msg_queue;
|
||||
|
||||
|
||||
dispatch_queue_t _video_decoder_queue;
|
||||
dispatch_queue_t _media_reader_queue;
|
||||
CAMultiAudioPCM *_bufferPCM;
|
||||
AudioStreamBasicDescription _asbd;
|
||||
CFTimeInterval _lastTimeUpdate;
|
||||
double _savedTime;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@property (strong) CSPcmPlayer *pcmPlayer;
|
||||
@property (strong) CSFFMpegPlayer *player;
|
||||
|
||||
@property (strong) NSString *currentTimeString;
|
||||
@property (strong) NSString *durationString;
|
||||
@property (assign) double currentMovieTime;
|
||||
@property (assign) double currentMovieDuration;
|
||||
@property (assign) bool playWhenLive;
|
||||
@property (assign) bool useCurrentPosition;
|
||||
|
||||
|
||||
|
||||
|
||||
-(void)queuePath:(NSString *)path;
|
||||
|
||||
-(void)pause;
|
||||
-(void)play;
|
||||
-(void)mute;
|
||||
-(void)next;
|
||||
-(void)back;
|
||||
|
||||
|
||||
@end
|
||||
363
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegCapture.m
Normal file
363
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegCapture.m
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
//
|
||||
// CSFFMpegCapture.m
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/11/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSFFMpegCapture.h"
|
||||
|
||||
@implementation CSFFMpegCapture
|
||||
|
||||
@synthesize currentMovieTime = _currentMovieTime;
|
||||
|
||||
-(instancetype) init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
av_register_all();
|
||||
avformat_network_init();
|
||||
|
||||
|
||||
self.needsSourceSelection = NO;
|
||||
|
||||
//Inputs resample to floating point non-interleaved 48k for now.
|
||||
|
||||
_asbd.mSampleRate = 48000;
|
||||
_asbd.mFormatID = kAudioFormatLinearPCM;
|
||||
_asbd.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved;
|
||||
_asbd.mChannelsPerFrame = 2;
|
||||
_asbd.mBitsPerChannel = 32;
|
||||
_asbd.mBytesPerFrame = 4;
|
||||
_asbd.mBytesPerPacket = 4;
|
||||
_asbd.mFramesPerPacket = 1;
|
||||
|
||||
_player = [[CSFFMpegPlayer alloc] init];
|
||||
|
||||
_player.asbd = &_asbd;
|
||||
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
|
||||
_player.itemStarted = ^(CSFFMpegInput *item) { [weakSelf itemStarted:item]; };
|
||||
_player.queueStateChanged = ^() { [weakSelf queueChanged]; };
|
||||
|
||||
self.activeVideoDevice = [[CSAbstractCaptureDevice alloc] init];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)encodeWithCoder:(NSCoder *)aCoder
|
||||
{
|
||||
NSMutableArray *queuePaths = [[NSMutableArray alloc] init];
|
||||
|
||||
for (CSFFMpegInput *inp in self.player.inputQueue)
|
||||
{
|
||||
[queuePaths addObject:inp.mediaPath];
|
||||
}
|
||||
|
||||
[aCoder encodeObject:queuePaths forKey:@"queuePaths"];
|
||||
|
||||
CSFFMpegInput *nowPlaying = self.player.currentlyPlaying;
|
||||
|
||||
NSString *nPath = nil;
|
||||
|
||||
if (nowPlaying)
|
||||
{
|
||||
nPath = nowPlaying.mediaPath;
|
||||
}
|
||||
|
||||
[aCoder encodeObject:nPath forKey:@"nowPlayingPath"];
|
||||
[aCoder encodeBool:self.playWhenLive forKey:@"playWhenLive"];
|
||||
[aCoder encodeBool:self.useCurrentPosition forKey:@"useCurrentPosition"];
|
||||
[aCoder encodeDouble:_currentMovieTime forKey:@"savedTime"];
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(instancetype)initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
if (self = [self init])
|
||||
{
|
||||
|
||||
CSFFMpegInput *nowPlayingInput = nil;
|
||||
NSString *nowPlayingPath = [aDecoder decodeObjectForKey:@"nowPlayingPath"];
|
||||
|
||||
NSArray *paths = [aDecoder decodeObjectForKey:@"queuePaths"];
|
||||
for (NSString *mPath in paths)
|
||||
{
|
||||
CSFFMpegInput *newInput = [[CSFFMpegInput alloc] initWithMediaPath:mPath];
|
||||
[self.player enqueueItem:newInput];
|
||||
if (nowPlayingPath && [newInput.mediaPath isEqualToString:nowPlayingPath])
|
||||
{
|
||||
nowPlayingInput = newInput;
|
||||
}
|
||||
}
|
||||
|
||||
if (nowPlayingInput)
|
||||
{
|
||||
self.player.currentlyPlaying = nowPlayingInput;
|
||||
}
|
||||
|
||||
_savedTime = [aDecoder decodeDoubleForKey:@"savedTime"];
|
||||
self.useCurrentPosition = [aDecoder decodeBoolForKey:@"useCurrentPosition"];
|
||||
|
||||
self.playWhenLive = [aDecoder decodeBoolForKey:@"playWhenLive"];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
+(NSString *)label
|
||||
{
|
||||
return @"Movie";
|
||||
}
|
||||
|
||||
-(void) generateUniqueID
|
||||
{
|
||||
NSMutableString *uID = [NSMutableString string];
|
||||
|
||||
|
||||
for(CSFFMpegInput *item in self.player.inputQueue)
|
||||
{
|
||||
NSString *itemStr = item.mediaPath;
|
||||
[uID appendString:itemStr];
|
||||
}
|
||||
|
||||
if (_pcmPlayer)
|
||||
{
|
||||
_pcmPlayer.nodeUID = uID;
|
||||
}
|
||||
|
||||
|
||||
self.activeVideoDevice.uniqueID = uID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(double)currentMovieTime
|
||||
{
|
||||
return _currentMovieTime;
|
||||
}
|
||||
|
||||
-(void)setCurrentMovieTime:(double)currentMovieTime
|
||||
{
|
||||
if (self.player)
|
||||
{
|
||||
[self.player seek:currentMovieTime];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)queueChanged
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self generateUniqueID];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
-(void)itemStarted:(CSFFMpegInput *)item
|
||||
{
|
||||
|
||||
NSString *timeString = [self timeToString:item.duration];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.durationString = [self timeToString:item.duration];
|
||||
self.currentMovieDuration = item.duration;
|
||||
[self generateUniqueID];
|
||||
self.captureName = item.shortName;
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
self.pcmPlayer.name = item.shortName;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)queuePath:(NSString *)path
|
||||
{
|
||||
if (!self.player.pcmPlayer && self.pcmPlayer)
|
||||
{
|
||||
self.player.pcmPlayer = self.pcmPlayer;
|
||||
}
|
||||
|
||||
CSFFMpegInput *newItem = [[CSFFMpegInput alloc] initWithMediaPath:path];
|
||||
|
||||
[self.player enqueueItem:newItem ];
|
||||
[self generateUniqueID];
|
||||
}
|
||||
|
||||
-(void)pause
|
||||
{
|
||||
if (self.player)
|
||||
{
|
||||
[self.player pause];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)play
|
||||
{
|
||||
if (self.player)
|
||||
{
|
||||
[self.player play];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)mute
|
||||
{
|
||||
if (self.player)
|
||||
{
|
||||
self.player.muted = !self.player.muted;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)next
|
||||
{
|
||||
if (self.player)
|
||||
{
|
||||
[self.player next];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)back
|
||||
{
|
||||
if (self.player)
|
||||
{
|
||||
[self.player back];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(CALayer *)createNewLayer
|
||||
{
|
||||
|
||||
CSIOSurfaceLayer *newLayer = [CSIOSurfaceLayer layer];
|
||||
|
||||
|
||||
return newLayer;
|
||||
}
|
||||
|
||||
|
||||
-(NSString *) timeToString:(double)convertTime
|
||||
{
|
||||
|
||||
UInt64 minutes = convertTime/60;
|
||||
UInt64 seconds = (int)convertTime % 60;
|
||||
return [NSString stringWithFormat:@"%02lld:%02lld", minutes, seconds];
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)frameTick
|
||||
{
|
||||
CFTimeInterval cTime = CACurrentMediaTime();
|
||||
CVPixelBufferRef use_buf = [self.player frameForMediaTime:cTime];
|
||||
|
||||
if (use_buf)
|
||||
{
|
||||
|
||||
if (cTime - _lastTimeUpdate > 0.5)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.currentTimeString = [self timeToString:self.player.lastVideoTime];
|
||||
[self willChangeValueForKey:@"currentMovieTime"];
|
||||
_currentMovieTime = self.player.lastVideoTime;;
|
||||
|
||||
[self didChangeValueForKey:@"currentMovieTime"];
|
||||
});
|
||||
}
|
||||
[self updateLayersWithBlock:^(CALayer *layer) {
|
||||
|
||||
((CSIOSurfaceLayer *)layer).imageBuffer = use_buf;
|
||||
}];
|
||||
|
||||
CVPixelBufferRelease(use_buf);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setIsLive:(bool)isLive
|
||||
{
|
||||
|
||||
bool oldLive = super.isLive;
|
||||
super.isLive = isLive;
|
||||
|
||||
if (isLive == oldLive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isLive)
|
||||
{
|
||||
[self registerPCMOutput:1024 audioFormat:&_asbd];
|
||||
if (self.playWhenLive)
|
||||
{
|
||||
[self.player play];
|
||||
if (self.useCurrentPosition)
|
||||
{
|
||||
[self.player seek:_savedTime];
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
[self deregisterPCMOutput];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)registerPCMOutput:(CMItemCount)frameCount audioFormat:(const AudioStreamBasicDescription *)audioFormat
|
||||
{
|
||||
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
//looks like we already have one?
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
self.pcmPlayer = [[CSPluginServices sharedPluginServices] createPCMInput:@"BLAHBLAH" withFormat:audioFormat];
|
||||
if (self.player)
|
||||
{
|
||||
self.player.asbd = &_asbd;
|
||||
self.player.pcmPlayer = self.pcmPlayer;
|
||||
self.pcmPlayer.name = self.player.currentlyPlaying.shortName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)deregisterPCMOutput
|
||||
{
|
||||
|
||||
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
|
||||
[[CSPluginServices sharedPluginServices] removePCMInput:self.pcmPlayer];
|
||||
}
|
||||
|
||||
self.pcmPlayer = nil;
|
||||
self.player.pcmPlayer = nil;
|
||||
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
[self deregisterPCMOutput];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// CSFFMpegCaptureViewController.h
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/14/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "CSFFMpegCapture.h"
|
||||
|
||||
@interface CSFFMpegCaptureViewController : NSViewController
|
||||
|
||||
@property (weak) CSFFMpegCapture *captureObj;
|
||||
@property (weak) IBOutlet NSSegmentedControl *playlistControl;
|
||||
@property (strong) IBOutlet NSArrayController *queueArrayController;
|
||||
@property (strong) NSString *stringItem;
|
||||
|
||||
|
||||
- (IBAction)queueTableDoubleClick:(NSTableView *)sender;
|
||||
|
||||
- (IBAction)chooseFile:(id)sender;
|
||||
- (IBAction)nextAction:(id)sender;
|
||||
- (IBAction)sliderValueChanged:(id)sender;
|
||||
- (IBAction)pauseAction:(id)sender;
|
||||
|
||||
- (IBAction)tableControlAction:(NSSegmentedControl *)sender;
|
||||
- (IBAction)manualAddItem:(id)sender;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
//
|
||||
// CSFFMpegCaptureViewController.m
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/14/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSFFMpegCaptureViewController.h"
|
||||
|
||||
@interface CSFFMpegCaptureViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation CSFFMpegCaptureViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do view setup here.
|
||||
if (self.captureObj && self.captureObj.player)
|
||||
{
|
||||
self.captureObj.player.pauseStateChanged = ^{
|
||||
[self pauseStateChanged];
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction)queueTableDoubleClick:(NSTableView *)sender
|
||||
{
|
||||
CSFFMpegInput *inp = [self.queueArrayController.arrangedObjects objectAtIndex:sender.clickedRow];
|
||||
if (inp)
|
||||
{
|
||||
[self.captureObj.player playAndAddItem:inp];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (IBAction)chooseFile:(id)sender
|
||||
{
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
panel.canChooseDirectories = NO;
|
||||
panel.canCreateDirectories = NO;
|
||||
panel.canChooseFiles = YES;
|
||||
panel.allowsMultipleSelection = YES;
|
||||
|
||||
[panel beginWithCompletionHandler:^(NSInteger result) {
|
||||
if (result == NSFileHandlingPanelOKButton)
|
||||
{
|
||||
for (NSURL *openURL in panel.URLs)
|
||||
{
|
||||
[self.captureObj queuePath:openURL.path];
|
||||
}
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
- (IBAction)tableControlAction:(NSSegmentedControl *)sender
|
||||
{
|
||||
NSUInteger clicked = sender.selectedSegment;
|
||||
|
||||
switch (clicked)
|
||||
{
|
||||
case 0:
|
||||
[self.queueArrayController removeObjectsAtArrangedObjectIndexes:self.queueArrayController.selectionIndexes];
|
||||
break;
|
||||
case 1:
|
||||
[self.captureObj back];
|
||||
break;
|
||||
case 2:
|
||||
if (!self.captureObj.player.playing || self.captureObj.player.paused)
|
||||
{
|
||||
[self.captureObj play];
|
||||
} else {
|
||||
[self.captureObj pause];
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
[self.captureObj next];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)manualAddItem:(id)sender
|
||||
{
|
||||
if (self.stringItem)
|
||||
{
|
||||
[self.captureObj queuePath:self.stringItem];
|
||||
self.stringItem = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-(void)pauseStateChanged
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self.captureObj.player.paused)
|
||||
{
|
||||
NSImage *playImage = [[NSBundle bundleForClass:[self class]] imageForResource:@"play"];
|
||||
|
||||
[self.playlistControl setImage:playImage forSegment:2];
|
||||
|
||||
} else {
|
||||
NSImage *pauseImage = [[NSBundle bundleForClass:[self class]] imageForResource:@"pause"];
|
||||
|
||||
[self.playlistControl setImage:pauseImage forSegment:2];
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
- (IBAction)sliderValueChanged:(id)sender
|
||||
{
|
||||
NSEvent *event = [[NSApplication sharedApplication] currentEvent];
|
||||
BOOL startingDrag = event.type == NSLeftMouseDown;
|
||||
BOOL endingDrag = event.type == NSLeftMouseUp;
|
||||
BOOL dragging = event.type == NSLeftMouseDragged;
|
||||
|
||||
|
||||
if (startingDrag) {
|
||||
[self.captureObj mute];
|
||||
}
|
||||
|
||||
|
||||
if (endingDrag) {
|
||||
[self.captureObj mute];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CSFFMpegCaptureViewController">
|
||||
<connections>
|
||||
<outlet property="playlistControl" destination="QyX-l5-Nc5" id="w6z-OF-Sap"/>
|
||||
<outlet property="queueArrayController" destination="IJW-AP-l9B" id="Iav-jl-1Al"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="Hz6-mo-xeY">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="308"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vOl-es-UsB">
|
||||
<rect key="frame" x="35" y="247" width="248" height="19"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="aCx-uQ-Hyw">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.stringItem" id="9bF-Cz-ync"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="f41-BA-QN1">
|
||||
<rect key="frame" x="0.0" y="85" width="480" height="154"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="brZ-Ue-OlN">
|
||||
<rect key="frame" x="1" y="1" width="478" height="152"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="I07-lW-ske">
|
||||
<rect key="frame" x="0.0" y="0.0" width="478" height="152"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="475" minWidth="40" maxWidth="1000" id="Nwb-J9-jgx">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
|
||||
</tableHeaderCell>
|
||||
<textFieldCell key="dataCell" controlSize="small" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="w0V-n1-Avc">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView id="RQg-6s-vBV">
|
||||
<rect key="frame" x="1" y="1" width="475" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="D02-lA-vKn">
|
||||
<rect key="frame" x="0.0" y="3" width="437" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="InC-Ai-kHU">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="RQg-6s-vBV" name="value" keyPath="objectValue.shortName" id="Keo-yR-kdF"/>
|
||||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="D02-lA-vKn" id="uUk-Qy-HWH"/>
|
||||
</connections>
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
</tableColumns>
|
||||
<connections>
|
||||
<action trigger="doubleAction" selector="queueTableDoubleClick:" target="-2" id="DqU-hT-tKe"/>
|
||||
<binding destination="IJW-AP-l9B" name="content" keyPath="arrangedObjects" id="Obn-rt-gTO"/>
|
||||
<binding destination="IJW-AP-l9B" name="selectionIndexes" keyPath="selectionIndexes" previousBinding="Obn-rt-gTO" id="uSY-FM-WQr"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="nop-yY-vCc">
|
||||
<rect key="frame" x="1" y="-14" width="0.0" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="v3c-hU-RoT">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SXP-7Z-utT">
|
||||
<rect key="frame" x="-2" y="48" width="53" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="4Uo-PT-atT">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.captureObj.currentTimeString" id="00c-WM-D7h"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0A5-wU-ykQ">
|
||||
<rect key="frame" x="426" y="48" width="56" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="geK-QL-6Yn">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="-2" name="value" keyPath="self.captureObj.durationString" id="8Rp-ok-mh4"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6Ff-r4-Piz">
|
||||
<rect key="frame" x="43" y="46" width="377" height="17"/>
|
||||
<sliderCell key="cell" controlSize="small" continuous="YES" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="above" sliderType="linear" id="0CD-ye-G7q"/>
|
||||
<connections>
|
||||
<action selector="sliderValueChanged:" target="-2" id="n3I-VU-HBB"/>
|
||||
<binding destination="oEH-Pr-eH8" name="maxValue" keyPath="selection.currentMovieDuration" id="tY5-ux-rot"/>
|
||||
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.currentMovieTime" previousBinding="tY5-ux-rot" id="3WD-8m-Go4"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<segmentedControl verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QyX-l5-Nc5">
|
||||
<rect key="frame" x="0.0" y="69" width="480" height="19"/>
|
||||
<segmentedCell key="cell" controlSize="mini" borderStyle="border" alignment="left" style="smallSquare" trackingMode="momentary" id="qwJ-2s-Umv">
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<segments>
|
||||
<segment image="NSRemoveTemplate"/>
|
||||
<segment image="rewind" tag="1"/>
|
||||
<segment image="play">
|
||||
<nil key="label"/>
|
||||
</segment>
|
||||
<segment image="fastforward">
|
||||
<nil key="label"/>
|
||||
</segment>
|
||||
<segment width="380" enabled="NO" tag="4">
|
||||
<nil key="label"/>
|
||||
</segment>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
<connections>
|
||||
<action selector="tableControlAction:" target="-2" id="iax-05-x1c"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rMk-Ss-9DA">
|
||||
<rect key="frame" x="-2" y="250" width="32" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Add:" id="p7M-Xi-1dn">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pyb-Oa-cTq">
|
||||
<rect key="frame" x="-2" y="288" width="52" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Playing:" id="b9z-O4-d9f">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Taf-5T-FT6">
|
||||
<rect key="frame" x="54" y="288" width="428" height="14"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="jIY-LY-9hI">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<connections>
|
||||
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.player.currentlyPlaying.shortName" id="xPc-Ft-0kn"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9Gg-JE-kf4">
|
||||
<rect key="frame" x="286" y="242" width="47" height="28"/>
|
||||
<buttonCell key="cell" type="push" title="Add" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="VLP-Wp-4UT">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="manualAddItem:" target="-2" id="b7q-4K-5mv"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lvV-HJ-t1F">
|
||||
<rect key="frame" x="331" y="242" width="65" height="28"/>
|
||||
<buttonCell key="cell" type="push" title="Browse" bezelStyle="rounded" alignment="center" controlSize="small" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Vlz-7L-vXD">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="chooseFile:" target="-2" id="upc-a7-d92"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i1u-Dr-69H">
|
||||
<rect key="frame" x="-3" y="23" width="96" height="20"/>
|
||||
<buttonCell key="cell" type="check" title="Play when live" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="meK-YV-QDR">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.playWhenLive" id="SP5-JY-yC1"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="o8b-MP-hMh">
|
||||
<rect key="frame" x="96" y="22" width="142" height="20"/>
|
||||
<buttonCell key="cell" type="check" title="Use current position" bezelStyle="regularSquare" imagePosition="left" controlSize="small" state="on" inset="2" id="c7q-Ze-6Qj">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<binding destination="oEH-Pr-eH8" name="value" keyPath="selection.useCurrentPosition" id="gTJ-ii-Wob"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="QyX-l5-Nc5" firstAttribute="top" secondItem="I07-lW-ske" secondAttribute="bottom" constant="-1" id="fLU-Tx-cYu"/>
|
||||
</constraints>
|
||||
<point key="canvasLocation" x="671" y="473"/>
|
||||
</customView>
|
||||
<objectController id="oEH-Pr-eH8" userLabel="FFmpegCaptureController">
|
||||
<connections>
|
||||
<binding destination="-2" name="contentObject" keyPath="self.captureObj" id="vTs-Dw-C56"/>
|
||||
</connections>
|
||||
</objectController>
|
||||
<arrayController id="IJW-AP-l9B" userLabel="QueueArrayController">
|
||||
<connections>
|
||||
<binding destination="-2" name="contentArray" keyPath="self.captureObj.player.inputQueue" id="87T-8P-KAK"/>
|
||||
</connections>
|
||||
</arrayController>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="NSRemoveTemplate" width="11" height="11"/>
|
||||
<image name="fastforward" width="74.400001525878906" height="58.400001525878906"/>
|
||||
<image name="play" width="50.400001525878906" height="58.400001525878906"/>
|
||||
<image name="rewind" width="74.400001525878906" height="58.400001525878906"/>
|
||||
</resources>
|
||||
</document>
|
||||
109
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegInput.h
Normal file
109
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegInput.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// CSFFMpegInput.h
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/11/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
|
||||
#import "libavformat/avformat.h"
|
||||
#import "libavcodec/avcodec.h"
|
||||
#import "libavutil/threadmessage.h"
|
||||
#import "libavutil/fifo.h"
|
||||
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
|
||||
#import "CAMultiAudioPCM.h"
|
||||
#import "CSPcmPlayer.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct frame_message {
|
||||
|
||||
AVFrame *frame;
|
||||
int notused;
|
||||
};
|
||||
|
||||
|
||||
@interface CSFFMpegInput : NSObject
|
||||
{
|
||||
int _video_stream_idx;
|
||||
int _audio_stream_idx;
|
||||
struct SwsContext *_sws_ctx;
|
||||
struct SwrContext *_swr_ctx;
|
||||
bool _video_done;
|
||||
bool _audio_done;
|
||||
uint64_t _seek_time;
|
||||
bool _seek_request;
|
||||
bool _stop_request;
|
||||
|
||||
dispatch_queue_t _seek_queue;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(instancetype) initWithMediaPath:(NSString *)mediaPath;
|
||||
-(bool)openMedia:(int)bufferVideoFrames;
|
||||
-(AVFrame *)consumeFrame;
|
||||
-(AVFrame *)consumeFrameWithRefill;
|
||||
-(void)readAndDecodeVideoFrames:(int)frameCnt;
|
||||
-(void)stop;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@property (strong) NSString *mediaPath;
|
||||
@property (assign) bool is_ready;
|
||||
@property (assign) bool is_draining;
|
||||
@property (assign) AVRational videoTimeBase;
|
||||
@property (assign) AVRational audioTimeBase;
|
||||
@property (strong) CSPcmPlayer *pcmPlayer;
|
||||
@property (assign) bool stopped;
|
||||
@property (assign) bool paused;
|
||||
@property (assign) AVThreadMessageQueue *video_message_queue;
|
||||
@property (assign) AVThreadMessageQueue *audio_message_queue;
|
||||
@property (assign) AVFormatContext *format_ctx;
|
||||
|
||||
@property (assign) AVCodecContext *video_codec_ctx;
|
||||
@property (assign) AVCodec *video_codec;
|
||||
|
||||
@property (assign) AVCodecContext *audio_codec_ctx;
|
||||
@property (assign) AVCodec *audio_codec;
|
||||
|
||||
|
||||
@property (nonatomic, copy) void (^completionCallback)(void);
|
||||
@property (assign) int64_t first_video_pts;
|
||||
@property (assign) int64_t first_audio_pts;
|
||||
|
||||
|
||||
@property (assign) NSSize dimensions;
|
||||
@property (assign) double duration;
|
||||
|
||||
@property (strong) NSString *shortName;
|
||||
|
||||
|
||||
-(AVFrame *)consumeFrame:(int *)error_out;
|
||||
-(CAMultiAudioPCM *)consumeAudioFrame:(AudioStreamBasicDescription *)asbd error_out:(int *)error_out;
|
||||
-(void) closeMedia;
|
||||
-(void) seek:(double)time;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
733
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegInput.m
Normal file
733
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegInput.m
Normal file
|
|
@ -0,0 +1,733 @@
|
|||
//
|
||||
// CSFFMpegInput.m
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/11/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSFFMpegInput.h"
|
||||
|
||||
@implementation CSFFMpegInput
|
||||
|
||||
|
||||
-(instancetype) init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_video_codec = NULL;
|
||||
_video_codec_ctx = NULL;
|
||||
_video_stream_idx = -1;
|
||||
_audio_stream_idx = -1;
|
||||
_is_ready = NO;
|
||||
_is_draining = NO;
|
||||
|
||||
_first_video_pts = 0;
|
||||
_first_audio_pts = 0;
|
||||
_duration = 0.0f;
|
||||
_seek_request = NO;
|
||||
_seek_time = 0;
|
||||
|
||||
_seek_queue = dispatch_queue_create("SEEK QUEUE", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(instancetype) initWithMediaPath:(NSString *)mediaPath
|
||||
{
|
||||
if (self = [self init])
|
||||
{
|
||||
self.mediaPath = mediaPath;
|
||||
self.shortName = [mediaPath lastPathComponent];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(bool)openMedia:(int)bufferVideoFrames
|
||||
{
|
||||
|
||||
|
||||
if (!self.mediaPath)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
if (!_video_message_queue)
|
||||
{
|
||||
av_thread_message_queue_alloc(&_video_message_queue, 300, sizeof(struct frame_message));
|
||||
}
|
||||
|
||||
if (!_audio_message_queue)
|
||||
{
|
||||
av_thread_message_queue_alloc(&_audio_message_queue, 4096 , sizeof(struct frame_message));
|
||||
}
|
||||
|
||||
av_thread_message_queue_set_err_recv(_video_message_queue, 0);
|
||||
av_thread_message_queue_set_err_recv(_audio_message_queue, 0);
|
||||
av_thread_message_queue_set_err_send(_video_message_queue, 0);
|
||||
av_thread_message_queue_set_err_send(_audio_message_queue, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AVCodecContext *v_codec_ctx_orig = NULL;
|
||||
AVCodecContext *a_codec_ctx_orig = NULL;
|
||||
int open_ret = avformat_open_input(&_format_ctx, self.mediaPath.UTF8String, NULL, NULL);
|
||||
if (open_ret < 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
avformat_find_stream_info(_format_ctx, NULL);
|
||||
//av_dump_format(_format_ctx, 0, self.mediaPath.UTF8String, 0);
|
||||
for (int i=0; i < _format_ctx->nb_streams; i++)
|
||||
{
|
||||
if (_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && _video_stream_idx == -1)
|
||||
{
|
||||
_video_stream_idx = i;
|
||||
}
|
||||
|
||||
if (_format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && _audio_stream_idx == -1)
|
||||
{
|
||||
_audio_stream_idx = i;
|
||||
}
|
||||
|
||||
if (_audio_stream_idx > -1 && _video_stream_idx > -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_video_stream_idx > -1)
|
||||
{
|
||||
self.videoTimeBase = _format_ctx->streams[_video_stream_idx]->time_base;
|
||||
v_codec_ctx_orig = _format_ctx->streams[_video_stream_idx]->codec;
|
||||
_video_codec = avcodec_find_decoder(v_codec_ctx_orig->codec_id);
|
||||
_video_codec_ctx = avcodec_alloc_context3(_video_codec);
|
||||
avcodec_copy_context(_video_codec_ctx, v_codec_ctx_orig);
|
||||
avcodec_open2(_video_codec_ctx, _video_codec, NULL);
|
||||
self.dimensions = NSMakeSize(_video_codec_ctx->width, _video_codec_ctx->height);
|
||||
_sws_ctx = sws_alloc_context();
|
||||
av_set_int(_sws_ctx, "srcw", _video_codec_ctx->width);
|
||||
av_set_int(_sws_ctx, "srch", _video_codec_ctx->height);
|
||||
av_set_int(_sws_ctx, "src_format", _video_codec_ctx->pix_fmt);
|
||||
av_set_int(_sws_ctx, "dstw", _video_codec_ctx->width);
|
||||
av_set_int(_sws_ctx, "dsth", _video_codec_ctx->height);
|
||||
av_set_int(_sws_ctx, "dst_format", AV_PIX_FMT_NV12);
|
||||
sws_init_context(_sws_ctx, NULL, NULL);
|
||||
}
|
||||
if (_audio_stream_idx > -1)
|
||||
{
|
||||
self.audioTimeBase = _format_ctx->streams[_audio_stream_idx]->time_base;
|
||||
|
||||
a_codec_ctx_orig = _format_ctx->streams[_audio_stream_idx]->codec;
|
||||
_audio_codec = avcodec_find_decoder(a_codec_ctx_orig->codec_id);
|
||||
_audio_codec_ctx = avcodec_alloc_context3(_audio_codec);
|
||||
avcodec_copy_context(_audio_codec_ctx, a_codec_ctx_orig);
|
||||
avcodec_open2(_audio_codec_ctx, _audio_codec, NULL);
|
||||
}
|
||||
|
||||
|
||||
self.is_ready = NO;
|
||||
_stop_request = NO;
|
||||
self.is_draining = NO;
|
||||
_video_done = NO;
|
||||
_audio_done = NO;
|
||||
|
||||
|
||||
self.duration = _format_ctx->duration / (double)AV_TIME_BASE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[self readAndDecodeVideoFrames:bufferVideoFrames];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-(CAMultiAudioPCM *)consumeAudioFrame:(AudioStreamBasicDescription *)asbd error_out:(int *)error_out
|
||||
{
|
||||
struct frame_message msg;
|
||||
|
||||
AudioBufferList *sampleABL = NULL;
|
||||
int av_ret = 0;
|
||||
|
||||
if (_audio_message_queue && ((*error_out = av_thread_message_queue_recv(_audio_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK)) >= 0))
|
||||
{
|
||||
|
||||
AVFrame *recv_frame;
|
||||
|
||||
recv_frame = msg.frame;
|
||||
if (!recv_frame)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (recv_frame->width == 999)
|
||||
{
|
||||
//flush PCM player
|
||||
av_frame_free(&recv_frame);
|
||||
CAMultiAudioPCM *flushPCM = [[CAMultiAudioPCM alloc] init];
|
||||
flushPCM.frameCount = -1;
|
||||
flushPCM.bufferCount = -1;
|
||||
return flushPCM;
|
||||
}
|
||||
|
||||
uint8_t **dst_data = NULL;
|
||||
int dst_linesize;
|
||||
|
||||
if (!_swr_ctx)
|
||||
{
|
||||
uint64_t channel_layout = _audio_codec_ctx->channel_layout;
|
||||
if (!channel_layout)
|
||||
{
|
||||
channel_layout = av_get_default_channel_layout(_audio_codec_ctx->channels);
|
||||
}
|
||||
_swr_ctx = swr_alloc_set_opts(NULL, AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_FLTP, asbd->mSampleRate, channel_layout, _audio_codec_ctx->sample_fmt, _audio_codec_ctx->sample_rate, 0, NULL);
|
||||
swr_init(_swr_ctx);
|
||||
}
|
||||
|
||||
|
||||
int dst_nb_samples = av_rescale_rnd(recv_frame->nb_samples, asbd->mSampleRate, _audio_codec_ctx->sample_rate, AV_ROUND_UP);
|
||||
av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, 2, dst_nb_samples, AV_SAMPLE_FMT_FLTP, 1);
|
||||
int conv_samples = swr_convert(_swr_ctx, dst_data, dst_nb_samples, recv_frame->extended_data, recv_frame->nb_samples);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int bufferCnt = asbd->mFormatFlags & kAudioFormatFlagIsNonInterleaved ? asbd->mChannelsPerFrame : 1;
|
||||
|
||||
int channelCnt = _audio_codec_ctx->channels;
|
||||
|
||||
long byteCnt = asbd->mBytesPerFrame * dst_nb_samples;
|
||||
|
||||
sampleABL = malloc(sizeof(AudioBufferList) + (bufferCnt-1)*sizeof(AudioBuffer));
|
||||
|
||||
|
||||
sampleABL->mNumberBuffers = bufferCnt;
|
||||
|
||||
for (int i=0; i<bufferCnt; i++)
|
||||
{
|
||||
sampleABL->mBuffers[i].mData = dst_data[i];
|
||||
|
||||
sampleABL->mBuffers[i].mDataByteSize = (UInt32)dst_linesize;
|
||||
sampleABL->mBuffers[i].mNumberChannels = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
av_frame_free(&recv_frame);
|
||||
|
||||
CAMultiAudioPCM *retPCM = [[CAMultiAudioPCM alloc] initWithAudioBufferList:sampleABL streamFormat:asbd];
|
||||
return retPCM;
|
||||
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)videoFlush:(bool)withEOF
|
||||
{
|
||||
|
||||
struct frame_message msg;
|
||||
avcodec_flush_buffers(_video_codec_ctx);
|
||||
int flush_cnt = 0;
|
||||
if (_video_message_queue)
|
||||
{
|
||||
while (av_thread_message_queue_recv(_video_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK) >= 0)
|
||||
{
|
||||
if (msg.frame)
|
||||
{
|
||||
av_frame_free(&msg.frame);
|
||||
}
|
||||
}
|
||||
if (withEOF)
|
||||
{
|
||||
av_thread_message_queue_set_err_recv(_video_message_queue, AVERROR_EOF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)audioFlush
|
||||
{
|
||||
|
||||
struct frame_message msg;
|
||||
int flush_cnt = 0;
|
||||
|
||||
avcodec_flush_buffers(_audio_codec_ctx);
|
||||
if (_audio_message_queue)
|
||||
{
|
||||
while (av_thread_message_queue_recv(_audio_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK) >= 0)
|
||||
{
|
||||
|
||||
if (msg.frame)
|
||||
{
|
||||
av_frame_free(&msg.frame);
|
||||
}
|
||||
}
|
||||
|
||||
AVFrame *flushFrame = av_frame_alloc();
|
||||
flushFrame->width = 999;
|
||||
msg.frame = flushFrame;
|
||||
|
||||
av_thread_message_queue_send(_audio_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)internal_seek:(int64_t)time
|
||||
{
|
||||
if (_format_ctx)
|
||||
{
|
||||
|
||||
int seek_ret = av_seek_frame(_format_ctx, -1, time, AVSEEK_FLAG_BACKWARD);
|
||||
|
||||
AVFifoBuffer *seek_buffer = av_fifo_alloc(sizeof(AVPacket) * 600);
|
||||
|
||||
|
||||
//int seek_ret = avformat_seek_file(_format_ctx, _video_stream_idx, time-10, time, time+10, AVSEEK_FLAG_BACKWARD);
|
||||
[self videoFlush:NO];
|
||||
[self audioFlush];
|
||||
|
||||
AVPacket buf_pkt;
|
||||
int64_t video_pts = AV_NOPTS_VALUE;
|
||||
|
||||
while (av_read_frame(_format_ctx, &buf_pkt) >= 0)
|
||||
{
|
||||
if (buf_pkt.stream_index == _video_stream_idx)
|
||||
{
|
||||
video_pts = buf_pkt.pts;
|
||||
[self decodeVideoPacket:&buf_pkt];
|
||||
av_free_packet(&buf_pkt);
|
||||
break;
|
||||
} else if (buf_pkt.stream_index == _audio_stream_idx){
|
||||
av_fifo_generic_write(seek_buffer, &buf_pkt, sizeof(AVPacket), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
while (av_fifo_size(seek_buffer) >= sizeof(AVPacket))
|
||||
{
|
||||
AVPacket a_pkt;
|
||||
av_fifo_generic_read(seek_buffer, &a_pkt, sizeof(AVPacket), NULL);
|
||||
if (av_compare_ts(a_pkt.pts, self.audioTimeBase, video_pts, self.videoTimeBase) >= 0)
|
||||
{
|
||||
[self decodeAudioPacket:&a_pkt];
|
||||
}
|
||||
av_free_packet(&a_pkt);
|
||||
}
|
||||
av_fifo_free(seek_buffer);
|
||||
|
||||
_first_video_pts = 0;
|
||||
_seek_request = NO;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)seek:(double)time
|
||||
{
|
||||
if (_seek_request) return;
|
||||
|
||||
if (_format_ctx)
|
||||
{
|
||||
int64_t seek_pts = time / av_q2d(AV_TIME_BASE_Q);
|
||||
|
||||
|
||||
_seek_time = seek_pts;
|
||||
_seek_request = YES;
|
||||
av_thread_message_queue_set_err_send(_video_message_queue, AVERROR_EXTERNAL);
|
||||
|
||||
//[self audioFlush];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)stop
|
||||
{
|
||||
_stop_request = YES;
|
||||
}
|
||||
|
||||
-(AVFrame *)consumeFrame:(int *)error_out
|
||||
{
|
||||
|
||||
if (!_video_message_queue)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (_video_done)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*error_out = 0;
|
||||
|
||||
struct frame_message msg;
|
||||
AVFrame *recv_frame;
|
||||
if ((*error_out = av_thread_message_queue_recv(_video_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK)) >= 0)
|
||||
{
|
||||
recv_frame = msg.frame;
|
||||
} else {
|
||||
if (*error_out == AVERROR_EOF)
|
||||
{
|
||||
_video_done = YES;
|
||||
}
|
||||
|
||||
if (self.is_draining)
|
||||
{
|
||||
self.is_ready = NO;
|
||||
}
|
||||
recv_frame = NULL;
|
||||
}
|
||||
return recv_frame;
|
||||
}
|
||||
|
||||
|
||||
//You should run this is a gcd queue/block
|
||||
|
||||
-(void)readAndDecodeVideoFrames:(int)frameCnt
|
||||
{
|
||||
|
||||
int read_frames = 0;
|
||||
AVFrame *output_frame = NULL;
|
||||
AVPacket av_packet;
|
||||
bool do_audio = YES;
|
||||
bool do_video = YES;
|
||||
int64_t seek_pts;
|
||||
struct frame_message msg;
|
||||
|
||||
|
||||
|
||||
if (!_format_ctx)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int pkt_cnt = 0;
|
||||
|
||||
while (do_audio || do_video)
|
||||
{
|
||||
if (_stop_request)
|
||||
{
|
||||
[self closeMedia];
|
||||
_stop_request = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_seek_request)
|
||||
{
|
||||
[self internal_seek:_seek_time];
|
||||
av_thread_message_queue_set_err_send(_video_message_queue, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (frameCnt == 0 && !self.is_ready)
|
||||
{
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
output_frame = av_frame_alloc();
|
||||
int got_decoded_frame;
|
||||
int read_ret = 0;
|
||||
|
||||
if (!self.is_draining)
|
||||
{
|
||||
read_ret = av_read_frame(_format_ctx, &av_packet);
|
||||
} else {
|
||||
|
||||
if (do_video)
|
||||
{
|
||||
av_init_packet(&av_packet);
|
||||
av_packet.stream_index = _video_stream_idx;
|
||||
av_packet.size = 0;
|
||||
av_packet.data = NULL;
|
||||
|
||||
} else if (do_audio) {
|
||||
av_init_packet(&av_packet);
|
||||
av_packet.stream_index = _audio_stream_idx;
|
||||
av_packet.size = 0;
|
||||
av_packet.data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (read_ret < 0)
|
||||
{
|
||||
self.is_draining = YES;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (do_video && (av_packet.stream_index == _video_stream_idx))
|
||||
{
|
||||
|
||||
if (_first_video_pts == 0 && av_packet.pts != AV_NOPTS_VALUE)
|
||||
{
|
||||
_first_video_pts = av_packet.pts;
|
||||
}
|
||||
|
||||
bool got_frame = [self decodeVideoPacket:&av_packet];
|
||||
|
||||
|
||||
|
||||
if (!got_frame)
|
||||
{
|
||||
if (self.is_draining)
|
||||
{
|
||||
av_thread_message_queue_set_err_recv(_video_message_queue, AVERROR_EOF);
|
||||
do_video = NO;
|
||||
}
|
||||
} else {
|
||||
read_frames++;
|
||||
}
|
||||
} else if (do_audio && (av_packet.stream_index == _audio_stream_idx)) {
|
||||
|
||||
if (_first_audio_pts == 0)
|
||||
{
|
||||
_first_audio_pts = av_packet.pts;
|
||||
}
|
||||
|
||||
bool got_frame = [self decodeAudioPacket:&av_packet];
|
||||
if (!got_frame && self.is_draining)
|
||||
{
|
||||
do_audio = NO;
|
||||
av_thread_message_queue_set_err_recv(_audio_message_queue, AVERROR_EOF);
|
||||
}
|
||||
}
|
||||
av_free_packet(&av_packet);
|
||||
|
||||
av_frame_free(&output_frame);
|
||||
if (frameCnt > 0 && read_frames >= frameCnt && !self.is_ready)
|
||||
{
|
||||
self.is_ready = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(bool)decodeAudioPacket:(AVPacket *)av_packet
|
||||
{
|
||||
|
||||
AVFrame *output_frame = NULL;
|
||||
void *orig_data;
|
||||
size_t orig_size;
|
||||
orig_size = av_packet->size;
|
||||
orig_data = av_packet->data;
|
||||
bool ret = NO;
|
||||
int got_decoded_frame = 0;
|
||||
output_frame = av_frame_alloc();
|
||||
struct frame_message msg;
|
||||
|
||||
|
||||
int read_len;
|
||||
while (av_packet->size > 0 || av_packet->data == NULL)
|
||||
{
|
||||
|
||||
read_len = avcodec_decode_audio4(_audio_codec_ctx, output_frame, &got_decoded_frame, av_packet);
|
||||
if (got_decoded_frame)
|
||||
{
|
||||
if (!output_frame->channel_layout)
|
||||
{
|
||||
output_frame->channel_layout = av_get_default_channel_layout(_audio_codec_ctx->channels);
|
||||
}
|
||||
AVFrame *cloned_frame = av_frame_clone(output_frame);
|
||||
|
||||
msg.frame = cloned_frame;
|
||||
msg.notused = 0;
|
||||
av_thread_message_queue_send(_audio_message_queue, &msg, 0);
|
||||
ret = YES;
|
||||
|
||||
} else {
|
||||
if (self.is_draining)
|
||||
{
|
||||
ret = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!self.is_draining)
|
||||
{
|
||||
if (read_len < 0)
|
||||
{
|
||||
av_packet->data = orig_data;
|
||||
av_packet->size = orig_size;
|
||||
break;
|
||||
} else {
|
||||
av_packet->data += read_len;
|
||||
av_packet->size -= read_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
av_frame_free(&output_frame);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
-(bool)decodeVideoPacket:(AVPacket *)av_packet
|
||||
{
|
||||
AVFrame *output_frame = NULL;
|
||||
struct frame_message msg;
|
||||
int got_decoded_frame = 0;
|
||||
bool ret = NO;
|
||||
|
||||
|
||||
|
||||
|
||||
output_frame = av_frame_alloc();
|
||||
|
||||
avcodec_decode_video2(_video_codec_ctx, output_frame, &got_decoded_frame, av_packet);
|
||||
if (got_decoded_frame)
|
||||
{
|
||||
|
||||
int width = output_frame->width;
|
||||
int height = output_frame->height;
|
||||
|
||||
|
||||
|
||||
AVFrame* conv_frame = avcodec_alloc_frame();
|
||||
conv_frame->width = width;
|
||||
conv_frame->height = height;
|
||||
conv_frame->format = AV_PIX_FMT_NV12;
|
||||
|
||||
int num_bytes = avpicture_get_size(AV_PIX_FMT_NV12, width, height);
|
||||
uint8_t* conv_buffer = (uint8_t *)av_malloc(num_bytes);
|
||||
avpicture_fill((AVPicture*)conv_frame, conv_buffer, AV_PIX_FMT_NV12, width, height);
|
||||
int scale_ret = sws_scale(_sws_ctx, output_frame->data, output_frame->linesize, 0, height, conv_frame->data, conv_frame->linesize);
|
||||
conv_frame->pts = output_frame->pts;
|
||||
conv_frame->pkt_dts = output_frame->pkt_dts;
|
||||
if (output_frame->pkt_pts != AV_NOPTS_VALUE)
|
||||
{
|
||||
|
||||
conv_frame->pkt_pts = output_frame->pkt_pts;
|
||||
} else {
|
||||
conv_frame->pkt_pts = output_frame->pkt_dts; //I guess
|
||||
}
|
||||
|
||||
|
||||
msg.frame = conv_frame;
|
||||
msg.notused = 0;
|
||||
av_thread_message_queue_send(_video_message_queue, &msg, 0);
|
||||
ret = YES;
|
||||
} else {
|
||||
ret = NO;
|
||||
}
|
||||
av_frame_free(&output_frame);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
-(void) closeMedia
|
||||
{
|
||||
|
||||
struct frame_message msg;
|
||||
|
||||
if (_video_message_queue)
|
||||
{
|
||||
while (av_thread_message_queue_recv(_video_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK) >= 0)
|
||||
{
|
||||
if (msg.frame)
|
||||
{
|
||||
av_frame_free(&msg.frame);
|
||||
}
|
||||
}
|
||||
|
||||
av_thread_message_queue_set_err_recv(_video_message_queue, AVERROR_EOF);
|
||||
|
||||
}
|
||||
|
||||
if (_audio_message_queue)
|
||||
{
|
||||
av_thread_message_queue_set_err_recv(_audio_message_queue, AVERROR_EOF);
|
||||
|
||||
|
||||
while (av_thread_message_queue_recv(_audio_message_queue, &msg, AV_THREAD_MESSAGE_NONBLOCK) >= 0)
|
||||
{
|
||||
if (msg.frame)
|
||||
{
|
||||
av_frame_free(&msg.frame);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_video_codec_ctx)
|
||||
{
|
||||
avcodec_close(_video_codec_ctx);
|
||||
}
|
||||
|
||||
if (_audio_codec_ctx)
|
||||
{
|
||||
avcodec_close(_audio_codec_ctx);
|
||||
}
|
||||
|
||||
|
||||
if (_format_ctx)
|
||||
{
|
||||
avformat_close_input(&_format_ctx);
|
||||
}
|
||||
|
||||
_video_codec_ctx = NULL;
|
||||
_audio_codec_ctx = NULL;
|
||||
|
||||
_format_ctx = NULL;
|
||||
if (_sws_ctx)
|
||||
{
|
||||
sws_freeContext(_sws_ctx);
|
||||
_sws_ctx = NULL;
|
||||
}
|
||||
|
||||
if (_swr_ctx)
|
||||
{
|
||||
swr_free(&_swr_ctx);
|
||||
}
|
||||
|
||||
|
||||
self.duration = 0.0f;
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
NSLog(@"DEALLOC?");
|
||||
[self closeMedia];
|
||||
if (_video_message_queue)
|
||||
{
|
||||
av_thread_message_queue_free(&_video_message_queue);
|
||||
_video_message_queue = NULL;
|
||||
}
|
||||
|
||||
if (_audio_message_queue)
|
||||
{
|
||||
av_thread_message_queue_free(&_audio_message_queue);
|
||||
_audio_message_queue = NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
85
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegPlayer.h
Normal file
85
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegPlayer.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// CSFFMpegPlayer.h
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/17/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import "CSFFMpegInput.h"
|
||||
#import "CSPcmPlayer.h"
|
||||
|
||||
@interface CSFFMpegPlayer : NSObject
|
||||
{
|
||||
CFTimeInterval _first_frame_host_time;
|
||||
AVFrame *_peek_frame;
|
||||
CVPixelBufferRef _last_buf;
|
||||
dispatch_queue_t _input_read_queue;
|
||||
dispatch_queue_t _audio_queue;
|
||||
bool _audio_done;
|
||||
bool _video_done;
|
||||
CVPixelBufferPoolRef *_cvpool;
|
||||
NSSize _currentSize;
|
||||
bool _nextFlag;
|
||||
int64_t _first_video_pts;
|
||||
bool _flushAudio;
|
||||
int _doneDirection;
|
||||
CSFFMpegInput *_forceNextInput;
|
||||
bool _seekRequest;
|
||||
double _seekRequestTime;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@property (strong) NSMutableArray *inputQueue;
|
||||
@property (strong) CSPcmPlayer *pcmPlayer;
|
||||
@property (assign) bool paused;
|
||||
@property (assign) bool playing;
|
||||
|
||||
@property (strong) CSFFMpegInput *currentlyPlaying;
|
||||
@property (assign) AudioStreamBasicDescription *asbd;
|
||||
|
||||
@property (copy, nonatomic) void (^itemStarted)(CSFFMpegInput *);
|
||||
@property (copy, nonatomic) void (^pauseStateChanged)();
|
||||
@property (copy, nonatomic) void (^queueStateChanged)();
|
||||
|
||||
|
||||
@property (assign) double lastVideoTime;
|
||||
@property (assign) double videoDuration;
|
||||
@property (assign) bool muted;
|
||||
@property (assign) bool seeking;
|
||||
@property (assign) bool audio_needs_restart;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-(void)nextItem;
|
||||
-(void)previousItem;
|
||||
-(void)enqueueItem:(CSFFMpegInput *)item;
|
||||
-(void)play;
|
||||
-(void)stop;
|
||||
-(void)next;
|
||||
-(void)pause;
|
||||
-(void)back;
|
||||
-(void)playAndAddItem:(CSFFMpegInput *)item;
|
||||
|
||||
|
||||
|
||||
-(void)seek:(double)toTime;
|
||||
-(void)startAudio;
|
||||
|
||||
|
||||
|
||||
-(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime;
|
||||
|
||||
|
||||
|
||||
@end
|
||||
660
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegPlayer.m
Normal file
660
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/CSFFMpegPlayer.m
Normal file
|
|
@ -0,0 +1,660 @@
|
|||
//
|
||||
// CSFFMpegPlayer.m
|
||||
// CSFFMpegCapturePlugin
|
||||
//
|
||||
// Created by Zakk on 6/17/16.
|
||||
// Copyright © 2016 Zakk. All rights reserved.
|
||||
//
|
||||
|
||||
#import "CSFFMpegPlayer.h"
|
||||
|
||||
@implementation CSFFMpegPlayer
|
||||
|
||||
@synthesize muted = _muted;
|
||||
|
||||
|
||||
-(instancetype) init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_input_read_queue = dispatch_queue_create("FFMPEG PLAYER INPUT", DISPATCH_QUEUE_SERIAL);
|
||||
_audio_queue = dispatch_queue_create("FFMPEG PLAYER AUDIO", DISPATCH_QUEUE_SERIAL);
|
||||
_currentSize = NSZeroSize;
|
||||
_inputQueue = [[NSMutableArray alloc] init];
|
||||
_nextFlag = NO;
|
||||
_muted = NO;
|
||||
_doneDirection = 1;
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
-(void)removeObjectFromInputQueueAtIndex:(NSUInteger)index
|
||||
{
|
||||
[_inputQueue removeObjectAtIndex:index];
|
||||
if (self.queueStateChanged)
|
||||
{
|
||||
self.queueStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
-(void)insertObject:(NSObject *)object inInputQueueAtIndex:(NSUInteger)index
|
||||
{
|
||||
[_inputQueue insertObject:object atIndex:index];
|
||||
if (self.queueStateChanged)
|
||||
{
|
||||
self.queueStateChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)setMuted:(bool)muted
|
||||
{
|
||||
_muted = muted;
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
|
||||
self.pcmPlayer.muted = muted;
|
||||
}
|
||||
}
|
||||
|
||||
-(bool)muted
|
||||
{
|
||||
return _muted;
|
||||
}
|
||||
|
||||
|
||||
-(void)readThread
|
||||
{
|
||||
if (self.currentlyPlaying)
|
||||
{
|
||||
if (_seekRequest)
|
||||
{
|
||||
[self seek:_seekRequestTime];
|
||||
}
|
||||
|
||||
[self.currentlyPlaying readAndDecodeVideoFrames:0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(CSFFMpegInput *)preChangeItem
|
||||
{
|
||||
CSFFMpegInput *useItem;
|
||||
_nextFlag = NO;
|
||||
@synchronized (self) {
|
||||
useItem = self.currentlyPlaying;
|
||||
self.currentlyPlaying = nil;
|
||||
_audio_done = NO;
|
||||
_video_done = NO;
|
||||
_flushAudio = NO;
|
||||
_first_frame_host_time = 0;
|
||||
}
|
||||
|
||||
if (useItem)
|
||||
{
|
||||
if (self.pcmPlayer)
|
||||
{
|
||||
[self.pcmPlayer flush];
|
||||
}
|
||||
}
|
||||
|
||||
if (useItem)
|
||||
{
|
||||
[useItem closeMedia];
|
||||
}
|
||||
|
||||
|
||||
return useItem;
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)previousItem
|
||||
{
|
||||
CSFFMpegInput *useItem = [self preChangeItem];
|
||||
|
||||
if (!self.playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger currentIdx = 0;
|
||||
|
||||
currentIdx = [_inputQueue indexOfObject:useItem];
|
||||
|
||||
currentIdx--;
|
||||
|
||||
if (currentIdx < 0)
|
||||
{
|
||||
currentIdx = _inputQueue.count-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CSFFMpegInput *nextItem = nil;
|
||||
|
||||
|
||||
if (currentIdx >=0 && (currentIdx < _inputQueue.count))
|
||||
{
|
||||
nextItem = [_inputQueue objectAtIndex:currentIdx];
|
||||
|
||||
}
|
||||
if (nextItem)
|
||||
{
|
||||
[self playItem:nextItem];
|
||||
//[self removeObjectFromInputQueueAtIndex:0];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)nextItem
|
||||
{
|
||||
CSFFMpegInput *useItem = [self preChangeItem];
|
||||
|
||||
if (!self.playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSUInteger currentIdx = 0;
|
||||
|
||||
currentIdx = [_inputQueue indexOfObject:useItem];
|
||||
|
||||
currentIdx++;
|
||||
|
||||
if (currentIdx >= _inputQueue.count)
|
||||
{
|
||||
currentIdx = 0;
|
||||
}
|
||||
|
||||
CSFFMpegInput *nextItem = nil;
|
||||
|
||||
|
||||
if (currentIdx >=0 && (currentIdx < _inputQueue.count))
|
||||
{
|
||||
nextItem = [_inputQueue objectAtIndex:currentIdx];
|
||||
|
||||
}
|
||||
if (nextItem)
|
||||
{
|
||||
[self playItem:nextItem];
|
||||
//[self removeObjectFromInputQueueAtIndex:0];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)playAndAddItem:(CSFFMpegInput *)item;
|
||||
{
|
||||
if ([_inputQueue indexOfObject:item] == NSNotFound)
|
||||
{
|
||||
[self enqueueItem:item];
|
||||
}
|
||||
|
||||
if (!self.playing)
|
||||
{
|
||||
self.currentlyPlaying = item;
|
||||
[self playItem:item];
|
||||
} else {
|
||||
_forceNextInput = item;
|
||||
[self.currentlyPlaying stop];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)seek:(double)toTime
|
||||
{
|
||||
|
||||
if (_seekRequest)
|
||||
{
|
||||
[self.currentlyPlaying seek:toTime];
|
||||
_first_frame_host_time = 0;
|
||||
_peek_frame = NULL;
|
||||
_first_video_pts = 0;
|
||||
_seekRequest = NO;
|
||||
_seekRequestTime = 0.0f;
|
||||
|
||||
} else {
|
||||
_seekRequest = YES;
|
||||
_seekRequestTime = toTime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)playItem:(CSFFMpegInput *)item
|
||||
{
|
||||
dispatch_async(_input_read_queue, ^{
|
||||
|
||||
[item openMedia:15];
|
||||
|
||||
if (self.itemStarted)
|
||||
{
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ self.itemStarted(item);});
|
||||
}
|
||||
|
||||
self.lastVideoTime = 0.0f;
|
||||
self.videoDuration = item.duration;
|
||||
|
||||
|
||||
@synchronized (self) {
|
||||
self.currentlyPlaying = item;
|
||||
self.playing = YES;
|
||||
}
|
||||
[self readThread];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
-(void)enqueueItem:(CSFFMpegInput *)item
|
||||
{
|
||||
[self insertObject:item inInputQueueAtIndex:self.inputQueue.count];
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(void)play
|
||||
{
|
||||
self.playing = YES;
|
||||
if (!self.currentlyPlaying)
|
||||
{
|
||||
|
||||
[self nextItem];
|
||||
} else {
|
||||
[self playItem:self.currentlyPlaying];
|
||||
}
|
||||
|
||||
if (self.paused)
|
||||
{
|
||||
[self pause];
|
||||
} else {
|
||||
|
||||
if (self.pauseStateChanged)
|
||||
{
|
||||
self.pauseStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)next
|
||||
{
|
||||
_flushAudio = YES;
|
||||
_doneDirection = 1;
|
||||
[self.currentlyPlaying stop];
|
||||
}
|
||||
|
||||
-(void)back
|
||||
{
|
||||
_flushAudio = YES;
|
||||
if (self.lastVideoTime >= 1.5)
|
||||
{
|
||||
[self seek:0.0];
|
||||
} else {
|
||||
_doneDirection = -1;
|
||||
[self.currentlyPlaying stop];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)stop
|
||||
{
|
||||
self.playing = NO;
|
||||
[self.currentlyPlaying closeMedia];
|
||||
}
|
||||
|
||||
-(void)startAudio
|
||||
{
|
||||
dispatch_async(_audio_queue, ^{
|
||||
|
||||
[self.pcmPlayer play];
|
||||
[self audioThread];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)audioThread
|
||||
{
|
||||
|
||||
|
||||
int av_error = 0;
|
||||
CAMultiAudioPCM *audioPCM = NULL;
|
||||
CSFFMpegInput *useItem;
|
||||
bool good_audio = NO;
|
||||
|
||||
while (self.playing)
|
||||
{
|
||||
if (self.paused)
|
||||
{
|
||||
[self.pcmPlayer pause];
|
||||
return;
|
||||
}
|
||||
|
||||
audioPCM = [self.currentlyPlaying consumeAudioFrame:self.asbd error_out:&av_error];
|
||||
if (!self.playing) break;
|
||||
if (av_error == AVERROR_EOF)
|
||||
{
|
||||
if (_flushAudio)
|
||||
{
|
||||
[self.pcmPlayer flush];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (audioPCM)
|
||||
{
|
||||
if (audioPCM.bufferCount == -1 && audioPCM.frameCount == -1)
|
||||
{
|
||||
if (good_audio)
|
||||
{
|
||||
//input needs us to flush the player, probably due to seek
|
||||
[self.pcmPlayer flush];
|
||||
[self.pcmPlayer play];
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
good_audio = YES;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!self.playing) break;
|
||||
|
||||
if (self.pcmPlayer.pendingFrames > 60 || av_error == AVERROR(EAGAIN))
|
||||
{
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
if (!self.playing) break;
|
||||
if (audioPCM)
|
||||
{
|
||||
[self.pcmPlayer playPcmBuffer:audioPCM];
|
||||
}
|
||||
if (self.paused)
|
||||
{
|
||||
[self.pcmPlayer pause];
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self.playing) break;
|
||||
}
|
||||
|
||||
_audio_done = YES;
|
||||
[self inputDone];
|
||||
}
|
||||
|
||||
|
||||
-(void)pause
|
||||
{
|
||||
if (self.paused)
|
||||
{
|
||||
_first_video_pts = self.lastVideoTime / av_q2d(self.currentlyPlaying.videoTimeBase);
|
||||
_first_frame_host_time = CACurrentMediaTime();
|
||||
self.paused = NO;
|
||||
[self startAudio];
|
||||
} else {
|
||||
self.paused = YES;
|
||||
}
|
||||
|
||||
if (self.pauseStateChanged)
|
||||
{
|
||||
self.pauseStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(CVPixelBufferRef)frameForMediaTime:(CFTimeInterval)mediaTime
|
||||
{
|
||||
CSFFMpegInput *_useInput;
|
||||
|
||||
@synchronized (self) {
|
||||
_useInput = self.currentlyPlaying;
|
||||
}
|
||||
|
||||
if (!_useInput)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (_seekRequest)
|
||||
{
|
||||
[self seek:_seekRequestTime];
|
||||
}
|
||||
|
||||
|
||||
AVFrame *use_frame = NULL;
|
||||
CVPixelBufferRef ret = nil;
|
||||
int64_t audio_pts = 0;
|
||||
bool play_audio = YES;
|
||||
|
||||
|
||||
int av_error = 0;
|
||||
|
||||
if (_first_frame_host_time == 0)
|
||||
{
|
||||
|
||||
play_audio = NO;
|
||||
|
||||
use_frame = [_useInput consumeFrame:&av_error];
|
||||
if (use_frame)
|
||||
{
|
||||
|
||||
_first_frame_host_time = mediaTime;
|
||||
_peek_frame = NULL;
|
||||
_last_buf = nil;
|
||||
audio_pts = use_frame->pkt_pts;
|
||||
_first_video_pts = 0;
|
||||
[self startAudio];
|
||||
}
|
||||
} else {
|
||||
if (!self.paused)
|
||||
{
|
||||
CFTimeInterval host_delta = mediaTime - _first_frame_host_time;
|
||||
int64_t target_pts = host_delta / av_q2d(self.currentlyPlaying.videoTimeBase);
|
||||
|
||||
if (_first_video_pts)
|
||||
{
|
||||
target_pts += _first_video_pts;
|
||||
} else {
|
||||
target_pts += _useInput.first_video_pts;
|
||||
}
|
||||
|
||||
audio_pts = target_pts;
|
||||
|
||||
|
||||
|
||||
int consumed = 0;
|
||||
use_frame = NULL;
|
||||
bool do_consume = YES;
|
||||
|
||||
if (_last_buf && _peek_frame)
|
||||
{
|
||||
|
||||
if (_peek_frame->pkt_pts > target_pts)
|
||||
{
|
||||
do_consume = NO;
|
||||
} else {
|
||||
use_frame = _peek_frame;
|
||||
do_consume = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (do_consume && (_peek_frame = [_useInput consumeFrame:&av_error]) && _peek_frame->pkt_pts < target_pts)
|
||||
{
|
||||
|
||||
if (use_frame)
|
||||
{
|
||||
av_frame_free(&use_frame);
|
||||
use_frame = _peek_frame;
|
||||
}
|
||||
consumed++;
|
||||
}
|
||||
if (av_error == AVERROR_EOF)
|
||||
{
|
||||
_video_done = YES;
|
||||
}
|
||||
|
||||
consumed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_frame && !_video_done)
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
if (self.audio_needs_restart)
|
||||
{
|
||||
[self.pcmPlayer flush];
|
||||
[self.pcmPlayer play];
|
||||
self.audio_needs_restart = NO;
|
||||
}*/
|
||||
|
||||
|
||||
self.lastVideoTime = use_frame->pkt_pts * av_q2d(_useInput.videoTimeBase);
|
||||
|
||||
ret = [self convertFrameToPixelBuffer:use_frame];
|
||||
av_frame_free(&use_frame);
|
||||
CVPixelBufferRetain(ret);
|
||||
if (_last_buf)
|
||||
{
|
||||
CVPixelBufferRelease(_last_buf);
|
||||
}
|
||||
_last_buf = ret;
|
||||
} else {
|
||||
CVPixelBufferRetain(_last_buf);
|
||||
ret = _last_buf;
|
||||
}
|
||||
|
||||
[self inputDone];
|
||||
return ret;
|
||||
}
|
||||
|
||||
-(void)inputDone
|
||||
{
|
||||
if (_audio_done && _video_done)
|
||||
{
|
||||
[self.currentlyPlaying stop];
|
||||
|
||||
if (_forceNextInput)
|
||||
{
|
||||
[self preChangeItem];
|
||||
[self playItem:_forceNextInput];
|
||||
_forceNextInput = nil;
|
||||
} else if (_doneDirection > 0) {
|
||||
[self nextItem];
|
||||
} else if (_doneDirection < 0) {
|
||||
[self previousItem];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(bool) createPixelBufferPoolForSize:(NSSize) size
|
||||
{
|
||||
|
||||
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
|
||||
[attributes setValue:[NSNumber numberWithInt:size.width] forKey:(NSString *)kCVPixelBufferWidthKey];
|
||||
[attributes setValue:[NSNumber numberWithInt:size.height] forKey:(NSString *)kCVPixelBufferHeightKey];
|
||||
[attributes setValue:@{(NSString *)kIOSurfaceIsGlobal: @NO} forKey:(NSString *)kCVPixelBufferIOSurfacePropertiesKey];
|
||||
[attributes setValue:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] forKey:(NSString *)kCVPixelBufferPixelFormatTypeKey];
|
||||
|
||||
|
||||
|
||||
if (_cvpool)
|
||||
{
|
||||
CVPixelBufferPoolRelease(_cvpool);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CVReturn result = CVPixelBufferPoolCreate(NULL, NULL, (__bridge CFDictionaryRef)(attributes), &_cvpool);
|
||||
|
||||
if (result != kCVReturnSuccess)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
|
||||
|
||||
}
|
||||
|
||||
-(CVPixelBufferRef) convertFrameToPixelBuffer:(AVFrame *)av_frame
|
||||
{
|
||||
if (!av_frame || !av_frame->data[0])
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
NSSize frameSize = NSMakeSize(av_frame->width, av_frame->height);
|
||||
if (!NSEqualSizes(_currentSize, frameSize))
|
||||
{
|
||||
_currentSize = frameSize;
|
||||
[self createPixelBufferPoolForSize:frameSize];
|
||||
}
|
||||
|
||||
|
||||
CVPixelBufferRef buf;
|
||||
CVPixelBufferPoolCreatePixelBuffer(NULL, _cvpool, &buf);
|
||||
int pbcnt = CVPixelBufferGetPlaneCount(buf);
|
||||
|
||||
CVPixelBufferLockBaseAddress(buf, 0);
|
||||
|
||||
for (int i = 0; i < pbcnt; i++)
|
||||
{
|
||||
uint8_t *src_addr;
|
||||
uint8_t *dst_addr;
|
||||
int dst_stride, src_stride;
|
||||
int rows;
|
||||
|
||||
dst_addr = CVPixelBufferGetBaseAddressOfPlane(buf, i);
|
||||
src_addr = av_frame->data[i];
|
||||
dst_stride = CVPixelBufferGetBytesPerRowOfPlane(buf, i);
|
||||
src_stride = av_frame->linesize[i];
|
||||
rows = CVPixelBufferGetHeightOfPlane(buf, i);
|
||||
|
||||
if (dst_stride == src_stride)
|
||||
{
|
||||
memcpy(dst_addr, src_addr, src_stride * rows);
|
||||
} else {
|
||||
int copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
|
||||
for (int j = 0; j < rows; j++)
|
||||
{
|
||||
memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
CVPixelBufferUnlockBaseAddress(buf, 0);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
-(void)removeInputQueueAtIndexes:(NSIndexSet *)indexes
|
||||
{
|
||||
[self.inputQueue removeObjectsAtIndexes:indexes];
|
||||
if (self.queueStateChanged)
|
||||
{
|
||||
self.queueStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
28
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/Info.plist
Normal file
28
CSFFMpegCapturePlugin/CSFFMpegCapturePlugin/Info.plist
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?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>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Zakk. All rights reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>CSFFMpegCapture</string>
|
||||
</dict>
|
||||
</plist>
|
||||
6
CSFFMpegCapturePlugin/Media.xcassets/Contents.json
Normal file
6
CSFFMpegCapturePlugin/Media.xcassets/Contents.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
21
CSFFMpegCapturePlugin/Media.xcassets/fastforward.imageset/Contents.json
vendored
Normal file
21
CSFFMpegCapturePlugin/Media.xcassets/fastforward.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "fastforward.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
CSFFMpegCapturePlugin/Media.xcassets/fastforward.imageset/fastforward.png
vendored
Normal file
BIN
CSFFMpegCapturePlugin/Media.xcassets/fastforward.imageset/fastforward.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
21
CSFFMpegCapturePlugin/Media.xcassets/pause.imageset/Contents.json
vendored
Normal file
21
CSFFMpegCapturePlugin/Media.xcassets/pause.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "pause.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
CSFFMpegCapturePlugin/Media.xcassets/pause.imageset/pause.png
vendored
Normal file
BIN
CSFFMpegCapturePlugin/Media.xcassets/pause.imageset/pause.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 667 B |
21
CSFFMpegCapturePlugin/Media.xcassets/play.imageset/Contents.json
vendored
Normal file
21
CSFFMpegCapturePlugin/Media.xcassets/play.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "play.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
CSFFMpegCapturePlugin/Media.xcassets/play.imageset/play.png
vendored
Normal file
BIN
CSFFMpegCapturePlugin/Media.xcassets/play.imageset/play.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
21
CSFFMpegCapturePlugin/Media.xcassets/rewind.imageset/Contents.json
vendored
Normal file
21
CSFFMpegCapturePlugin/Media.xcassets/rewind.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "rewind.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
CSFFMpegCapturePlugin/Media.xcassets/rewind.imageset/rewind.png
vendored
Normal file
BIN
CSFFMpegCapturePlugin/Media.xcassets/rewind.imageset/rewind.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
NSString *const CSNotificationLayoutAdded = @"CSNotificationLayoutAdded";
|
||||
NSString *const CSNotificationLayoutDeleted = @"CSNotificationLayoutDeleted";
|
||||
|
||||
NSString *const CSNotificationLayoutCanvasChanged = @"CSNotificationLayoutCanvasChanged";
|
||||
NSString *const CSNotificationLayoutFramerateChanged = @"CSNotificationLayoutFramerateChanged";
|
||||
|
||||
|
||||
|
||||
|
|
@ -22,7 +23,9 @@ NSString *const CSNotificationOutputDeleted = @"CSNotificationOutputDeleted";
|
|||
|
||||
|
||||
NSString *const CSNotificationCompressorAdded = @"CSNotificationCompressorAdded";
|
||||
NSString *const CSNotificationCompressorDeleted = @"CSNotificationCompressorDeleted";
|
||||
NSString *const CSNotificationCompressorDeleted = @"CSNotificationCompressorDeleted";
|
||||
NSString *const CSNotificationCompressorRenamed = @"CSNotificationCompressorRenamed";
|
||||
NSString *const CSNotificationCompressorReconfigured = @"CSNotificationCompressorReconfigured";
|
||||
|
||||
|
||||
NSString *const CSNotificationInputAdded = @"CSNotificationInputAdded";
|
||||
|
|
@ -30,5 +33,9 @@ NSString *const CSNotificationInputDeleted = @"CSNotificationInputDeleted";
|
|||
|
||||
NSString *const CSNotificationInputSelected = @"CSNotificationInputSelected";
|
||||
|
||||
NSString *const CSNotificationInputAttached = @"CSNotificationInputAttached";
|
||||
NSString *const CSNotificationInputDetached = @"CSNotificationInputDetached";
|
||||
|
||||
NSString *const CSNotificationLayoutModeChanged = @"CSNotificationLayoutModeChanged";
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
<<<<<<< HEAD
|
||||
LastUpgradeVersion = "0700"
|
||||
=======
|
||||
LastUpgradeVersion = "0730"
|
||||
>>>>>>> 2.0UI
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
<<<<<<< HEAD
|
||||
LastUpgradeVersion = "0700"
|
||||
=======
|
||||
LastUpgradeVersion = "0730"
|
||||
>>>>>>> 2.0UI
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0640"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0640"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AFC1FE19B04F700007C07B"
|
||||
BuildableName = "CSAVFCapturePlugin.bundle"
|
||||
BlueprintName = "CSAVFCapturePlugin"
|
||||
ReferencedContainer = "container:CSAVFCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -233,6 +233,7 @@
|
|||
|
||||
[_capture_session registerOutput:self];
|
||||
|
||||
|
||||
self.captureName = newDev.captureName;
|
||||
|
||||
self.videoFormats = _selectedVideoCaptureDevice.formats;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34F7C54F1B2C908700345230"
|
||||
BuildableName = "CSDeckLinkCapturePlugin.bundle"
|
||||
BlueprintName = "CSDeckLinkCapturePlugin"
|
||||
ReferencedContainer = "container:CSDeckLinkCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34F7C54F1B2C908700345230"
|
||||
BuildableName = "CSDeckLinkCapturePlugin.bundle"
|
||||
BlueprintName = "CSDeckLinkCapturePlugin"
|
||||
ReferencedContainer = "container:CSDeckLinkCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34F7C54F1B2C908700345230"
|
||||
BuildableName = "CSDeckLinkCapturePlugin.bundle"
|
||||
BlueprintName = "CSDeckLinkCapturePlugin"
|
||||
ReferencedContainer = "container:CSDeckLinkCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>CSDeckLinkCapturePlugin.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>21</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>34F7C54F1B2C908700345230</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -137,6 +137,7 @@
|
|||
|
||||
if (activeVideoDevice)
|
||||
{
|
||||
|
||||
CSDeckLinkWrapper *devWrapper = activeVideoDevice.captureDevice;
|
||||
IDeckLink *deckLink = devWrapper.deckLink;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CSDeckLinkCaptureViewController">
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <OpenGL/gl.h>
|
||||
|
||||
#import "DeckLinkBridge.h"
|
||||
|
||||
|
||||
|
|
@ -16,7 +17,7 @@
|
|||
{
|
||||
CGLContextObj _myCGLContext;
|
||||
CGRect _lastBounds;
|
||||
CGSize _lastImageSize;
|
||||
NSRect _lastImageSize;
|
||||
CGRect _privateCropRect;
|
||||
CGRect _lastCrop;
|
||||
CGRect _calculatedCrop;
|
||||
|
|
|
|||
|
|
@ -25,20 +25,15 @@
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
-(void)setContentsRect:(CGRect)contentsRect
|
||||
{
|
||||
_privateCropRect = contentsRect;
|
||||
[self calculateCrop:_lastImageSize];
|
||||
_needsRedraw = YES;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
-(CGRect)contentsRect
|
||||
{
|
||||
return _privateCropRect;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
-(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pf
|
||||
|
|
@ -86,16 +81,23 @@
|
|||
|
||||
|
||||
NSSize useSize = self.bounds.size;
|
||||
CGRect newCrop;
|
||||
|
||||
newCrop.origin.x = _deckLinkFrameSize.width * _privateCropRect.origin.x;
|
||||
newCrop.origin.y = _deckLinkFrameSize.height * _privateCropRect.origin.y;
|
||||
newCrop.size.width = _deckLinkFrameSize.width * _privateCropRect.size.width;
|
||||
newCrop.size.height = _deckLinkFrameSize.height * _privateCropRect.size.height;
|
||||
|
||||
if ([self.contentsGravity isEqualToString:kCAGravityResizeAspect])
|
||||
{
|
||||
float wr = _deckLinkFrameSize.width / self.bounds.size.width;
|
||||
float hr = _deckLinkFrameSize.height / self.bounds.size.height;
|
||||
float wr = newCrop.size.width / self.bounds.size.width;
|
||||
float hr = newCrop.size.height / self.bounds.size.height;
|
||||
|
||||
float ratio = (hr < wr ? wr : hr);
|
||||
useSize = NSMakeSize(_deckLinkFrameSize.width / ratio, _deckLinkFrameSize.height / ratio);
|
||||
useSize = NSMakeSize(newCrop.size.width / ratio, newCrop.size.height / ratio);
|
||||
}
|
||||
|
||||
|
||||
GLint vpx = (self.bounds.size.width - useSize.width)/2;
|
||||
GLint vpy = (self.bounds.size.height - useSize.height)/2;
|
||||
|
||||
|
|
@ -104,19 +106,29 @@
|
|||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
|
||||
NSRect cropRect;
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
|
||||
|
||||
GLfloat yt = 1.0 - (_privateCropRect.origin.y + _privateCropRect.size.height);
|
||||
|
||||
|
||||
glScalef(_privateCropRect.size.width, _privateCropRect.size.height, 1);
|
||||
glTranslatef(_privateCropRect.origin.x * _deckLinkFrameSize.width, yt * _deckLinkFrameSize.height, 0);
|
||||
|
||||
|
||||
|
||||
if (_deckLinkOGL)
|
||||
{
|
||||
_deckLinkOGL->PaintGL();
|
||||
}
|
||||
|
||||
/*
|
||||
glTranslated(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5, 0.0);
|
||||
*/
|
||||
|
||||
|
||||
[super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -85,6 +85,12 @@
|
|||
}
|
||||
|
||||
|
||||
-(NSImage *)libraryImage
|
||||
{
|
||||
return [NSImage imageNamed:NSImageNameComputer];
|
||||
}
|
||||
|
||||
|
||||
-(void)frameTick
|
||||
{
|
||||
|
||||
|
|
@ -245,6 +251,7 @@
|
|||
_displayStreamRef = CGDisplayStreamCreateWithDispatchQueue(self.currentDisplay, width, height, kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, (__bridge CFDictionaryRef)(opts), _capture_queue, ^(CGDisplayStreamFrameStatus status, uint64_t displayTime, IOSurfaceRef frameSurface, CGDisplayStreamUpdateRef updateRef) {
|
||||
|
||||
|
||||
|
||||
CFAbsoluteTime nowTime = CFAbsoluteTimeGetCurrent();
|
||||
_lastFrame = nowTime;
|
||||
|
||||
|
|
@ -406,6 +413,7 @@
|
|||
|
||||
-(void)dealloc
|
||||
{
|
||||
|
||||
[self removeObserver:self forKeyPath:@"propertiesChanged"];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -86,11 +86,25 @@
|
|||
} else if (_animation) {
|
||||
[newLayer addAnimation:_animation forKey:@"contents"];
|
||||
}
|
||||
|
||||
newLayer.minificationFilter = kCAFilterTrilinear;
|
||||
newLayer.magnificationFilter = kCAFilterTrilinear;
|
||||
|
||||
return newLayer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(NSImage *)libraryImage
|
||||
{
|
||||
if (self.imagePath)
|
||||
{
|
||||
return [[NSImage alloc] initWithContentsOfFile:self.imagePath];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
-(NSString *)imagePath
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#import "MovieCapture.h"
|
||||
|
||||
extern void av_register_all();
|
||||
|
||||
|
||||
void tapInit(MTAudioProcessingTapRef tap, void *clientInfo, void **tapStorageOut) {
|
||||
*tapStorageOut = clientInfo;
|
||||
|
|
@ -117,6 +119,8 @@ void tapProcess(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioPr
|
|||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
|
||||
|
||||
self.repeat = kCSMovieRepeatNone;
|
||||
|
||||
_currentMovieTime = 0.0f;
|
||||
|
|
@ -140,6 +144,9 @@ void tapProcess(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioPr
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-(void)frameTick
|
||||
{
|
||||
|
||||
|
|
@ -200,7 +207,7 @@ void tapProcess(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioPr
|
|||
{
|
||||
AudioStreamBasicDescription asbd = _bufferPCM.pcmFormat;
|
||||
|
||||
[self registerPCMOutput:_bufferPCM.frameCount audioFormat:&asbd];
|
||||
[self registerPCMOutput:1024 audioFormat:&asbd];
|
||||
} else {
|
||||
[self deregisterPCMOutput];
|
||||
}
|
||||
|
|
@ -352,7 +359,7 @@ void tapProcess(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioPr
|
|||
|
||||
-(void) setCurrentMovieTime:(double)time
|
||||
{
|
||||
[_avPlayer seekToTime:CMTimeMakeWithSeconds(time, 1)];
|
||||
[_avPlayer seekToTime:CMTimeMakeWithSeconds(time, 1000)];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -589,9 +596,11 @@ void tapProcess(MTAudioProcessingTapRef tap, CMItemCount numberFrames, MTAudioPr
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+(NSString *)label
|
||||
{
|
||||
return @"Movie";
|
||||
return @"AppleMovie";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="MovieCaptureViewController">
|
||||
|
|
@ -71,12 +71,12 @@
|
|||
</textField>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="16" horizontalPageScroll="10" verticalLineScroll="16" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tAh-bu-KEx">
|
||||
<rect key="frame" x="75" y="23" width="437" height="135"/>
|
||||
<clipView key="contentView" misplaced="YES" id="gdK-lO-BG6">
|
||||
<rect key="frame" x="1" y="1" width="452" height="133"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="gdK-lO-BG6">
|
||||
<rect key="frame" x="1" y="1" width="435" height="133"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" autosaveColumns="NO" rowHeight="14" id="qOx-dl-WXI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="452" height="16"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="435" height="133"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
|
|
@ -108,9 +108,11 @@
|
|||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="896-9n-obg">
|
||||
<rect key="frame" x="-7" y="-14" width="0.0" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="rYi-gP-FPw">
|
||||
<rect key="frame" x="-14" y="-7" width="15" height="0.0"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
|
|
@ -162,8 +164,8 @@
|
|||
</popUpButtonCell>
|
||||
<connections>
|
||||
<binding destination="1ve-hK-YuQ" name="content" keyPath="arrangedObjects" id="PCN-JM-6fZ"/>
|
||||
<binding destination="1ve-hK-YuQ" name="contentObjects" keyPath="arrangedObjects.value" previousBinding="PCN-JM-6fZ" id="04C-pZ-lQ4"/>
|
||||
<binding destination="1ve-hK-YuQ" name="contentValues" keyPath="arrangedObjects.key" previousBinding="04C-pZ-lQ4" id="c9n-te-ZJW"/>
|
||||
<binding destination="1ve-hK-YuQ" name="contentObjects" keyPath="arrangedObjects.value" previousBinding="PCN-JM-6fZ" id="04C-pZ-lQ4"/>
|
||||
<binding destination="zML-fQ-s12" name="selectedObject" keyPath="selection.repeat" previousBinding="c9n-te-ZJW" id="pA4-W2-b9T"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
|
|
@ -201,8 +203,8 @@
|
|||
</arrayController>
|
||||
<dictionaryController objectClassName="_NSControllerKeyValuePair" id="1ve-hK-YuQ" userLabel="repeatTypeController">
|
||||
<connections>
|
||||
<binding destination="-2" name="contentDictionary" keyPath="self.repeatTypeMap" id="iJm-hw-bLq"/>
|
||||
<binding destination="-2" name="sortDescriptors" keyPath="self.repeatSortDescriptors" id="rep-8X-7z7"/>
|
||||
<binding destination="-2" name="contentDictionary" keyPath="self.repeatTypeMap" id="iJm-hw-bLq"/>
|
||||
</connections>
|
||||
</dictionaryController>
|
||||
</objects>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34D2D58E1A54857C001004E5"
|
||||
BuildableName = "CSNowPlayingPlugin.bundle"
|
||||
BlueprintName = "CSNowPlayingPlugin"
|
||||
ReferencedContainer = "container:CSNowPlayingPlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34D2D58E1A54857C001004E5"
|
||||
BuildableName = "CSNowPlayingPlugin.bundle"
|
||||
BlueprintName = "CSNowPlayingPlugin"
|
||||
ReferencedContainer = "container:CSNowPlayingPlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34D2D58E1A54857C001004E5"
|
||||
BuildableName = "CSNowPlayingPlugin.bundle"
|
||||
BlueprintName = "CSNowPlayingPlugin"
|
||||
ReferencedContainer = "container:CSNowPlayingPlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>CSNowPlayingPlugin.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>23</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>34D2D58E1A54857C001004E5</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
343692431B6236DF007EC2D9 /* CSShapeCaptureFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 343692421B6236DF007EC2D9 /* CSShapeCaptureFactory.m */; };
|
||||
3436924C1B6238C6007EC2D9 /* CSShapeCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 3436924B1B6238C6007EC2D9 /* CSShapeCapture.m */; };
|
||||
343692641B63891C007EC2D9 /* CSShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 343692631B63891C007EC2D9 /* CSShapeLayer.m */; };
|
||||
3470CD3C1D6085AE006404D9 /* rectangle.py in Resources */ = {isa = PBXBuildFile; fileRef = 3470CD3B1D6085AE006404D9 /* rectangle.py */; };
|
||||
3470CD3D1D6085DB006404D9 /* rectangle.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3470CD3B1D6085AE006404D9 /* rectangle.py */; };
|
||||
34E3010A1B64A39E000C16DB /* CSShapeCaptureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E301081B64A39E000C16DB /* CSShapeCaptureViewController.m */; };
|
||||
34E3010B1B64A39E000C16DB /* CSShapeCaptureViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34E301091B64A39E000C16DB /* CSShapeCaptureViewController.xib */; };
|
||||
34E301141B6515C9000C16DB /* circle.py in CopyFiles */ = {isa = PBXBuildFile; fileRef = 34E3010D1B6514F9000C16DB /* circle.py */; };
|
||||
|
|
@ -37,8 +39,9 @@
|
|||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = Paths;
|
||||
dstSubfolderSpec = 13;
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
3470CD3D1D6085DB006404D9 /* rectangle.py in CopyFiles */,
|
||||
34F2FF2B1B8AAAC1000B5964 /* arc.py in CopyFiles */,
|
||||
34E301141B6515C9000C16DB /* circle.py in CopyFiles */,
|
||||
34E301151B6515C9000C16DB /* triangle.py in CopyFiles */,
|
||||
|
|
@ -72,6 +75,7 @@
|
|||
3436925F1B638382007EC2D9 /* CSShapePathLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CSShapePathLoader.h; sourceTree = "<group>"; };
|
||||
343692621B63891C007EC2D9 /* CSShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSShapeLayer.h; sourceTree = "<group>"; };
|
||||
343692631B63891C007EC2D9 /* CSShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSShapeLayer.m; sourceTree = "<group>"; };
|
||||
3470CD3B1D6085AE006404D9 /* rectangle.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = rectangle.py; sourceTree = "<group>"; };
|
||||
34E301071B64A39E000C16DB /* CSShapeCaptureViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSShapeCaptureViewController.h; sourceTree = "<group>"; };
|
||||
34E301081B64A39E000C16DB /* CSShapeCaptureViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSShapeCaptureViewController.m; sourceTree = "<group>"; };
|
||||
34E301091B64A39E000C16DB /* CSShapeCaptureViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CSShapeCaptureViewController.xib; sourceTree = "<group>"; };
|
||||
|
|
@ -179,6 +183,7 @@
|
|||
34E3010F1B651515000C16DB /* triangle.py */,
|
||||
34E301111B65153A000C16DB /* rtriangle.py */,
|
||||
34F2FF291B8AA717000B5964 /* arc.py */,
|
||||
3470CD3B1D6085AE006404D9 /* rectangle.py */,
|
||||
);
|
||||
name = ShapePaths;
|
||||
path = CSShapeCapturePlugin/ShapePaths;
|
||||
|
|
@ -243,6 +248,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
34E3010B1B64A39E000C16DB /* CSShapeCaptureViewController.xib in Resources */,
|
||||
3470CD3C1D6085AE006404D9 /* rectangle.py in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "343692101B62364E007EC2D9"
|
||||
BuildableName = "CSShapeCapturePlugin.bundle"
|
||||
BlueprintName = "CSShapeCapturePlugin"
|
||||
ReferencedContainer = "container:CSShapeCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "343692101B62364E007EC2D9"
|
||||
BuildableName = "CSShapeCapturePlugin.bundle"
|
||||
BlueprintName = "CSShapeCapturePlugin"
|
||||
ReferencedContainer = "container:CSShapeCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "343692101B62364E007EC2D9"
|
||||
BuildableName = "CSShapeCapturePlugin.bundle"
|
||||
BlueprintName = "CSShapeCapturePlugin"
|
||||
ReferencedContainer = "container:CSShapeCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>CSShapeCapturePlugin.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>20</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>343692101B62364E007EC2D9</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -16,7 +16,7 @@ plugin_base = PluginBase(package='shapeplugins')
|
|||
|
||||
library_dirs = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask - NSSystemDomainMask, YES)
|
||||
plugin_dirs = map(lambda x: x + "/Application Support/CocoaSplit/Plugins/Paths", library_dirs)
|
||||
plugin_dirs.append(NSBundle.bundleForClass_(objc.lookUpClass("CSShapeCapture").class__()).builtInPlugInsPath() + "/Paths")
|
||||
plugin_dirs.append(NSBundle.bundleForClass_(objc.lookUpClass("CSShapeCapture").class__()).resourcePath() + "/Paths")
|
||||
plugin_source = plugin_base.make_plugin_source(searchpath=plugin_dirs)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
from Quartz import CGPathCreateMutable, CGPathAddRect
|
||||
|
||||
name = "Rectangle"
|
||||
|
||||
def create_cgpath(frame):
|
||||
newpath = CGPathCreateMutable()
|
||||
CGPathAddRect(newpath, None, frame)
|
||||
return newpath
|
||||
|
|
@ -9,13 +9,13 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
3429A0491A41063900EE702C /* CSSyphonInjectCaptureViewNotInstalled.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3429A0481A41063900EE702C /* CSSyphonInjectCaptureViewNotInstalled.xib */; };
|
||||
3479A99A1A91C5A500A524F0 /* CSSyphonCaptureLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3479A9991A91C5A500A524F0 /* CSSyphonCaptureLayer.m */; };
|
||||
349CA6A71BC04D1B0010678D /* Syphon.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 34C67B4A1A2A4D870012DC1B /* Syphon.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
34AFC1D719B04EB90007C07B /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34AFC1D619B04EB90007C07B /* Cocoa.framework */; };
|
||||
34AFC1E119B04EB90007C07B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 34AFC1DF19B04EB90007C07B /* InfoPlist.strings */; };
|
||||
34AFC1F319B04F0B0007C07B /* SyphonCaptureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AFC1EF19B04F0B0007C07B /* SyphonCaptureViewController.m */; };
|
||||
34AFC1F419B04F0B0007C07B /* SyphonCaptureViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 34AFC1F019B04F0B0007C07B /* SyphonCaptureViewController.xib */; };
|
||||
34AFC1F519B04F0B0007C07B /* SyphonCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 34AFC1F219B04F0B0007C07B /* SyphonCapture.m */; };
|
||||
34C67B4F1A2A56A20012DC1B /* Syphon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34C67B4A1A2A4D870012DC1B /* Syphon.framework */; };
|
||||
34C67B4E1A2A4ECB0012DC1B /* Syphon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34C67B4A1A2A4D870012DC1B /* Syphon.framework */; };
|
||||
34C67B4F1A2A56A20012DC1B /* Syphon.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 34C67B4A1A2A4D870012DC1B /* Syphon.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
34C7B8C91A344DB20033AC71 /* CSSyphonInjectCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C7B8C81A344DB20033AC71 /* CSSyphonInjectCapture.m */; };
|
||||
34C7B8CC1A34621C0033AC71 /* CSSyphonCaptureFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C7B8CB1A34621C0033AC71 /* CSSyphonCaptureFactory.m */; };
|
||||
34C7B8DB1A3465010033AC71 /* CSSyphonInjectCaptureViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34C7B8D91A3465010033AC71 /* CSSyphonInjectCaptureViewController.m */; };
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
349CA6A71BC04D1B0010678D /* Syphon.framework in CopyFiles */,
|
||||
34C67B4F1A2A56A20012DC1B /* Syphon.framework in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -101,7 +101,7 @@
|
|||
files = (
|
||||
34C7B8DE1A3562400033AC71 /* ScriptingBridge.framework in Frameworks */,
|
||||
34AFC1D719B04EB90007C07B /* Cocoa.framework in Frameworks */,
|
||||
34C67B4F1A2A56A20012DC1B /* Syphon.framework in Frameworks */,
|
||||
34C67B4E1A2A4ECB0012DC1B /* Syphon.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 01b144811f6f7080b70b2d7cc729da071f86f9d7
|
||||
Subproject commit ead4c1f9790a9ba3285858bc67dceaee985605aa
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -61,6 +61,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
-(NSImage *)libraryImage
|
||||
{
|
||||
NSString *calPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"com.apple.iCal"];
|
||||
|
||||
if (calPath)
|
||||
{
|
||||
return [[NSWorkspace sharedWorkspace] iconForFile:calPath];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+(NSString *)label
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34FDA7FC1A84BF9300E7F65E"
|
||||
BuildableName = "CSTimeCapturePlugin.bundle"
|
||||
BlueprintName = "CSTimeCapturePlugin"
|
||||
ReferencedContainer = "container:CSTimeCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34FDA7FC1A84BF9300E7F65E"
|
||||
BuildableName = "CSTimeCapturePlugin.bundle"
|
||||
BlueprintName = "CSTimeCapturePlugin"
|
||||
ReferencedContainer = "container:CSTimeCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34FDA7FC1A84BF9300E7F65E"
|
||||
BuildableName = "CSTimeCapturePlugin.bundle"
|
||||
BlueprintName = "CSTimeCapturePlugin"
|
||||
ReferencedContainer = "container:CSTimeCapturePlugin.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>CSTimeCapturePlugin.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>22</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>34FDA7FC1A84BF9300E7F65E</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -58,6 +58,18 @@
|
|||
}
|
||||
|
||||
|
||||
-(NSImage *)libraryImage
|
||||
{
|
||||
NSString *calPath = [[NSWorkspace sharedWorkspace] absolutePathForAppBundleWithIdentifier:@"com.apple.iCal"];
|
||||
|
||||
if (calPath)
|
||||
{
|
||||
return [[NSWorkspace sharedWorkspace] iconForFile:calPath];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
-(void)setFormat:(NSString *)format
|
||||
{
|
||||
_format = format;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,35 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
|
||||
-(void)encodeWithCoder:(NSCoder *)aCoder
|
||||
{
|
||||
[super encodeWithCoder:aCoder];
|
||||
[aCoder encodeFloat:self.captureFPS forKey:@"captureFPS"];
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(id) initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
if (self = [super initWithCoder:aDecoder])
|
||||
{
|
||||
self.captureFPS = [aDecoder decodeFloatForKey:@"captureFPS"];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
-(CALayer *)createNewLayer
|
||||
{
|
||||
CALayer *newLayer = [super createNewLayer];
|
||||
newLayer.minificationFilter = kCAFilterTrilinear;
|
||||
newLayer.magnificationFilter = kCAFilterTrilinear;
|
||||
return newLayer;
|
||||
}
|
||||
|
||||
|
||||
-(NSArray *) availableVideoDevices
|
||||
{
|
||||
NSArray *windows = CFBridgingRelease(CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly|kCGWindowListExcludeDesktopElements, kCGNullWindowID));
|
||||
|
|
@ -81,12 +110,15 @@
|
|||
NSNumber *windowID = self.activeVideoDevice.captureDevice;
|
||||
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
|
||||
CGImageRef windowImg = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, [windowID unsignedIntValue], kCGWindowImageBoundsIgnoreFraming|kCGWindowImageBestResolution);
|
||||
[self updateLayersWithBlock:^(CALayer *layer) {
|
||||
|
||||
layer.contents = (__bridge id)(windowImg);
|
||||
}];
|
||||
CGImageRelease(windowImg);
|
||||
});
|
||||
|
||||
_nextCaptureTime = currentTime + (1/self.captureFPS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6250" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="8191" systemVersion="15B42" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6250"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="8191"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="WindowCaptureViewController">
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="B9K-hI-eIC">
|
||||
<rect key="frame" x="-2" y="30" width="480" height="68"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" id="1ti-or-XeN">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<string key="title">This capture method sucks. The API for grabbing window images really isn't made for video framerates and depending on what window you are capturing it can't keep up. Set the framerate for the source low if you can get away with it. Otherwise expect to drop lots of frames.</string>
|
||||
|
|
@ -27,6 +28,7 @@
|
|||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hjq-Aj-7hP">
|
||||
<rect key="frame" x="-2" y="5" width="38" height="14"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="FPS" id="GjO-zf-D4C">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
|
@ -35,6 +37,7 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UNk-IL-Bxf">
|
||||
<rect key="frame" x="42" y="3" width="43" height="19"/>
|
||||
<animations/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="Sz5-tw-4zZ">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
|
@ -45,6 +48,7 @@
|
|||
</connections>
|
||||
</textField>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<point key="canvasLocation" x="479" y="306"/>
|
||||
</customView>
|
||||
<objectController id="2Rc-rP-Ag7" userLabel="WindowCaptureController">
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
7
CocoaSplit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
CocoaSplit.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "2F75B324D6E95041E8A2E2A8BC21974740F08BF7",
|
||||
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
|
||||
|
||||
},
|
||||
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
|
||||
"2F75B324D6E95041E8A2E2A8BC21974740F08BF7" : 0,
|
||||
"7360F7D45D6592BBC0CCBB41E9FC383DA90D4985" : 0
|
||||
},
|
||||
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "E6022B3D-C90B-4603-869E-23206BED5F1F",
|
||||
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
|
||||
"2F75B324D6E95041E8A2E2A8BC21974740F08BF7" : "CocoaSplit\/",
|
||||
"7360F7D45D6592BBC0CCBB41E9FC383DA90D4985" : "CocoaSplit\/CapturePlugins\/CSSyphonCapturePlugin\/Syphon-Framework\/"
|
||||
},
|
||||
"DVTSourceControlWorkspaceBlueprintNameKey" : "CocoaSplit",
|
||||
"DVTSourceControlWorkspaceBlueprintVersion" : 204,
|
||||
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "CocoaSplit.xcodeproj",
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
|
||||
{
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zakk4223\/CocoaSplit.git",
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "2F75B324D6E95041E8A2E2A8BC21974740F08BF7"
|
||||
},
|
||||
{
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/palana\/Syphon-Framework.git",
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
|
||||
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "7360F7D45D6592BBC0CCBB41E9FC383DA90D4985"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
CocoaSplit.xcodeproj/project.xcworkspace/xcuserdata/zakk.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
BIN
CocoaSplit.xcodeproj/project.xcworkspace/xcuserdata/zakk.xcuserdatad/UserInterfaceState.xcuserstate
generated
Normal file
Binary file not shown.
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
scope = "0"
|
||||
stopOnStyle = "0">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "340FE49C15F3417E00E4CE4E"
|
||||
BuildableName = "CocoaSplit.app"
|
||||
BlueprintName = "CocoaSplit"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "340FE49C15F3417E00E4CE4E"
|
||||
BuildableName = "CocoaSplit.app"
|
||||
BlueprintName = "CocoaSplit"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "340FE49C15F3417E00E4CE4E"
|
||||
BuildableName = "CocoaSplit.app"
|
||||
BlueprintName = "CocoaSplit"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "-NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints YES"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "340FE49C15F3417E00E4CE4E"
|
||||
BuildableName = "CocoaSplit.app"
|
||||
BlueprintName = "CocoaSplit"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "3451A1C217111BD900DF6A8B"
|
||||
BuildableName = "CocoaSplitCmd"
|
||||
BlueprintName = "CocoaSplitCmd"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "3451A1C217111BD900DF6A8B"
|
||||
BuildableName = "CocoaSplitCmd"
|
||||
BlueprintName = "CocoaSplitCmd"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "3451A1C217111BD900DF6A8B"
|
||||
BuildableName = "CocoaSplitCmd"
|
||||
BlueprintName = "CocoaSplitCmd"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "3451A1C217111BD900DF6A8B"
|
||||
BuildableName = "CocoaSplitCmd"
|
||||
BlueprintName = "CocoaSplitCmd"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0730"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AE3C2D164E3E020052C95E"
|
||||
BuildableName = "zakk.lol.QTCaptureHelper.xpc"
|
||||
BlueprintName = "QTCaptureHelper"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AE3C2D164E3E020052C95E"
|
||||
BuildableName = "zakk.lol.QTCaptureHelper.xpc"
|
||||
BlueprintName = "QTCaptureHelper"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "34AE3C2D164E3E020052C95E"
|
||||
BuildableName = "zakk.lol.QTCaptureHelper.xpc"
|
||||
BlueprintName = "QTCaptureHelper"
|
||||
ReferencedContainer = "container:CocoaSplit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?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>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>CocoaSplit.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>14</integer>
|
||||
</dict>
|
||||
<key>CocoaSplitCmd.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>16</integer>
|
||||
</dict>
|
||||
<key>QTCaptureHelper.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>15</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>340FE49C15F3417E00E4CE4E</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>3451A1C217111BD900DF6A8B</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>34AE3C2D164E3E020052C95E</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
CocoaSplit/.DS_Store
vendored
Normal file
BIN
CocoaSplit/.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
@class CAMultiAudioPCMPlayer;
|
||||
|
||||
@class CaptureController;
|
||||
|
||||
@interface AVFAudioCapture : CSCaptureBase <CSCaptureSourceProtocol, AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate>
|
||||
{
|
||||
|
|
@ -29,7 +28,6 @@
|
|||
|
||||
|
||||
@property (strong) AVFChannelManager *audioChannelManager;
|
||||
@property (strong) CaptureController *audioDelegate;
|
||||
@property (assign) int audioBitrate;
|
||||
@property (assign) float audioSamplerate;
|
||||
@property (strong) AVCaptureDevice *activeAudioDevice;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#import "AVFAudioCapture.h"
|
||||
#import "CAMultiAudioPCMPlayer.h"
|
||||
#import "CaptureController.h"
|
||||
|
||||
|
||||
@implementation AVFAudioCapture
|
||||
|
|
@ -281,10 +280,6 @@
|
|||
|
||||
if (connection.output == _audio_capture_output) {
|
||||
|
||||
if (!self.useAudioEngine && self.audioDelegate)
|
||||
{
|
||||
[_audioDelegate captureOutputAudio:self didOutputSampleBuffer:sampleBuffer];
|
||||
} else {
|
||||
|
||||
if (self.multiInput)
|
||||
{
|
||||
|
|
@ -293,9 +288,6 @@
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from Foundation import NSLog
|
||||
|
||||
animation_name = "RotateDemo"
|
||||
animation_description = "Rotate demo"
|
||||
|
||||
|
|
@ -7,6 +9,7 @@ animation_params = ["degrees"]
|
|||
|
||||
def do_animation(inputs, duration):
|
||||
|
||||
NSLog("RUNNING ANIMATION")
|
||||
source1 = inputs['source1']
|
||||
source2 = inputs['source2']
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <QTKit/QTKit.h>
|
||||
#import "CaptureController.h"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
-(instancetype)initWithDevice:(AVCaptureDevice *)avDevice withFormat:(AudioStreamBasicDescription *)withFormat;
|
||||
|
||||
-(void)resetFormat:(AudioStreamBasicDescription *)format;
|
||||
-(const AudioStreamBasicDescription *)deviceAudioDescription;
|
||||
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@
|
|||
{
|
||||
UInt32 enableVal = 1;
|
||||
OSStatus err;
|
||||
err = AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_MeteringMode, kAudioUnitScope_Input, bus, &enableVal, sizeof(enableVal));
|
||||
//err = AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_MeteringMode, kAudioUnitScope_Input, bus, &enableVal, sizeof(enableVal));
|
||||
err = AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_MeteringMode, kAudioUnitScope_Output, 0, &enableVal, sizeof(enableVal));
|
||||
|
||||
if (err)
|
||||
{
|
||||
|
|
@ -71,7 +72,9 @@
|
|||
Float32 result = 0;
|
||||
OSStatus err;
|
||||
|
||||
err = AudioUnitGetParameter(self.audioUnit, kStereoMixerParam_PostAveragePower, kAudioUnitScope_Input, bus, &result);
|
||||
|
||||
//err = AudioUnitGetParameter(self.audioUnit, kStereoMixerParam_PostAveragePower, kAudioUnitScope_Input, bus, &result);
|
||||
err = AudioUnitGetParameter(self.audioUnit, kStereoMixerParam_PostAveragePower, kAudioUnitScope_Output, 0, &result);
|
||||
|
||||
|
||||
if (err)
|
||||
|
|
@ -83,6 +86,24 @@
|
|||
}
|
||||
|
||||
|
||||
-(Float32)outputPower
|
||||
{
|
||||
Float32 result = 0;
|
||||
OSStatus err;
|
||||
|
||||
|
||||
err = AudioUnitGetParameter(self.audioUnit, kStereoMixerParam_PostAveragePower, kAudioUnitScope_Output, 0, &result);
|
||||
|
||||
|
||||
if (err)
|
||||
{
|
||||
NSLog(@"GET POWER ERROR %d", err);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)setVolumeForScope:(AudioUnitScope)scope onBus:(AudioUnitElement)onBus volume:(float)volume
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@
|
|||
@property (strong) CAMultiAudioDevice *outputNode;
|
||||
@property (strong) CAMultiAudioDevice *graphOutputNode;
|
||||
@property (strong) NSArray *validSamplerates;
|
||||
|
||||
@property (assign) Float32 streamAudioPowerLevel;
|
||||
@property (assign) Float32 previewAudioPowerLevel;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -150,11 +150,27 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
|
|||
|
||||
-(void)updateStatistics
|
||||
{
|
||||
/*
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
for(CAMultiAudioNode *node in self.audioInputs)
|
||||
{
|
||||
[node updatePowerlevel];
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
float rawPreview = [self.previewMixer outputPower];
|
||||
float rawStream = [self.encodeMixer outputPower];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self.previewAudioPowerLevel = pow(10.0f, rawPreview/20.0f);
|
||||
self.streamAudioPowerLevel = pow(10.0f, rawStream/20.0f);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -440,6 +456,7 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
|
|||
|
||||
[self.graph addNode:input];
|
||||
[self attachInput:newConverter];
|
||||
|
||||
[self.graph connectNode:input toNode:newConverter sampleRate:input.inputFormat->mSampleRate];
|
||||
|
||||
}
|
||||
|
|
@ -570,6 +587,8 @@ OSStatus encoderRenderCallback( void *inRefCon, AudioUnitRenderActionFlags *ioAc
|
|||
|
||||
if (selfPtr.encoder)
|
||||
{
|
||||
|
||||
|
||||
[selfPtr.encoder enqueuePCM:ioData atTime:inTimeStamp];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,25 @@
|
|||
}
|
||||
|
||||
|
||||
-(Float32)outputPower
|
||||
{
|
||||
Float32 result = 0;
|
||||
OSStatus err;
|
||||
|
||||
|
||||
err = AudioUnitGetParameter(self.audioUnit, kStereoMixerParam_PostAveragePower, kAudioUnitScope_Output, 0, &result);
|
||||
|
||||
|
||||
if (err)
|
||||
{
|
||||
NSLog(@"GET POWER ERROR %d", err);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
-(Float32)powerForInputBus:(UInt32)bus
|
||||
{
|
||||
Float32 result = 0;
|
||||
|
|
|
|||
|
|
@ -130,15 +130,18 @@
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void)updatePowerlevel
|
||||
{
|
||||
|
||||
[self.connectedTo updatePowerlevel];
|
||||
|
||||
if ([self.connectedTo.class conformsToProtocol:@protocol(CAMultiAudioMixingProtocol)])
|
||||
{
|
||||
id<CAMultiAudioMixingProtocol>mixerNode = (id<CAMultiAudioMixingProtocol>)self.connectedTo;
|
||||
self.powerLevel = [mixerNode powerForInputBus:self.connectedToBus];
|
||||
float rawPower = [mixerNode powerForInputBus:self.connectedToBus];
|
||||
|
||||
self.powerLevel = pow(10.0f, rawPower/20.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -164,8 +167,11 @@
|
|||
{
|
||||
self.mixerWindow = [[CAMultiAudioMatrixMixerWindowController alloc] initWithAudioMixer:self.downMixer];
|
||||
[self.mixerWindow showWindow:nil];
|
||||
self.mixerWindow.window.title = self.name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)nodeConnected:(CAMultiAudioNode *)toNode onBus:(UInt32)onBus
|
||||
{
|
||||
self.connectedTo = toNode;
|
||||
|
|
@ -189,9 +195,12 @@
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
//if we're muting, save the current player volume
|
||||
if (muted == YES)
|
||||
{
|
||||
NSLog(@"NODE MUTE %d", muted);
|
||||
|
||||
_saved_volume = self.volume;
|
||||
self.volume = 0.0f;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
self.frameCount = _audioSlice->mNumberFrames;
|
||||
|
||||
self.bufferCount = streamFormat->mChannelsPerFrame;
|
||||
_alloced_buffers = NO;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
}
|
||||
|
||||
|
||||
|
||||
-(void)copyFromAudioBufferList:(AudioBufferList *)copyFrom
|
||||
{
|
||||
//Just copy the data, we already allocated the List.
|
||||
|
|
@ -91,6 +93,7 @@
|
|||
}
|
||||
_audioSlice->mBufferList = _pcmData;
|
||||
memcpy(&_pcmFormat, streamFormat, sizeof(AudioStreamBasicDescription));
|
||||
_alloced_buffers = YES;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -101,13 +104,14 @@
|
|||
|
||||
-(void)dealloc
|
||||
{
|
||||
//You better not have freed this before
|
||||
if (_alloced_buffers || self.handleFreeBuffer)
|
||||
{
|
||||
for (int i=0; i < self.bufferCount; i++)
|
||||
{
|
||||
free(_audioSlice->mBufferList->mBuffers[i].mData);
|
||||
}
|
||||
|
||||
free(_audioSlice->mBufferList);
|
||||
}
|
||||
free(_audioSlice);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,17 @@
|
|||
bool _playing;
|
||||
int _bufcnt;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@property (strong) NSString *inputUID;
|
||||
@property (weak) id converterNode;
|
||||
@property (assign) Float64 latestScheduledTime;
|
||||
@property (assign) AudioStreamBasicDescription *inputFormat;
|
||||
@property (readonly) NSUInteger pendingFrames;
|
||||
@property (nonatomic, copy) void (^completedBlock)(CAMultiAudioPCM *pcmBuffer);
|
||||
@property (strong) NSMutableArray *pauseBuffer;
|
||||
@property (assign) bool save_buffer;
|
||||
|
||||
-(void)releasePCM:(CAMultiAudioPCM *)buffer;
|
||||
-(void)scheduleBuffer:(CMSampleBufferRef)sampleBuffer;
|
||||
|
|
@ -32,6 +37,8 @@
|
|||
|
||||
|
||||
-(void)play;
|
||||
-(void)pause;
|
||||
-(void)flush;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
_bufcnt = 0;
|
||||
_inputFormat = NULL;
|
||||
self.latestScheduledTime = 0;
|
||||
_pauseBuffer = [[NSMutableArray alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
@ -41,6 +42,10 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
[self playPcmBuffer:pcmBuffer];
|
||||
}
|
||||
|
||||
-(NSUInteger)pendingFrames
|
||||
{
|
||||
return _pendingBuffers.count;
|
||||
}
|
||||
|
||||
-(bool)playPcmBuffer:(CAMultiAudioPCM *)pcmBuffer
|
||||
{
|
||||
|
|
@ -102,9 +107,10 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
|
||||
|
||||
|
||||
|
||||
dispatch_async(_pendingQueue, ^{
|
||||
|
||||
[_pendingBuffers addObject:pcmBuffer];
|
||||
[self->_pendingBuffers addObject:pcmBuffer];
|
||||
});
|
||||
|
||||
|
||||
|
|
@ -115,6 +121,21 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
return YES;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-(void)setVolume:(float)volume
|
||||
{
|
||||
super.volume = volume;
|
||||
|
||||
|
||||
if (self.converterNode)
|
||||
{
|
||||
|
||||
[(CAMultiAudioNode *)self.converterNode setVolumeOnConnectedNode];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)scheduleBuffer:(CMSampleBufferRef)sampleBuffer
|
||||
{
|
||||
|
||||
|
|
@ -155,6 +176,9 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
CMSampleBufferCopyPCMDataIntoAudioBufferList(sampleBuffer, 0, (int32_t)numSamples, sampleABL);
|
||||
CAMultiAudioPCM *pcmBuffer = [[CAMultiAudioPCM alloc] initWithAudioBufferList:sampleABL streamFormat:asbd];
|
||||
|
||||
pcmBuffer.handleFreeBuffer = YES;
|
||||
|
||||
|
||||
|
||||
|
||||
[self playPcmBuffer:pcmBuffer];
|
||||
|
|
@ -217,6 +241,22 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
}
|
||||
}
|
||||
|
||||
-(void)pause
|
||||
{
|
||||
|
||||
self.save_buffer = YES;
|
||||
[self flush];
|
||||
}
|
||||
|
||||
|
||||
-(void)flush
|
||||
{
|
||||
if (self.audioUnit)
|
||||
{
|
||||
AudioUnitReset(self.audioUnit, kAudioUnitScope_Global, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)play
|
||||
{
|
||||
|
|
@ -226,11 +266,20 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList);
|
|||
|
||||
|
||||
|
||||
|
||||
ts.mFlags = kAudioTimeStampSampleTimeValid;
|
||||
ts.mSampleTime = -1;
|
||||
err = AudioUnitSetProperty(self.audioUnit, kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &ts, sizeof(ts));
|
||||
_save_buffer = NO;
|
||||
for (CAMultiAudioPCM *buffer in self.pauseBuffer)
|
||||
{
|
||||
[self playPcmBuffer:buffer];
|
||||
}
|
||||
|
||||
[self.pauseBuffer removeAllObjects];
|
||||
}
|
||||
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
if (_inputFormat)
|
||||
|
|
@ -248,11 +297,23 @@ void BufferCompletedPlaying(void *userData, ScheduledAudioSlice *bufferList)
|
|||
CAMultiAudioPCM *pcmObj = (__bridge CAMultiAudioPCM *)(userData);
|
||||
//maybe put this on a dedicated queue?
|
||||
//why a queue? don't want to do any sort of memory/managed object operations in an audio callback.
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
//dispatch_async(dispatch_get_main_queue(), ^{
|
||||
CAMultiAudioPCMPlayer *pplayer = pcmObj.player;
|
||||
//pplayer.latestScheduledTime = pcmObj.audioSlice->mTimeStamp.mSampleTime + pcmObj.audioSlice->mNumberFrames;
|
||||
if (pplayer.completedBlock)
|
||||
{
|
||||
pplayer.completedBlock(pcmObj);
|
||||
}
|
||||
|
||||
if (pplayer.save_buffer)
|
||||
{
|
||||
[pplayer.pauseBuffer addObject:pcmObj];
|
||||
} else {
|
||||
[pplayer releasePCM:pcmObj];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//});
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CAMultiAudioMatrixMixerWindowController"/>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<customView id="c22-O7-iKe" customClass="CAMultiAudioMatrixCell">
|
||||
<rect key="frame" x="0.0" y="-1" width="17" height="148"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="17" height="148"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<slider horizontalHuggingPriority="750" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UPM-S6-sSJ">
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
-(void)setVolumeOnOutput:(float)volume;
|
||||
-(void)enableMeteringOnInputBus:(UInt32)bus;
|
||||
-(Float32)powerForInputBus:(UInt32)bus;
|
||||
-(Float32)outputPower;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import <AudioToolbox/AudioToolbox.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import "TPCircularBuffer.h"
|
||||
#import "TPCircularBuffer+AudioBufferList.h"
|
||||
|
||||
|
||||
@class CaptureController;
|
||||
|
||||
|
|
@ -24,6 +27,14 @@
|
|||
long outputSampleCount;
|
||||
CMAudioFormatDescriptionRef cmFormat;
|
||||
void *_pcmData;
|
||||
u_int64_t _last_sample_time;
|
||||
int _last_write_sample_cnt;
|
||||
TPCircularBuffer _inputBuffer;
|
||||
TPCircularBuffer _scratchBuffer;
|
||||
dispatch_source_t _dispatch_timer;
|
||||
dispatch_semaphore_t _aSemaphore;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@property (assign) bool encoderStarted;
|
||||
|
|
@ -31,8 +42,11 @@
|
|||
@property (assign) int sampleRate;
|
||||
@property (assign) int bitRate;
|
||||
@property (assign) int preallocatedBuffersize;
|
||||
@property (assign) AudioStreamBasicDescription *inputASBD;
|
||||
|
||||
-(void) enqueuePCM:(AudioBufferList *)pcmBuffer atTime:(const AudioTimeStamp *)atTime;
|
||||
-(void) setupEncoderBuffer;
|
||||
|
||||
-(void) stopEncoder;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,37 +19,32 @@
|
|||
if (self = [super init])
|
||||
{
|
||||
encoderQueue = dispatch_queue_create("CSAACEncoderQueue", NULL);
|
||||
_pcmData = NULL;
|
||||
_aSemaphore = dispatch_semaphore_create(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)preallocateBufferList:(AudioBufferList *)bufferList
|
||||
-(void)setupEncoderBuffer
|
||||
{
|
||||
//To avoid doing mallocs every cycle, the AU callback asks us to preallocate memory based on the size of the buffers it receives
|
||||
//If the size changes, we only re-allocate if it is bigger than our preallocated size. If it's smaller we
|
||||
//just "waste" the memory and leave it be.
|
||||
|
||||
int bufferSize = bufferList->mBuffers[0].mDataByteSize;
|
||||
|
||||
if (bufferSize > self.preallocatedBuffersize)
|
||||
{
|
||||
_pcmData = malloc(bufferSize*2); //Assuming deinterleaved 2-ch, so allocate enough space for both channels
|
||||
self.preallocatedBuffersize = bufferSize;
|
||||
}
|
||||
TPCircularBufferInit(&_inputBuffer, self.inputASBD->mBytesPerFrame * 4096);
|
||||
TPCircularBufferInit(&_scratchBuffer, self.inputASBD->mBytesPerFrame * 4096);
|
||||
|
||||
dispatch_async(encoderQueue, ^{[self encodeAudio];});
|
||||
}
|
||||
|
||||
|
||||
|
||||
-(void) enqueuePCM:(AudioBufferList *)pcmBuffer atTime:(const AudioTimeStamp *)atTime
|
||||
{
|
||||
TPCircularBufferCopyAudioBufferList(&_inputBuffer, pcmBuffer, atTime, kTPCircularBufferCopyAll, NULL);
|
||||
dispatch_semaphore_signal(_aSemaphore);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[self preallocateBufferList:pcmBuffer];
|
||||
|
||||
-(void)encodeAudio
|
||||
{
|
||||
|
||||
|
||||
if (!self.encoderStarted)
|
||||
|
|
@ -58,17 +53,25 @@
|
|||
self.encoderStarted = YES;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
dispatch_semaphore_wait(_aSemaphore, DISPATCH_TIME_FOREVER);
|
||||
|
||||
|
||||
|
||||
//for now assume Float32, 2 channel, non-interleaved. We have to interleave it outselves here.
|
||||
while (TPCircularBufferPeek(&_inputBuffer, NULL, self.inputASBD) >= 1024)
|
||||
{
|
||||
AudioBufferList *inBuffer = TPCircularBufferPrepareEmptyAudioBufferListWithAudioFormat(&_scratchBuffer, self.inputASBD, 1024, NULL);
|
||||
UInt32 inFrameCnt = 1024;
|
||||
AudioTimeStamp atTime;
|
||||
|
||||
AudioBuffer buffer0 = pcmBuffer->mBuffers[0];
|
||||
AudioBuffer buffer1 = pcmBuffer->mBuffers[1];
|
||||
TPCircularBufferDequeueBufferListFrames(&_inputBuffer, &inFrameCnt, inBuffer, &atTime, self.inputASBD);
|
||||
|
||||
Float32 *writebuf = malloc(inBuffer->mBuffers[0].mDataByteSize*2);
|
||||
AudioBuffer buffer0 = inBuffer->mBuffers[0];
|
||||
AudioBuffer buffer1 = inBuffer->mBuffers[1];
|
||||
Float32 *data0 = buffer0.mData;
|
||||
Float32 *data1 = buffer1.mData;
|
||||
|
||||
Float32 *writebuf = _pcmData;
|
||||
int channel_size = buffer0.mDataByteSize/sizeof(Float32);
|
||||
int i, u;
|
||||
for(i=u=0; i < channel_size; i++,u+=2)
|
||||
|
|
@ -77,57 +80,32 @@
|
|||
writebuf[u+1] = data1[i];
|
||||
}
|
||||
|
||||
@autoreleasepool {
|
||||
|
||||
|
||||
//Do the actual compression on another thread so as not to block AudioUnit callbacks
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
dispatch_async(encoderQueue, ^{
|
||||
|
||||
|
||||
|
||||
|
||||
UInt32 wrote_bytes = 0;
|
||||
UInt32 num_packets = 1;
|
||||
UInt32 outstatus = 0;
|
||||
Float32 *readbuf = _pcmData;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UInt32 bufsize = self.preallocatedBuffersize*2; //This should be equal to 2x pcmBuffer->mBuffers[0].mDataByteSize
|
||||
UInt32 bufsize = inBuffer->mBuffers[0].mDataByteSize*2;//This should be equal to 2x pcmBuffer->mBuffers[0].mDataByteSize
|
||||
|
||||
|
||||
UInt32 orig_size = bufsize;
|
||||
|
||||
|
||||
|
||||
UInt32 buffer_size = maxOutputSize;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
void *aacBuffer = malloc(maxOutputSize);
|
||||
|
||||
|
||||
OSStatus err;
|
||||
|
||||
err = AudioCodecAppendInputData(aacCodec, readbuf, &bufsize, NULL, NULL);
|
||||
|
||||
|
||||
wrote_bytes += bufsize;
|
||||
|
||||
readbuf += bufsize/sizeof(Float32);
|
||||
//reset bufsize for next loop
|
||||
bufsize = orig_size - wrote_bytes;
|
||||
err = AudioCodecAppendInputData(aacCodec, writebuf, &bufsize, NULL, NULL);
|
||||
|
||||
free(writebuf);
|
||||
AudioStreamPacketDescription packetDesc;
|
||||
|
||||
|
||||
|
|
@ -143,6 +121,7 @@
|
|||
|
||||
if (outstatus == kAudioCodecProduceOutputPacketNeedsMoreInputData)
|
||||
{
|
||||
NSLog(@"NEED MORE INPUT DATA");
|
||||
free(aacBuffer);
|
||||
break;
|
||||
}
|
||||
|
|
@ -150,8 +129,14 @@
|
|||
|
||||
if (self.encodedReceiver && buffer_size)
|
||||
{
|
||||
CMTime ptsTime = CMTimeMake(outputSampleCount, self.sampleRate);
|
||||
|
||||
|
||||
CMTime duration = CMTimeMake(1024, self.sampleRate);
|
||||
uint64_t mach_now = atTime.mHostTime;
|
||||
|
||||
double abs_pts = (double)mach_now/NSEC_PER_SEC;
|
||||
|
||||
CMTime ptsTime = CMTimeMake(abs_pts*1000, 1000);
|
||||
|
||||
CMSampleTimingInfo timeInfo;
|
||||
|
||||
|
|
@ -170,15 +155,15 @@
|
|||
CMAudioSampleBufferCreateWithPacketDescriptions(kCFAllocatorDefault, bufferRef, YES, NULL, NULL, cmFormat, 1, ptsTime, &packetDesc, &newSampleBuf);
|
||||
|
||||
|
||||
//CMAudioSampleBufferCreateReadyWithPacketDescriptions(kCFAllocatorDefault, bufferRef, cmFormat, 1, ptsTime, &packetDesc, &newSampleBuf);
|
||||
|
||||
CMSampleBufferCreateCopyWithNewTiming(kCFAllocatorDefault, newSampleBuf, 1, &timeInfo, &timingSampleBuf);
|
||||
|
||||
CFRelease(newSampleBuf);
|
||||
//The sample buffer retains the block buffer when it is handed over to it, we can release ours.
|
||||
CFRelease(bufferRef);
|
||||
|
||||
|
||||
[self.encodedReceiver captureOutputAudio:nil didOutputSampleBuffer:timingSampleBuf];
|
||||
|
||||
//Individual video compressors retain the buffer until they push it to their output, we can release it now.
|
||||
CFRelease(timingSampleBuf);
|
||||
|
||||
|
|
@ -192,20 +177,12 @@
|
|||
num_packets = 1;
|
||||
|
||||
outputSampleCount += 1024;
|
||||
if (wrote_bytes >= orig_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void) setupEncoder
|
||||
{
|
||||
//create the input format.
|
||||
|
|
|
|||
|
|
@ -8,12 +8,10 @@
|
|||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "SourceLayout.h"
|
||||
#import "CaptureController.h"
|
||||
|
||||
@interface CSAnimationChooserViewController : NSViewController <NSPopoverDelegate>
|
||||
|
||||
|
||||
@property (weak) CaptureController *controller;
|
||||
@property (weak) NSPopover *popover;
|
||||
|
||||
@property (strong) SourceLayout *sourceLayout;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
//
|
||||
|
||||
#import "CSAnimationChooserViewController.h"
|
||||
#import "CaptureController.h"
|
||||
|
||||
|
||||
@interface CSAnimationChooserViewController ()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6250" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6250"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="CSAnimationChooserViewController">
|
||||
|
|
@ -28,15 +28,15 @@
|
|||
</button>
|
||||
<scrollView fixedFrame="YES" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="E7g-X1-KBR">
|
||||
<rect key="frame" x="20" y="117" width="240" height="135"/>
|
||||
<clipView key="contentView" ambiguous="YES" misplaced="YES" id="YxO-Ik-kS6">
|
||||
<rect key="frame" x="1" y="0.0" width="238" height="134"/>
|
||||
<clipView key="contentView" ambiguous="YES" id="YxO-Ik-kS6">
|
||||
<rect key="frame" x="1" y="1" width="238" height="133"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" id="8h3-66-GPo">
|
||||
<rect key="frame" x="0.0" y="0.0" width="238" height="19"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="238" height="133"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="235" minWidth="40" maxWidth="1000" id="uvE-KP-YFs">
|
||||
|
|
@ -65,11 +65,11 @@
|
|||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="Xbw-In-gXs">
|
||||
<rect key="frame" x="1" y="118.99995851516724" width="238" height="15"/>
|
||||
<rect key="frame" x="-7" y="-14" width="0.0" height="15"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="ztZ-EN-bSu">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<rect key="frame" x="-14" y="-7" width="15" height="0.0"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
@property (strong) NSString *module_name;
|
||||
@property (strong) NSString *name;
|
||||
@property (readonly) bool onLive;
|
||||
@property (strong) NSString *uuid;
|
||||
@property (assign) NSInteger refCount;
|
||||
|
||||
|
||||
|
||||
//label -> 'whatever'
|
||||
//input -> InputSource
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sourceWasDeleted:) name:CSNotificationInputDeleted object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sourceWasAdded:) name:CSNotificationInputAdded object:nil];
|
||||
|
||||
[self createUUID];
|
||||
self.refCount = 0;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
|
@ -38,7 +39,24 @@
|
|||
|
||||
[aCoder encodeObject:self.name forKey:@"name"];
|
||||
[aCoder encodeObject:self.module_name forKey:@"module_name"];
|
||||
for (NSMutableDictionary *item in self.inputs)
|
||||
{
|
||||
if ([item[@"type"] isEqualToString:@"input"])
|
||||
{
|
||||
if (item[@"value"] && ![item[@"value"] isEqualTo:[NSNull null]])
|
||||
{
|
||||
InputSource *inp = item[@"value"];
|
||||
item[@"savedUUID"] = inp.uuid;
|
||||
//item[@"value"] = [NSNull null];
|
||||
}
|
||||
}
|
||||
}
|
||||
[aCoder encodeObject:self.inputs forKey:@"inputs"];
|
||||
|
||||
if (self.uuid)
|
||||
{
|
||||
[aCoder encodeObject:self.uuid forKey:@"uuid"];
|
||||
}
|
||||
}
|
||||
|
||||
-(instancetype)initWithCoder:(NSCoder *)aDecoder
|
||||
|
|
@ -48,12 +66,24 @@
|
|||
self.name = [aDecoder decodeObjectForKey:@"name"];
|
||||
self.module_name = [aDecoder decodeObjectForKey:@"module_name"];
|
||||
self.inputs = [aDecoder decodeObjectForKey:@"inputs"];
|
||||
if ([aDecoder containsValueForKey:@"uuid"])
|
||||
{
|
||||
self.uuid = [aDecoder decodeObjectForKey:@"uuid"];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
-(void)createUUID
|
||||
{
|
||||
CFUUIDRef tmpUUID = CFUUIDCreate(NULL);
|
||||
self.uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, tmpUUID);
|
||||
CFRelease(tmpUUID);
|
||||
|
||||
}
|
||||
|
||||
-(instancetype)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
CSAnimationItem *newItem = [[CSAnimationItem allocWithZone:zone] init];
|
||||
|
|
@ -97,7 +127,7 @@
|
|||
if ([inputType isEqualToString:@"input"])
|
||||
{
|
||||
InputSource *inpsrc = inp[@"value"];
|
||||
if (inpsrc == srcDel)
|
||||
if (inpsrc == srcDel && inpsrc.sourceLayout == srcDel.sourceLayout)
|
||||
{
|
||||
inp[@"deletedUUID"] = srcDel.uuid;
|
||||
inp[@"value"] = [NSNull null];
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ plugin_base = PluginBase(package='animationplugins')
|
|||
|
||||
library_dirs = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask - NSSystemDomainMask, YES)
|
||||
plugin_dirs = map(lambda x: x + "/Application Support/CocoaSplit/Plugins/Animations", library_dirs)
|
||||
plugin_dirs.append(NSBundle.mainBundle().builtInPlugInsPath() + "/Animations")
|
||||
plugin_dirs.append(NSBundle.mainBundle().resourcePath() + "/Animations")
|
||||
plugin_source = plugin_base.make_plugin_source(searchpath=plugin_dirs)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,5 +9,7 @@
|
|||
#import "CSCaptureBase+TimerDelegate.h"
|
||||
|
||||
@implementation CSCaptureBase (TimerDelegate)
|
||||
@dynamic timerDelegateCtx;
|
||||
@dynamic timerDelegate;
|
||||
|
||||
@end
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue