Merge branch '2.0UI'

This commit is contained in:
Zakk 2016-11-19 10:34:15 -05:00
commit 8eba5fa9b2
474 changed files with 22414 additions and 6244 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View file

@ -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 */;
}

View file

@ -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>

View file

@ -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>

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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>

View 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

View 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

View 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

View 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

View 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>

View file

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View 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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View 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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

View 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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View 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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -9,7 +9,8 @@
NSString *const CSNotificationLayoutAdded = @"CSNotificationLayoutAdded";
NSString *const CSNotificationLayoutDeleted = @"CSNotificationLayoutDeleted";
NSString *const CSNotificationLayoutCanvasChanged = @"CSNotificationLayoutCanvasChanged";
NSString *const CSNotificationLayoutFramerateChanged = @"CSNotificationLayoutFramerateChanged";
@ -23,6 +24,8 @@ NSString *const CSNotificationOutputDeleted = @"CSNotificationOutputDeleted";
NSString *const CSNotificationCompressorAdded = @"CSNotificationCompressorAdded";
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";

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -233,6 +233,7 @@
[_capture_session registerOutput:self];
self.captureName = newDev.captureName;
self.videoFormats = _selectedVideoCaptureDevice.formats;

View file

@ -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>

View file

@ -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>

View file

@ -137,6 +137,7 @@
if (activeVideoDevice)
{
CSDeckLinkWrapper *devWrapper = activeVideoDevice.captureDevice;
IDeckLink *deckLink = devWrapper.deckLink;

View file

@ -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">

View file

@ -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;

View file

@ -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];

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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];
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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
{

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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";
}

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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;
};

View file

@ -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>

View file

@ -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>

View file

@ -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)

View file

@ -0,0 +1,8 @@
from Quartz import CGPathCreateMutable, CGPathAddRect
name = "Rectangle"
def create_cgpath(frame):
newpath = CGPathCreateMutable()
CGPathAddRect(newpath, None, frame)
return newpath

View file

@ -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;
};

View file

@ -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

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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
{

View file

@ -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>

View file

@ -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>

View file

@ -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;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0700"
LastUpgradeVersion = "0730"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -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);
}

View file

@ -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

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View file

@ -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"
}
]
}

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

Binary file not shown.

View file

@ -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;

View file

@ -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 @@
}
}
}
}

View file

@ -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']

View file

@ -7,7 +7,6 @@
//
#import <Cocoa/Cocoa.h>
#import <QTKit/QTKit.h>
#import "CaptureController.h"

View file

@ -20,7 +20,6 @@
-(instancetype)initWithDevice:(AVCaptureDevice *)avDevice withFormat:(AudioStreamBasicDescription *)withFormat;
-(void)resetFormat:(AudioStreamBasicDescription *)format;
-(const AudioStreamBasicDescription *)deviceAudioDescription;
@end

View file

@ -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

View file

@ -42,7 +42,8 @@
@property (strong) CAMultiAudioDevice *outputNode;
@property (strong) CAMultiAudioDevice *graphOutputNode;
@property (strong) NSArray *validSamplerates;
@property (assign) Float32 streamAudioPowerLevel;
@property (assign) Float32 previewAudioPowerLevel;

View file

@ -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];
}

View file

@ -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;

View file

@ -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 {

View file

@ -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);
}

View file

@ -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;

View file

@ -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];
});
}
//});
}

View file

@ -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">

View file

@ -21,6 +21,8 @@
-(void)setVolumeOnOutput:(float)volume;
-(void)enableMeteringOnInputBus:(UInt32)bus;
-(Float32)powerForInputBus:(UInt32)bus;
-(Float32)outputPower;
@end

View file

@ -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;

View file

@ -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.
TPCircularBufferInit(&_inputBuffer, self.inputASBD->mBytesPerFrame * 4096);
TPCircularBufferInit(&_scratchBuffer, self.inputASBD->mBytesPerFrame * 4096);
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;
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,19 +177,11 @@
num_packets = 1;
outputSampleCount += 1024;
if (wrote_bytes >= orig_size)
{
break;
}
}
});
}
}
-(void) setupEncoder
{

View file

@ -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;

View file

@ -7,6 +7,8 @@
//
#import "CSAnimationChooserViewController.h"
#import "CaptureController.h"
@interface CSAnimationChooserViewController ()

View file

@ -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>

View file

@ -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

View file

@ -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];

View file

@ -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)

View file

@ -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