diff --git a/.travis.yml b/.travis.yml index e757a110a..eb328e5c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: objective-c before_install: - - gem install cocoapods --pre --quiet - pod --version - pod setup --silent - pod repo update --silent diff --git a/GPUImage.podspec b/GPUImage.podspec index e5454d4d5..4e1961cbf 100644 --- a/GPUImage.podspec +++ b/GPUImage.podspec @@ -19,7 +19,6 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.6' s.osx.exclude_files = 'framework/Source/iOS', 'framework/Source/GPUImageFilterPipeline.*', - 'framework/Source/GPUImageMovie.*', 'framework/Source/GPUImageMovieComposition.*', 'framework/Source/GPUImageVideoCamera.*', 'framework/Source/GPUImageStillCamera.*', diff --git a/README.md b/README.md old mode 100755 new mode 100644 index a487f368d..16bc3f64f --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@
- + Brad Larson http://www.sunsetlakesoftware.com -[@bradlarson](http://twitter.com/bradlarson) +[@bradlarson](https://twitter.com/bradlarson) contact@sunsetlakesoftware.com @@ -96,7 +96,7 @@ You then need to add a new Copy Files build phase, set the Destination to Framew ### Documentation ### -Documentation is generated from header comments using appledoc. To build the documentation, switch to the "Documentation" scheme in Xcode. You should ensure that "APPLEDOC_PATH" (a User-Defined build setting) points to an appledoc binary, available on Github or through Homebrew. It will also build and install a .docset file, which you can view with your favorite documentation tool. +Documentation is generated from header comments using appledoc. To build the documentation, switch to the "Documentation" scheme in Xcode. You should ensure that "APPLEDOC_PATH" (a User-Defined build setting) points to an appledoc binary, available on Github or through Homebrew. It will also build and install a .docset file, which you can view with your favorite documentation tool. ## Performing common tasks ## @@ -294,6 +294,13 @@ There are currently 125 built-in filters, divided into the following categories: - **GPUImageHueFilter**: Adjusts the hue of an image - *hue*: The hue angle, in degrees. 90 degrees by default +- **GPUImageVibranceFilter**: Adjusts the vibrance of an image + - *vibrance*: The vibrance adjustment to apply, using 0.0 as the default, and a suggested min/max of around -1.2 and 1.2, respectively. + +- **GPUImageWhiteBalanceFilter**: Adjusts the white balance of an image. + - *temperature*: The temperature to adjust the image by, in ºK. A value of 4000 is very cool and 7000 very warm. The default value is 5000. Note that the scale between 4000 and 5000 is nearly as visually significant as that between 5000 and 7000. + - *tint*: The tint to adjust the image by. A value of -200 is *very* green and 200 is *very* pink. The default value is 0. + - **GPUImageToneCurveFilter**: Adjusts the colors of an image based on spline curves for each color channel. - *redControlPoints*: - *greenControlPoints*: @@ -302,7 +309,13 @@ There are currently 125 built-in filters, divided into the following categories: - **GPUImageHighlightShadowFilter**: Adjusts the shadows and highlights of an image - *shadows*: Increase to lighten shadows, from 0.0 to 1.0, with 0.0 as the default. - - *highlights*: Decrease to darken highlights, from 0.0 to 1.0, with 1.0 as the default. + - *highlights*: Decrease to darken highlights, from 1.0 to 0.0, with 1.0 as the default. + +- **GPUImageHighlightShadowTintFilter**: Allows you to tint the shadows and highlights of an image independently using a color and intensity + - *shadowTintColor*: Shadow tint RGB color (GPUVector4). Default: `{1.0f, 0.0f, 0.0f, 1.0f}` (red). + - *highlightTintColor*: Highlight tint RGB color (GPUVector4). Default: `{0.0f, 0.0f, 1.0f, 1.0f}` (blue). + - *shadowTintIntensity*: Shadow tint intensity, from 0.0 to 1.0. Default: 0.0 + - *highlightTintIntensity*: Highlight tint intensity, from 0.0 to 1.0, with 0.0 as the default. - **GPUImageLookupFilter**: Uses an RGB color lookup image to remap the colors in an image. First, use your favourite photo editing application to apply a filter to lookup.png from GPUImage/framework/Resources. For this to work properly each pixel color must not depend on other pixels (e.g. blur will not work). If you need a more complex filter you can create as many lookup tables as required. Once ready, use your new lookup.png file as a second input for GPUImageLookupFilter. @@ -312,6 +325,14 @@ There are currently 125 built-in filters, divided into the following categories: - **GPUImageSoftEleganceFilter**: Another lookup-based color remapping filter. If you want to use this effect you have to add lookup_soft_elegance_1.png and lookup_soft_elegance_2.png from the GPUImage Resources folder to your application bundle. +- **GPUImageSkinToneFilter**: A skin-tone adjustment filter that affects a unique range of light skin-tone colors and adjusts the pink/green or pink/orange range accordingly. Default values are targetted at fair caucasian skin, but can be adjusted as required. + - *skinToneAdjust*: Amount to adjust skin tone. Default: 0.0, suggested min/max: -0.3 and 0.3 respectively. + - *skinHue*: Skin hue to be detected. Default: 0.05 (fair caucasian to reddish skin). + - *skinHueThreshold*: Amount of variance in skin hue. Default: 40.0. + - *maxHueShift*: Maximum amount of hue shifting allowed. Default: 0.25. + - *maxSaturationShift* = Maximum amount of saturation to be shifted (when using orange). Default: 0.4. + - *upperSkinToneColor* = `GPUImageSkinToneUpperColorGreen` or `GPUImageSkinToneUpperColorOrange` + - **GPUImageColorInvertFilter**: Inverts the colors of an image - **GPUImageGrayscaleFilter**: Converts an image to grayscale (a slightly faster implementation of the saturation filter, without the ability to vary the color contribution) @@ -663,8 +684,10 @@ There are currently 125 built-in filters, divided into the following categories: - *refractiveIndex*: The index of refraction for the sphere, with a default of 0.71 - **GPUImageVignetteFilter**: Performs a vignetting effect, fading out the image at the edges - - *x*: - - *y*: The directional intensity of the vignetting, with a default of x = 0.75, y = 0.5 + - *vignetteCenter*: The center for the vignette in tex coords (CGPoint), with a default of 0.5, 0.5 + - *vignetteColor*: The color to use for the vignette (GPUVector3), with a default of black + - *vignetteStart*: The normalized distance from the center where the vignette effect starts, with a default of 0.5 + - *vignetteEnd*: The normalized distance from the center where the vignette effect ends, with a default of 0.75 - **GPUImageKuwaharaFilter**: Kuwahara image abstraction, drawn from the work of Kyprianidis, et. al. in their publication "Anisotropic Kuwahara Filtering on the GPU" within the GPU Pro collection. This produces an oil-painting-like image, but it is extremely computationally expensive, so it can take seconds to render a frame on an iPad 2. This might be best used for still images. - *radius*: In integer specifying the number of pixels out from the center pixel to test when applying the filter, with a default of 4. A higher value creates a more abstracted image, but at the cost of much greater processing time. diff --git a/build.sh b/build.sh index 999f66b65..399c72e2e 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ set -e -IOSSDK_VER="7.0" +IOSSDK_VER="9.0" # xcodebuild -showsdks diff --git a/examples/Mac/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj b/examples/Mac/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj index 09e483c97..09f107c26 100644 --- a/examples/Mac/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj +++ b/examples/Mac/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj @@ -244,6 +244,7 @@ BC0B246E197DF612009AC707 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 0700; LastUpgradeCheck = 0600; ORGANIZATIONNAME = "Sunset Lake Software"; TargetAttributes = { diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj new file mode 100644 index 000000000..1006246a8 --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj @@ -0,0 +1,500 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 575AD8C91BEA6FC60088E866 /* sample_iPod.m4v in Resources */ = {isa = PBXBuildFile; fileRef = 575AD8C81BEA6FC60088E866 /* sample_iPod.m4v */; settings = {ASSET_TAGS = (); }; }; + 79C26E221A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 79C26E211A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.m */; }; + 79C26E2E1A5F02B70054857C /* SLSSimpleVideoFileFilterWindowController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 79C26E2D1A5F02B70054857C /* SLSSimpleVideoFileFilterWindowController.xib */; }; + 79E8A5FB1A5ED6A700E6A226 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E8A5FA1A5ED6A700E6A226 /* AppDelegate.m */; }; + 79E8A5FD1A5ED6A700E6A226 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E8A5FC1A5ED6A700E6A226 /* main.m */; }; + 79E8A5FF1A5ED6A700E6A226 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 79E8A5FE1A5ED6A700E6A226 /* Images.xcassets */; }; + 79E8A6021A5ED6A700E6A226 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 79E8A6001A5ED6A700E6A226 /* MainMenu.xib */; }; + 79E8A60E1A5ED6A700E6A226 /* SimpleVideoFilterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 79E8A60D1A5ED6A700E6A226 /* SimpleVideoFilterTests.m */; }; + BCF8E9E51A75DE67005AE243 /* GPUImage.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = BCF8E9E21A75DE3F005AE243 /* GPUImage.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 79E8A6081A5ED6A700E6A226 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 79E8A5EC1A5ED6A700E6A226 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 79E8A5F31A5ED6A700E6A226; + remoteInfo = SimpleVideoFilter; + }; + BCF8E9E11A75DE3F005AE243 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCF8E9DD1A75DE3F005AE243 /* GPUImageMac.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BCA3F31C17239B6500E28AEC; + remoteInfo = GPUImage; + }; + BCF8E9E31A75DE5B005AE243 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BCF8E9DD1A75DE3F005AE243 /* GPUImageMac.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = BCA3F31B17239B6500E28AEC; + remoteInfo = GPUImage; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 79C26E251A5EE5210054857C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + BCF8E9E51A75DE67005AE243 /* GPUImage.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 575AD8C81BEA6FC60088E866 /* sample_iPod.m4v */ = {isa = PBXFileReference; lastKnownFileType = file; path = sample_iPod.m4v; sourceTree = ""; }; + 79C26E201A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLSSimpleVideoFileFilterWindowController.h; sourceTree = ""; }; + 79C26E211A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLSSimpleVideoFileFilterWindowController.m; sourceTree = ""; }; + 79C26E2D1A5F02B70054857C /* SLSSimpleVideoFileFilterWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SLSSimpleVideoFileFilterWindowController.xib; sourceTree = ""; }; + 79E8A5F41A5ED6A700E6A226 /* SimpleVideoFileFilter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleVideoFileFilter.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 79E8A5F81A5ED6A700E6A226 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 79E8A5F91A5ED6A700E6A226 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 79E8A5FA1A5ED6A700E6A226 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 79E8A5FC1A5ED6A700E6A226 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 79E8A5FE1A5ED6A700E6A226 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 79E8A6011A5ED6A700E6A226 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 79E8A6071A5ED6A700E6A226 /* SimpleVideoFileFilter.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SimpleVideoFileFilter.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 79E8A60C1A5ED6A700E6A226 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 79E8A60D1A5ED6A700E6A226 /* SimpleVideoFilterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SimpleVideoFilterTests.m; sourceTree = ""; }; + BCF8E9DD1A75DE3F005AE243 /* GPUImageMac.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GPUImageMac.xcodeproj; path = ../../../../framework/GPUImageMac.xcodeproj; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 79E8A5F11A5ED6A700E6A226 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79E8A6041A5ED6A700E6A226 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 79E8A5EB1A5ED6A700E6A226 = { + isa = PBXGroup; + children = ( + 79E8A5F61A5ED6A700E6A226 /* SimpleVideoFileFilter */, + 79E8A61D1A5ED97400E6A226 /* Frameworks */, + 79E8A60A1A5ED6A700E6A226 /* SimpleVideoFilterTests */, + 79E8A5F51A5ED6A700E6A226 /* Products */, + ); + sourceTree = ""; + }; + 79E8A5F51A5ED6A700E6A226 /* Products */ = { + isa = PBXGroup; + children = ( + 79E8A5F41A5ED6A700E6A226 /* SimpleVideoFileFilter.app */, + 79E8A6071A5ED6A700E6A226 /* SimpleVideoFileFilter.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 79E8A5F61A5ED6A700E6A226 /* SimpleVideoFileFilter */ = { + isa = PBXGroup; + children = ( + 79E8A5F91A5ED6A700E6A226 /* AppDelegate.h */, + 79E8A5FA1A5ED6A700E6A226 /* AppDelegate.m */, + 79C26E201A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.h */, + 79C26E211A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.m */, + 79C26E2D1A5F02B70054857C /* SLSSimpleVideoFileFilterWindowController.xib */, + 79E8A5FE1A5ED6A700E6A226 /* Images.xcassets */, + 79E8A6001A5ED6A700E6A226 /* MainMenu.xib */, + 79E8A5F71A5ED6A700E6A226 /* Supporting Files */, + ); + name = SimpleVideoFileFilter; + path = SimpleVideoFilter; + sourceTree = ""; + }; + 79E8A5F71A5ED6A700E6A226 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 575AD8C81BEA6FC60088E866 /* sample_iPod.m4v */, + 79E8A5F81A5ED6A700E6A226 /* Info.plist */, + 79E8A5FC1A5ED6A700E6A226 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 79E8A60A1A5ED6A700E6A226 /* SimpleVideoFilterTests */ = { + isa = PBXGroup; + children = ( + 79E8A60D1A5ED6A700E6A226 /* SimpleVideoFilterTests.m */, + 79E8A60B1A5ED6A700E6A226 /* Supporting Files */, + ); + path = SimpleVideoFilterTests; + sourceTree = ""; + }; + 79E8A60B1A5ED6A700E6A226 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 79E8A60C1A5ED6A700E6A226 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 79E8A61D1A5ED97400E6A226 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BCF8E9DD1A75DE3F005AE243 /* GPUImageMac.xcodeproj */, + ); + name = Frameworks; + path = SimpleVideoFilterTests; + sourceTree = ""; + }; + BCF8E9DE1A75DE3F005AE243 /* Products */ = { + isa = PBXGroup; + children = ( + BCF8E9E21A75DE3F005AE243 /* GPUImage.framework */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 79E8A5F31A5ED6A700E6A226 /* SimpleVideoFileFilter */ = { + isa = PBXNativeTarget; + buildConfigurationList = 79E8A6111A5ED6A700E6A226 /* Build configuration list for PBXNativeTarget "SimpleVideoFileFilter" */; + buildPhases = ( + 79E8A5F01A5ED6A700E6A226 /* Sources */, + 79E8A5F11A5ED6A700E6A226 /* Frameworks */, + 79E8A5F21A5ED6A700E6A226 /* Resources */, + 79C26E251A5EE5210054857C /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + BCF8E9E41A75DE5B005AE243 /* PBXTargetDependency */, + ); + name = SimpleVideoFileFilter; + productName = SimpleVideoFilter; + productReference = 79E8A5F41A5ED6A700E6A226 /* SimpleVideoFileFilter.app */; + productType = "com.apple.product-type.application"; + }; + 79E8A6061A5ED6A700E6A226 /* SimpleVideoFileFilterTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 79E8A6141A5ED6A700E6A226 /* Build configuration list for PBXNativeTarget "SimpleVideoFileFilterTests" */; + buildPhases = ( + 79E8A6031A5ED6A700E6A226 /* Sources */, + 79E8A6041A5ED6A700E6A226 /* Frameworks */, + 79E8A6051A5ED6A700E6A226 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 79E8A6091A5ED6A700E6A226 /* PBXTargetDependency */, + ); + name = SimpleVideoFileFilterTests; + productName = SimpleVideoFilterTests; + productReference = 79E8A6071A5ED6A700E6A226 /* SimpleVideoFileFilter.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 79E8A5EC1A5ED6A700E6A226 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Red Queen Coder, LLC"; + TargetAttributes = { + 79E8A5F31A5ED6A700E6A226 = { + CreatedOnToolsVersion = 6.1.1; + }; + 79E8A6061A5ED6A700E6A226 = { + CreatedOnToolsVersion = 6.1.1; + TestTargetID = 79E8A5F31A5ED6A700E6A226; + }; + }; + }; + buildConfigurationList = 79E8A5EF1A5ED6A700E6A226 /* Build configuration list for PBXProject "SimpleVideoFileFilter" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 79E8A5EB1A5ED6A700E6A226; + productRefGroup = 79E8A5F51A5ED6A700E6A226 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = BCF8E9DE1A75DE3F005AE243 /* Products */; + ProjectRef = BCF8E9DD1A75DE3F005AE243 /* GPUImageMac.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 79E8A5F31A5ED6A700E6A226 /* SimpleVideoFileFilter */, + 79E8A6061A5ED6A700E6A226 /* SimpleVideoFileFilterTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + BCF8E9E21A75DE3F005AE243 /* GPUImage.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = GPUImage.framework; + remoteRef = BCF8E9E11A75DE3F005AE243 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 79E8A5F21A5ED6A700E6A226 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79E8A5FF1A5ED6A700E6A226 /* Images.xcassets in Resources */, + 575AD8C91BEA6FC60088E866 /* sample_iPod.m4v in Resources */, + 79C26E2E1A5F02B70054857C /* SLSSimpleVideoFileFilterWindowController.xib in Resources */, + 79E8A6021A5ED6A700E6A226 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79E8A6051A5ED6A700E6A226 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 79E8A5F01A5ED6A700E6A226 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79E8A5FD1A5ED6A700E6A226 /* main.m in Sources */, + 79E8A5FB1A5ED6A700E6A226 /* AppDelegate.m in Sources */, + 79C26E221A5EDD1C0054857C /* SLSSimpleVideoFileFilterWindowController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79E8A6031A5ED6A700E6A226 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79E8A60E1A5ED6A700E6A226 /* SimpleVideoFilterTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 79E8A6091A5ED6A700E6A226 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 79E8A5F31A5ED6A700E6A226 /* SimpleVideoFileFilter */; + targetProxy = 79E8A6081A5ED6A700E6A226 /* PBXContainerItemProxy */; + }; + BCF8E9E41A75DE5B005AE243 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = GPUImage; + targetProxy = BCF8E9E31A75DE5B005AE243 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 79E8A6001A5ED6A700E6A226 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 79E8A6011A5ED6A700E6A226 /* Base */, + ); + name = MainMenu.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 79E8A60F1A5ED6A700E6A226 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + 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.10; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 79E8A6101A5ED6A700E6A226 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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 = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + 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.10; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + }; + name = Release; + }; + 79E8A6121A5ED6A700E6A226 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = SimpleVideoFilter/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_NAME = SimpleVideoFileFilter; + }; + name = Debug; + }; + 79E8A6131A5ED6A700E6A226 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = SimpleVideoFilter/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + PRODUCT_NAME = SimpleVideoFileFilter; + }; + name = Release; + }; + 79E8A6151A5ED6A700E6A226 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = SimpleVideoFilterTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_NAME = SimpleVideoFileFilter; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SimpleVideoFileFilter.app/Contents/MacOS/SimpleVideoFileFilter"; + }; + name = Debug; + }; + 79E8A6161A5ED6A700E6A226 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + INFOPLIST_FILE = SimpleVideoFilterTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_NAME = SimpleVideoFileFilter; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SimpleVideoFileFilter.app/Contents/MacOS/SimpleVideoFileFilter"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 79E8A5EF1A5ED6A700E6A226 /* Build configuration list for PBXProject "SimpleVideoFileFilter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79E8A60F1A5ED6A700E6A226 /* Debug */, + 79E8A6101A5ED6A700E6A226 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 79E8A6111A5ED6A700E6A226 /* Build configuration list for PBXNativeTarget "SimpleVideoFileFilter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79E8A6121A5ED6A700E6A226 /* Debug */, + 79E8A6131A5ED6A700E6A226 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 79E8A6141A5ED6A700E6A226 /* Build configuration list for PBXNativeTarget "SimpleVideoFileFilterTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79E8A6151A5ED6A700E6A226 /* Debug */, + 79E8A6161A5ED6A700E6A226 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 79E8A5EC1A5ED6A700E6A226 /* Project object */; +} diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/AppDelegate.h b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/AppDelegate.h new file mode 100644 index 000000000..ab53e3b6d --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/AppDelegate.h @@ -0,0 +1,10 @@ +#import +#import "SLSSimpleVideoFileFilterWindowController.h" + +@interface AppDelegate : NSObject +{ + SLSSimpleVideoFileFilterWindowController *simpleVideoFileFilterWindowController; +} + +@end + diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/AppDelegate.m b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/AppDelegate.m new file mode 100644 index 000000000..3142c1d8c --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/AppDelegate.m @@ -0,0 +1,21 @@ +#import "AppDelegate.h" +#import + +@interface AppDelegate () + +@property (weak) IBOutlet NSWindow *window; +@end + +@implementation AppDelegate + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + // Insert code here to initialize your application + simpleVideoFileFilterWindowController = [[SLSSimpleVideoFileFilterWindowController alloc] initWithWindowNibName:@"SLSSimpleVideoFileFilterWindowController"]; + [simpleVideoFileFilterWindowController showWindow:self]; +} + +- (void)applicationWillTerminate:(NSNotification *)aNotification { + // Insert code here to tear down your application +} + +@end diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Base.lproj/MainMenu.xib b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Base.lproj/MainMenu.xib new file mode 100644 index 000000000..7396d8880 --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Base.lproj/MainMenu.xib @@ -0,0 +1,676 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..2db2b1c7c --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,58 @@ +{ + "images" : [ + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "16x16", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "32x32", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "128x128", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "256x256", + "scale" : "2x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "1x" + }, + { + "idiom" : "mac", + "size" : "512x512", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Info.plist b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Info.plist new file mode 100644 index 000000000..f3cc20d03 --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + com.redqueencoder.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + Copyright © 2015 Red Queen Coder, LLC. All rights reserved. + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.h b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.h new file mode 100644 index 000000000..3860944be --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.h @@ -0,0 +1,5 @@ +#import + +@interface SLSSimpleVideoFileFilterWindowController : NSWindowController + +@end diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.m b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.m new file mode 100644 index 000000000..5c2cb6b44 --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.m @@ -0,0 +1,116 @@ +#import "SLSSimpleVideoFileFilterWindowController.h" +#import + +@interface SLSSimpleVideoFileFilterWindowController () +{ + GPUImageMovie *movieFile; + GPUImageOutput *filter; + GPUImageMovieWriter *movieWriter; + NSTimer * timer; +} + +@property (weak) IBOutlet GPUImageView *videoView; +@property (weak) IBOutlet NSTextField *progressLabel; + +@property (weak) IBOutlet NSView *containerView; +@property (weak) IBOutlet NSButton *urlButton; +@property (weak) IBOutlet NSButton *avPlayerItemButton; + +@property (nonatomic, strong) AVPlayerItem *playerItem; +@property (nonatomic, strong) AVPlayer *player; + +@end + +@implementation SLSSimpleVideoFileFilterWindowController + + +- (void)windowDidLoad { + [super windowDidLoad]; + + self.containerView.hidden = YES; + +} + +- (IBAction)gpuImageMovieWithURLButtonAction:(id)sender { + [self runProcessingWithAVPlayerItem:NO]; + [self showProcessingUI]; +} + +- (IBAction)gpuImageMovieWithAvplayeritemButtonAction:(id)sender { + [self runProcessingWithAVPlayerItem:YES]; + [self showProcessingUI]; +} + +- (void)showProcessingUI { + self.containerView.hidden = NO; + self.urlButton.hidden = YES; + self.avPlayerItemButton.hidden = YES; +} + +- (void)runProcessingWithAVPlayerItem:(BOOL)withAVPlayerItem { + NSURL *sampleURL = [[NSBundle mainBundle] URLForResource:@"sample_iPod" withExtension:@"m4v"]; + + self.playerItem = [[AVPlayerItem alloc] initWithURL:sampleURL]; + self.player = [AVPlayer playerWithPlayerItem:self.playerItem]; + + //movieFile = [[GPUImageMovie alloc] initWithURL:sampleURL]; + movieFile = [[GPUImageMovie alloc] initWithPlayerItem:self.playerItem]; + movieFile.runBenchmark = YES; + movieFile.playAtActualSpeed = NO; + filter = [[GPUImagePixellateFilter alloc] init]; + // filter = [[GPUImageUnsharpMaskFilter alloc] init]; + + [movieFile addTarget:filter]; + + // Only rotate the video for display, leave orientation the same for recording + GPUImageView *filterView = (GPUImageView *)self.videoView; + [filter addTarget:filterView]; + + // In addition to displaying to the screen, write out a processed version of the movie to disk + NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.m4v"]; + unlink([pathToMovie UTF8String]); // If a file already exists, AVAssetWriter won't let you record new frames, so delete the old movie + NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie]; + + movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:CGSizeMake(640.0, 480.0)]; + [filter addTarget:movieWriter]; + + // Configure this for video from the movie file, where we want to preserve all video frames and audio samples + movieWriter.shouldPassthroughAudio = YES; + movieFile.audioEncodingTarget = movieWriter; + [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter]; + + [movieWriter startRecording]; + [movieFile startProcessing]; + + timer = [NSTimer scheduledTimerWithTimeInterval:0.3f + target:self + selector:@selector(retrievingProgress) + userInfo:nil + repeats:YES]; + + [movieWriter setCompletionBlock:^{ + [filter removeTarget:movieWriter]; + [movieWriter finishRecording]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [timer invalidate]; + self.progressLabel.stringValue = @"100%"; + }); + }]; + + [self.player play]; +} + +- (void)retrievingProgress +{ + self.progressLabel.stringValue = [NSString stringWithFormat:@"%d%%", (int)(movieFile.progress * 100)]; +} + +- (IBAction)updatePixelWidth:(id)sender +{ + // [(GPUImageUnsharpMaskFilter *)filter setIntensity:[(UISlider *)sender value]]; + [(GPUImagePixellateFilter *)filter setFractionalWidthOfAPixel:[(NSSlider *)sender floatValue]]; +} + + +@end diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.xib b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.xib new file mode 100644 index 000000000..73be63722 --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/SLSSimpleVideoFileFilterWindowController.xib @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/main.m b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/main.m new file mode 100644 index 000000000..303f9ce6c --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/main.m @@ -0,0 +1,13 @@ +// +// main.m +// SimpleVideoFilter +// +// Created by Janie Clayton-Hasz on 1/8/15. +// Copyright (c) 2015 Red Queen Coder, LLC. All rights reserved. +// + +#import + +int main(int argc, const char * argv[]) { + return NSApplicationMain(argc, argv); +} diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/sample_iPod.m4v b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/sample_iPod.m4v new file mode 100755 index 000000000..85d9018f1 Binary files /dev/null and b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilter/sample_iPod.m4v differ diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilterTests/Info.plist b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilterTests/Info.plist new file mode 100644 index 000000000..8ff6f557a --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilterTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.redqueencoder.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilterTests/SimpleVideoFilterTests.m b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilterTests/SimpleVideoFilterTests.m new file mode 100644 index 000000000..179e59bd5 --- /dev/null +++ b/examples/Mac/SimpleVideoFileFilter/SimpleVideoFilterTests/SimpleVideoFilterTests.m @@ -0,0 +1,40 @@ +// +// SimpleVideoFilterTests.m +// SimpleVideoFilterTests +// +// Created by Janie Clayton-Hasz on 1/8/15. +// Copyright (c) 2015 Red Queen Coder, LLC. All rights reserved. +// + +#import +#import + +@interface SimpleVideoFilterTests : XCTestCase + +@end + +@implementation SimpleVideoFilterTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/examples/Mac/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj b/examples/Mac/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj index 3fdf2cf9b..9ad08db0d 100644 --- a/examples/Mac/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj +++ b/examples/Mac/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj @@ -55,9 +55,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 79C26E201A5EDD1C0054857C /* SLSSimpleVideoFilterWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLSSimpleVideoFilterWindowController.h; sourceTree = ""; }; - 79C26E211A5EDD1C0054857C /* SLSSimpleVideoFilterWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLSSimpleVideoFilterWindowController.m; sourceTree = ""; }; - 79C26E2D1A5F02B70054857C /* SLSSimpleVideoFilterWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SLSSimpleVideoFilterWindowController.xib; sourceTree = ""; }; + 79C26E201A5EDD1C0054857C /* SLSSimpleVideoFilterWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SLSSimpleVideoFilterWindowController.h; path = SimpleVideoFilter/SLSSimpleVideoFilterWindowController.h; sourceTree = SOURCE_ROOT; }; + 79C26E211A5EDD1C0054857C /* SLSSimpleVideoFilterWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SLSSimpleVideoFilterWindowController.m; path = SimpleVideoFilter/SLSSimpleVideoFilterWindowController.m; sourceTree = SOURCE_ROOT; }; + 79C26E2D1A5F02B70054857C /* SLSSimpleVideoFilterWindowController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = SLSSimpleVideoFilterWindowController.xib; path = SimpleVideoFilter/SLSSimpleVideoFilterWindowController.xib; sourceTree = SOURCE_ROOT; }; 79E8A5F41A5ED6A700E6A226 /* SimpleVideoFilter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleVideoFilter.app; sourceTree = BUILT_PRODUCTS_DIR; }; 79E8A5F81A5ED6A700E6A226 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 79E8A5F91A5ED6A700E6A226 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; diff --git a/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/SLSSimpleVideoFilterWindowController.xib b/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/SLSSimpleVideoFilterWindowController.xib index eb91fd97b..90d66050c 100644 --- a/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/SLSSimpleVideoFilterWindowController.xib +++ b/examples/Mac/SimpleVideoFilter/SimpleVideoFilter/SLSSimpleVideoFilterWindowController.xib @@ -1,7 +1,7 @@ - + - + @@ -16,7 +16,7 @@ - + diff --git a/examples/iOS/BenchmarkSuite/BenchmarkSuite/BenchmarkAppDelegate.m b/examples/iOS/BenchmarkSuite/BenchmarkSuite/BenchmarkAppDelegate.m index b714fc6d6..3089d1db9 100755 --- a/examples/iOS/BenchmarkSuite/BenchmarkSuite/BenchmarkAppDelegate.m +++ b/examples/iOS/BenchmarkSuite/BenchmarkSuite/BenchmarkAppDelegate.m @@ -33,8 +33,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( mainTabBarController.viewControllers = arrayOfViewControllers; mainTabBarController.selectedViewController = imageFilteringBenchmarkController; - [self.window addSubview:mainTabBarController.view]; - + self.window.rootViewController = mainTabBarController; + [self.window makeKeyAndVisible]; return YES; } diff --git a/examples/iOS/ColorObjectTracking/ColorObjectTracking/ColorTrackingAppDelegate.m b/examples/iOS/ColorObjectTracking/ColorObjectTracking/ColorTrackingAppDelegate.m index 3ee1d8e03..90d4cf733 100755 --- a/examples/iOS/ColorObjectTracking/ColorObjectTracking/ColorTrackingAppDelegate.m +++ b/examples/iOS/ColorObjectTracking/ColorObjectTracking/ColorTrackingAppDelegate.m @@ -10,8 +10,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor]; - colorTrackingViewController = [[ColorTrackingViewController alloc] initWithNibName:nil bundle:nil]; - [self.window addSubview:colorTrackingViewController.view]; + self.window.rootViewController = [[ColorTrackingViewController alloc] initWithNibName:nil bundle:nil]; [self.window makeKeyAndVisible]; return YES; diff --git a/examples/iOS/FilterShowcase/FilterShowcase.xcodeproj/project.pbxproj b/examples/iOS/FilterShowcase/FilterShowcase.xcodeproj/project.pbxproj index d6725df68..228d1d2aa 100755 --- a/examples/iOS/FilterShowcase/FilterShowcase.xcodeproj/project.pbxproj +++ b/examples/iOS/FilterShowcase/FilterShowcase.xcodeproj/project.pbxproj @@ -372,6 +372,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; @@ -414,6 +415,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; diff --git a/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseAppDelegate.m b/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseAppDelegate.m index f154970e4..cc57485a3 100755 --- a/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseAppDelegate.m +++ b/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseAppDelegate.m @@ -12,12 +12,10 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window.backgroundColor = [UIColor whiteColor]; filterNavigationController = [[UINavigationController alloc] init]; - [self.window addSubview:filterNavigationController.view]; - filterListController = [[ShowcaseFilterListController alloc] initWithNibName:nil bundle:nil]; - [filterNavigationController pushViewController:filterListController animated:NO]; + [self.window setRootViewController:filterNavigationController]; [self.window makeKeyAndVisible]; return YES; diff --git a/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseFilterViewController.m b/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseFilterViewController.m index 5f5d5b648..d9ed42146 100755 --- a/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseFilterViewController.m +++ b/examples/iOS/FilterShowcase/FilterShowcase/ShowcaseFilterViewController.m @@ -870,6 +870,7 @@ - (void)setupFilter; { self.title = @"Voronoi"; self.filterSettingsSlider.hidden = YES; + needsSecondImage = YES; GPUImageJFAVoronoiFilter *jfa = [[GPUImageJFAVoronoiFilter alloc] init]; [jfa setSizeInPixels:CGSizeMake(1024.0, 1024.0)]; diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj index 5158f4050..9ba882a2c 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift.xcodeproj/project.pbxproj @@ -192,7 +192,8 @@ BC0037AF195CA11B00B9D651 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = "Sunset Lake Software"; TargetAttributes = { BC0037B6195CA11B00B9D651 = { @@ -315,7 +316,9 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -358,6 +361,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -382,6 +386,7 @@ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; INFOPLIST_FILE = FilterShowcaseSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -393,6 +398,7 @@ ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; INFOPLIST_FILE = FilterShowcaseSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Base.lproj/Main.storyboard b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Base.lproj/Main.storyboard index 9deef2c4d..877a7671d 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Base.lproj/Main.storyboard +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Base.lproj/Main.storyboard @@ -1,14 +1,14 @@ - + - - + + - + @@ -70,11 +70,11 @@ - + - - - - - - - - diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterDisplayViewController.swift b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterDisplayViewController.swift index 723e621a6..79892dbc1 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterDisplayViewController.swift +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterDisplayViewController.swift @@ -14,7 +14,7 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega videoCamera = GPUImageVideoCamera(sessionPreset: AVCaptureSessionPreset640x480, cameraPosition: .Back) videoCamera.outputImageOrientation = .Portrait; - super.init(coder: aDecoder) + super.init(coder: aDecoder)! } var filterOperation: FilterOperationInterface? { @@ -69,7 +69,7 @@ class FilterDisplayViewController: UIViewController, UISplitViewControllerDelega @IBAction func updateSliderValue() { if let currentFilterConfiguration = self.filterOperation { switch (currentFilterConfiguration.sliderConfiguration) { - case let .Enabled(minimumValue, maximumValue, initialValue): + case .Enabled(_, _, _): currentFilterConfiguration.updateBasedOnSliderValue(CGFloat(self.filterSlider!.value)) // If the UISlider isn't wired up, I want this to throw a runtime exception case .Disabled: break diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterListViewController.swift b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterListViewController.swift index 4c568f9de..b3adc1fc6 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterListViewController.swift +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterListViewController.swift @@ -9,7 +9,7 @@ class FilterListViewController: UITableViewController { override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "showDetail" { - if let indexPath = self.tableView.indexPathForSelectedRow() { + if let indexPath = self.tableView.indexPathForSelectedRow { let filterInList = filterOperations[indexPath.row] (segue.destinationViewController as! FilterDisplayViewController).filterOperation = filterInList } @@ -27,7 +27,7 @@ class FilterListViewController: UITableViewController { } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell + let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) let filterInList:FilterOperationInterface = filterOperations[indexPath.row] cell.textLabel?.text = filterInList.listName diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterOperations.swift b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterOperations.swift index 50df5b2bf..585a183a0 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterOperations.swift +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/FilterOperations.swift @@ -352,6 +352,15 @@ let filterOperations: Array = [ }, filterOperationType:.SingleInput ), + FilterOperation ( + listName:"Solarize", + titleName:"Solarize", + sliderConfiguration:.Enabled(minimumValue:0.0, maximumValue:1.0, initialValue:0.5), + sliderUpdateCallback: {(filter, sliderValue) in + filter.threshold = sliderValue + }, + filterOperationType:.SingleInput + ), FilterOperation ( listName:"Pixellate", titleName:"Pixellate", @@ -578,6 +587,13 @@ let filterOperations: Array = [ return (filter, nil) }) ), + FilterOperation ( + listName:"ColourFAST feature detector", + titleName:"ColourFAST Feature Detector", + sliderConfiguration:.Disabled, + sliderUpdateCallback:nil, + filterOperationType:.SingleInput + ), FilterOperation ( listName:"Buffer", titleName:"Buffer", @@ -1009,6 +1025,17 @@ let filterOperations: Array = [ }, filterOperationType:.SingleInput ), + FilterOperation ( + listName:"Local binary pattern (color)", + titleName:"Local Binary Pattern (color)", + sliderConfiguration:.Enabled(minimumValue:1.0, maximumValue:5.0, initialValue:1.0), + sliderUpdateCallback: {(filter, sliderValue) in + let filterSize = filter.outputFrameSize() + filter.texelWidth = (sliderValue / filterSize.width) + filter.texelHeight = (sliderValue / filterSize.height) + }, + filterOperationType:.SingleInput + ), FilterOperation ( listName:"Dissolve blend", titleName:"Dissolve Blend", diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Images.xcassets/AppIcon.appiconset/Contents.json b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Images.xcassets/AppIcon.appiconset/Contents.json index 91bf9c14a..36d2c80d8 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Images.xcassets/AppIcon.appiconset/Contents.json @@ -5,16 +5,31 @@ "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, { "idiom" : "ipad", "size" : "29x29", diff --git a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Info.plist b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Info.plist index a70abd66e..c8feee23e 100644 --- a/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Info.plist +++ b/examples/iOS/FilterShowcaseSwift/FilterShowcaseSwift/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -28,6 +28,10 @@ armv7 + UIRequiresFullScreen + + UIStatusBarHidden + UIStatusBarTintParameters UINavigationBar @@ -38,5 +42,9 @@ + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + diff --git a/examples/iOS/SimpleImageFilter/SimpleImageFilter/SimpleImageAppDelegate.m b/examples/iOS/SimpleImageFilter/SimpleImageFilter/SimpleImageAppDelegate.m index 65019b6c8..8f63db4a7 100755 --- a/examples/iOS/SimpleImageFilter/SimpleImageFilter/SimpleImageAppDelegate.m +++ b/examples/iOS/SimpleImageFilter/SimpleImageFilter/SimpleImageAppDelegate.m @@ -11,7 +11,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window.backgroundColor = [UIColor whiteColor]; rootViewController = [[SimpleImageViewController alloc] initWithNibName:nil bundle:nil]; - [self.window addSubview:rootViewController.view]; + [self.window setRootViewController:rootViewController]; [self.window makeKeyAndVisible]; return YES; diff --git a/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample.xcodeproj/project.pbxproj b/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample.xcodeproj/project.pbxproj index 4512e28e3..264c8966c 100644 --- a/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample.xcodeproj/project.pbxproj +++ b/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample.xcodeproj/project.pbxproj @@ -148,7 +148,8 @@ BC73FD1619612C19004A9191 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = "Sunset Lake Software"; TargetAttributes = { BC73FD1D19612C19004A9191 = { @@ -261,6 +262,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -325,8 +327,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; INFOPLIST_FILE = SimpleSwiftVideoFilterExample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -336,8 +340,10 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Developer"; INFOPLIST_FILE = SimpleSwiftVideoFilterExample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample/Info.plist b/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample/Info.plist index 5b429967f..66c240a90 100644 --- a/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample/Info.plist +++ b/examples/iOS/SimpleSwiftVideoFilterExample/SimpleSwiftVideoFilterExample/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj b/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj index 239163d54..2ccacccb0 100755 --- a/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj +++ b/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter.xcodeproj/project.pbxproj @@ -383,6 +383,7 @@ BCB5DDE314E86899000AF3C2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SimpleVideoFileFilter/SimpleVideoFileFilter-Prefix.pch"; INFOPLIST_FILE = "SimpleVideoFileFilter/SimpleVideoFileFilter-Info.plist"; @@ -394,6 +395,7 @@ BCB5DDE414E86899000AF3C2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ENABLE_BITCODE = NO; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SimpleVideoFileFilter/SimpleVideoFileFilter-Prefix.pch"; INFOPLIST_FILE = "SimpleVideoFileFilter/SimpleVideoFileFilter-Info.plist"; diff --git a/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter/SimpleVideoFileFilterAppDelegate.m b/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter/SimpleVideoFileFilterAppDelegate.m index 30a60aeaf..4faf44d99 100755 --- a/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter/SimpleVideoFileFilterAppDelegate.m +++ b/examples/iOS/SimpleVideoFileFilter/SimpleVideoFileFilter/SimpleVideoFileFilterAppDelegate.m @@ -19,9 +19,13 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( rootViewController = [[SimpleVideoFileFilterViewController alloc] initWithNibName:@"SimpleVideoFileFilterViewController" bundle:nil]; rootViewController.view.frame = [[UIScreen mainScreen] bounds]; - [self.window addSubview:rootViewController.view]; + self.window.rootViewController = rootViewController; +// [self.window addSubview:rootViewController.view]; [self.window makeKeyAndVisible]; + [self.window layoutSubviews]; + self.window.rootViewController = rootViewController; + return YES; } diff --git a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj index 736b03314..9845f261a 100755 --- a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj +++ b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ BCB5DDFF14E87783000AF3C2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB5DDFE14E87783000AF3C2 /* QuartzCore.framework */; }; BCB5DE0114E87789000AF3C2 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BCB5DE0014E87789000AF3C2 /* OpenGLES.framework */; }; BCF867511725AB5300912E34 /* libGPUImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BCF8674C1725AB2100912E34 /* libGPUImage.a */; }; + D30ACF271BAFE43F00E9759C /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D30ACF261BAFE43F00E9759C /* AssetsLibrary.framework */; }; E5066F611855AC78008C7682 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E5066F601855AC78008C7682 /* Default-568h@2x.png */; }; /* End PBXBuildFile section */ @@ -78,6 +79,7 @@ BCB5DDFB14E876ED000AF3C2 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; }; BCB5DDFE14E87783000AF3C2 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; BCB5DE0014E87789000AF3C2 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + D30ACF261BAFE43F00E9759C /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; E5066F601855AC78008C7682 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -86,6 +88,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D30ACF271BAFE43F00E9759C /* AssetsLibrary.framework in Frameworks */, BCF867511725AB5300912E34 /* libGPUImage.a in Frameworks */, BCB5DE0114E87789000AF3C2 /* OpenGLES.framework in Frameworks */, BCB5DDFF14E87783000AF3C2 /* QuartzCore.framework in Frameworks */, @@ -122,6 +125,7 @@ BCB5DDCD14E86899000AF3C2 /* Frameworks */ = { isa = PBXGroup; children = ( + D30ACF261BAFE43F00E9759C /* AssetsLibrary.framework */, BCB5DDEA14E8756A000AF3C2 /* GPUImage.xcodeproj */, BCB5DE0014E87789000AF3C2 /* OpenGLES.framework */, BCB5DDFE14E87783000AF3C2 /* QuartzCore.framework */, @@ -202,6 +206,11 @@ attributes = { LastUpgradeCheck = 0500; ORGANIZATIONNAME = "Cell Phone"; + TargetAttributes = { + BCB5DDC914E86899000AF3C2 = { + DevelopmentTeam = V2DTUY5PQ8; + }; + }; }; buildConfigurationList = BCB5DDC414E86899000AF3C2 /* Build configuration list for PBXProject "SimpleVideoFilter" */; compatibilityVersion = "Xcode 3.2"; @@ -323,7 +332,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "../../../framework/**"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( "-ObjC", @@ -356,7 +365,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "../../../framework/**"; - IPHONEOS_DEPLOYMENT_TARGET = 4.3; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; OTHER_LDFLAGS = ( "-ObjC", @@ -371,9 +380,11 @@ BCB5DDE314E86899000AF3C2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SimpleVideoFilter/SimpleVideoFilter-Prefix.pch"; INFOPLIST_FILE = "SimpleVideoFilter/SimpleVideoFilter-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -382,9 +393,11 @@ BCB5DDE414E86899000AF3C2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "SimpleVideoFilter/SimpleVideoFilter-Prefix.pch"; INFOPLIST_FILE = "SimpleVideoFilter/SimpleVideoFilter-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 6.0; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.m b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.m index 7f30d620f..bbe0aaba4 100755 --- a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.m +++ b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.m @@ -1,4 +1,5 @@ #import "SimpleVideoFilterViewController.h" +#import @implementation SimpleVideoFilterViewController @@ -88,6 +89,26 @@ - (void)viewDidLoad [movieWriter finishRecording]; NSLog(@"Movie completed"); + ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; + if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:movieURL]) + { + [library writeVideoAtPathToSavedPhotosAlbum:movieURL completionBlock:^(NSURL *assetURL, NSError *error) + { + dispatch_async(dispatch_get_main_queue(), ^{ + + if (error) { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Saving Failed" + delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [alert show]; + } else { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Saved" message:@"Saved To Photo Album" + delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; + [alert show]; + } + }); + }]; + } + // [videoCamera.inputCamera lockForConfiguration:nil]; // [videoCamera.inputCamera setTorchMode:AVCaptureTorchModeOff]; // [videoCamera.inputCamera unlockForConfiguration]; diff --git a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.xib b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.xib index 1213d5a75..5b6df9cd5 100755 --- a/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.xib +++ b/examples/iOS/SimpleVideoFilter/SimpleVideoFilter/SimpleVideoFilterViewController.xib @@ -1,174 +1,30 @@ - - - - 1280 - 11D50 - 2182 - 1138.32 - 568.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1179 - - - IBProxyObject - IBUIView - IBUISlider - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 266 - {{18, 418}, {284, 23}} - - - - _NS:623 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - - - {{0, 20}, {320, 460}} - - - - - 3 - MQA - - 2 - - - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - updateSliderValue: - - - 13 - - 6 - - - - - - 0 - - - - - - 1 - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - - - SimpleVideoFilterViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - GPUImageView - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 6 - - - - - GPUImageView - UIView - - IBProjectSource - ./Classes/GPUImageView.h - - - - SimpleVideoFilterViewController - UIViewController - - updateSliderValue: - id - - - updateSliderValue: - - updateSliderValue: - id - - - - IBProjectSource - ./Classes/SimpleVideoFilterViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 1179 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/framework/GPUImage.xcodeproj/project.pbxproj b/framework/GPUImage.xcodeproj/project.pbxproj index 08b6610b2..462f2f285 100644 --- a/framework/GPUImage.xcodeproj/project.pbxproj +++ b/framework/GPUImage.xcodeproj/project.pbxproj @@ -29,10 +29,18 @@ 46869530155AACAC0060BA43 /* GPUImageSourceOverBlendFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4686952E155AACAC0060BA43 /* GPUImageSourceOverBlendFilter.m */; }; 46A8097816B8A48E000C29ED /* GPUImageTwoInputCrossTextureSamplingFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 46A8097616B8A48E000C29ED /* GPUImageTwoInputCrossTextureSamplingFilter.h */; }; 46A8097916B8A48E000C29ED /* GPUImageTwoInputCrossTextureSamplingFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A8097716B8A48E000C29ED /* GPUImageTwoInputCrossTextureSamplingFilter.m */; }; + 574B5D8A1BEA3CC000F4EC5A /* GPUImageColorConversion.m in Sources */ = {isa = PBXBuildFile; fileRef = 574B5D891BEA3CC000F4EC5A /* GPUImageColorConversion.m */; }; + 574B5D8B1BEA3CC000F4EC5A /* GPUImageColorConversion.m in Sources */ = {isa = PBXBuildFile; fileRef = 574B5D891BEA3CC000F4EC5A /* GPUImageColorConversion.m */; }; + 574B5D8D1BEA3E5B00F4EC5A /* GPUImageColorConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 574B5D8C1BEA3E5B00F4EC5A /* GPUImageColorConversion.h */; }; + 574B5D8E1BEA3E5B00F4EC5A /* GPUImageColorConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 574B5D8C1BEA3E5B00F4EC5A /* GPUImageColorConversion.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6D13DBE6151AA804000B23BA /* GPUImageHazeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D13DBE4151AA804000B23BA /* GPUImageHazeFilter.h */; }; 6D13DBE7151AA804000B23BA /* GPUImageHazeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D13DBE5151AA804000B23BA /* GPUImageHazeFilter.m */; }; 6EE27493150E8FC60040DDB6 /* GPUImageGrayscaleFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE27491150E8FC50040DDB6 /* GPUImageGrayscaleFilter.h */; }; 6EE27494150E8FC60040DDB6 /* GPUImageGrayscaleFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6EE27492150E8FC50040DDB6 /* GPUImageGrayscaleFilter.m */; }; + 79F8FD151C8B2A620095AB3E /* GPUImageSolarizeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 79F8FD131C8B2A620095AB3E /* GPUImageSolarizeFilter.h */; }; + 79F8FD161C8B2A620095AB3E /* GPUImageSolarizeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 79F8FD141C8B2A620095AB3E /* GPUImageSolarizeFilter.m */; }; + 79F8FD171C8B2AA00095AB3E /* GPUImageSolarizeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 79F8FD131C8B2A620095AB3E /* GPUImageSolarizeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79F8FD181C8B2AA60095AB3E /* GPUImageSolarizeFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 79F8FD141C8B2A620095AB3E /* GPUImageSolarizeFilter.m */; }; 83AE9F981540DFE500F7FC13 /* GPUImageSubtractBlendFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83AE9F961540DFE400F7FC13 /* GPUImageSubtractBlendFilter.h */; }; 83AE9F991540DFE500F7FC13 /* GPUImageSubtractBlendFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 83AE9F971540DFE500F7FC13 /* GPUImageSubtractBlendFilter.m */; }; 83AE9FCD1540E92800F7FC13 /* GPUImageMaskFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83AE9FCB1540E92800F7FC13 /* GPUImageMaskFilter.h */; }; @@ -107,8 +115,16 @@ BC245DCB14DDBED7009FE7EB /* GPUImageFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC245DC914DDBED7009FE7EB /* GPUImageFilter.m */; }; BC27A3CB15654F5A004F2D45 /* GPUImagePerlinNoiseFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC27A3C915654F5A004F2D45 /* GPUImagePerlinNoiseFilter.h */; }; BC27A3CC15654F5A004F2D45 /* GPUImagePerlinNoiseFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC27A3CA15654F5A004F2D45 /* GPUImagePerlinNoiseFilter.m */; }; + BC3AA4B21C11104B003B7561 /* GPUImageColourFASTFeatureDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = BC44A42C1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BC3AA4B31C11104E003B7561 /* GPUImageColourFASTSamplingOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC44A42E1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BC3AA4B41C111054003B7561 /* GPUImageColourFASTFeatureDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = BC44A42D1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.m */; }; + BC3AA4B51C111057003B7561 /* GPUImageColourFASTSamplingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = BC44A42F1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.m */; }; BC3AC8B015E6F6170065144E /* GPUImageAverageColor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3AC8AE15E6F6170065144E /* GPUImageAverageColor.h */; }; BC3AC8B115E6F6170065144E /* GPUImageAverageColor.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3AC8AF15E6F6170065144E /* GPUImageAverageColor.m */; }; + BC44A4301C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.h in Headers */ = {isa = PBXBuildFile; fileRef = BC44A42C1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.h */; }; + BC44A4311C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = BC44A42D1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.m */; }; + BC44A4321C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC44A42E1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.h */; }; + BC44A4331C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = BC44A42F1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.m */; }; BC4D03CF160919AE00F64358 /* GPUImageHalftoneFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC4D03CD160919AE00F64358 /* GPUImageHalftoneFilter.h */; }; BC4D03D0160919AE00F64358 /* GPUImageHalftoneFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC4D03CE160919AE00F64358 /* GPUImageHalftoneFilter.m */; }; BC54D563151904FF003F4A41 /* GPUImageChromaKeyBlendFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BC54D561151904FF003F4A41 /* GPUImageChromaKeyBlendFilter.h */; }; @@ -187,6 +203,10 @@ BCA632871623D18B00EEB24F /* GPUImageParallelCoordinateLineTransformFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA632851623D18B00EEB24F /* GPUImageParallelCoordinateLineTransformFilter.m */; }; BCA6328A1623DD0E00EEB24F /* GPUImageThresholdSketchFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCA632881623DD0E00EEB24F /* GPUImageThresholdSketchFilter.h */; }; BCA6328B1623DD0E00EEB24F /* GPUImageThresholdSketchFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCA632891623DD0E00EEB24F /* GPUImageThresholdSketchFilter.m */; }; + BCAA73BC1C18E42400BC2D31 /* GPUImageFourInputFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCAA73BA1C18E42400BC2D31 /* GPUImageFourInputFilter.h */; }; + BCAA73BD1C18E42400BC2D31 /* GPUImageFourInputFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAA73BB1C18E42400BC2D31 /* GPUImageFourInputFilter.m */; }; + BCAA73BE1C18E42D00BC2D31 /* GPUImageFourInputFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCAA73BA1C18E42400BC2D31 /* GPUImageFourInputFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BCAA73BF1C18E43400BC2D31 /* GPUImageFourInputFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCAA73BB1C18E42400BC2D31 /* GPUImageFourInputFilter.m */; }; BCABED8E15263CF20098A93E /* GPUImagePolarPixellateFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCABED8A15263CF20098A93E /* GPUImagePolarPixellateFilter.h */; }; BCABED8F15263CF20098A93E /* GPUImagePolarPixellateFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCABED8B15263CF20098A93E /* GPUImagePolarPixellateFilter.m */; }; BCABED9015263CF20098A93E /* GPUImageStretchDistortionFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCABED8C15263CF20098A93E /* GPUImageStretchDistortionFilter.h */; }; @@ -682,12 +702,17 @@ BCF866C8172589A500912E34 /* GPUImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BC245DBF14DDBCF5009FE7EB /* GPUImage.h */; }; BCFB588715E03E4F00750F12 /* GPUImageLanczosResamplingFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFB588515E03E4F00750F12 /* GPUImageLanczosResamplingFilter.h */; }; BCFB588815E03E4F00750F12 /* GPUImageLanczosResamplingFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFB588615E03E4F00750F12 /* GPUImageLanczosResamplingFilter.m */; }; + BCFC5F661C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFC5F641C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.h */; }; + BCFC5F671C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFC5F651C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.m */; }; + BCFC5F681C18C3D300C7F43B /* GPUImageColorLocalBinaryPatternFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFC5F641C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BCFC5F691C18C3E200C7F43B /* GPUImageColorLocalBinaryPatternFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFC5F651C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.m */; }; BEBE83B5155C092A00EEF8C3 /* GPUImageRGBFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = BEBE83B3155C092A00EEF8C3 /* GPUImageRGBFilter.h */; }; BEBE83B6155C092A00EEF8C3 /* GPUImageRGBFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = BEBE83B4155C092A00EEF8C3 /* GPUImageRGBFilter.m */; }; C04C8D1715F8059F00449601 /* GPUImageColorBlendFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = C04C8D1515F8059F00449601 /* GPUImageColorBlendFilter.h */; }; C04C8D1815F8059F00449601 /* GPUImageColorBlendFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = C04C8D1615F8059F00449601 /* GPUImageColorBlendFilter.m */; }; C2EDA90615BB136D007CBA0F /* GPUImageHueFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = C2EDA90415BB136D007CBA0F /* GPUImageHueFilter.h */; }; C2EDA90715BB136D007CBA0F /* GPUImageHueFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = C2EDA90515BB136D007CBA0F /* GPUImageHueFilter.m */; }; + D30ACF231BAFE3DD00E9759C /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D30ACF221BAFE3DD00E9759C /* AssetsLibrary.framework */; }; D443237A17C81C0C00204484 /* GPUImageMovieComposition.h in Headers */ = {isa = PBXBuildFile; fileRef = D443237817C81C0C00204484 /* GPUImageMovieComposition.h */; }; D443237B17C81C0C00204484 /* GPUImageMovieComposition.m in Sources */ = {isa = PBXBuildFile; fileRef = D443237917C81C0C00204484 /* GPUImageMovieComposition.m */; }; /* End PBXBuildFile section */ @@ -709,10 +734,14 @@ 46A8097716B8A48E000C29ED /* GPUImageTwoInputCrossTextureSamplingFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageTwoInputCrossTextureSamplingFilter.m; path = Source/GPUImageTwoInputCrossTextureSamplingFilter.m; sourceTree = SOURCE_ROOT; }; 46A8097B16B8A6A2000C29ED /* GPUImagePoissonBlendFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImagePoissonBlendFilter.h; path = Source/GPUImagePoissonBlendFilter.h; sourceTree = SOURCE_ROOT; }; 46A8097C16B8A6A2000C29ED /* GPUImagePoissonBlendFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImagePoissonBlendFilter.m; path = Source/GPUImagePoissonBlendFilter.m; sourceTree = SOURCE_ROOT; }; + 574B5D891BEA3CC000F4EC5A /* GPUImageColorConversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageColorConversion.m; path = Source/GPUImageColorConversion.m; sourceTree = SOURCE_ROOT; }; + 574B5D8C1BEA3E5B00F4EC5A /* GPUImageColorConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageColorConversion.h; path = Source/GPUImageColorConversion.h; sourceTree = SOURCE_ROOT; }; 6D13DBE4151AA804000B23BA /* GPUImageHazeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageHazeFilter.h; path = Source/GPUImageHazeFilter.h; sourceTree = SOURCE_ROOT; }; 6D13DBE5151AA804000B23BA /* GPUImageHazeFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageHazeFilter.m; path = Source/GPUImageHazeFilter.m; sourceTree = SOURCE_ROOT; }; 6EE27491150E8FC50040DDB6 /* GPUImageGrayscaleFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageGrayscaleFilter.h; path = Source/GPUImageGrayscaleFilter.h; sourceTree = SOURCE_ROOT; }; 6EE27492150E8FC50040DDB6 /* GPUImageGrayscaleFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageGrayscaleFilter.m; path = Source/GPUImageGrayscaleFilter.m; sourceTree = SOURCE_ROOT; }; + 79F8FD131C8B2A620095AB3E /* GPUImageSolarizeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageSolarizeFilter.h; path = Source/GPUImageSolarizeFilter.h; sourceTree = SOURCE_ROOT; }; + 79F8FD141C8B2A620095AB3E /* GPUImageSolarizeFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageSolarizeFilter.m; path = Source/GPUImageSolarizeFilter.m; sourceTree = SOURCE_ROOT; }; 83AE9F961540DFE400F7FC13 /* GPUImageSubtractBlendFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageSubtractBlendFilter.h; path = Source/GPUImageSubtractBlendFilter.h; sourceTree = SOURCE_ROOT; }; 83AE9F971540DFE500F7FC13 /* GPUImageSubtractBlendFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageSubtractBlendFilter.m; path = Source/GPUImageSubtractBlendFilter.m; sourceTree = SOURCE_ROOT; }; 83AE9FCB1540E92800F7FC13 /* GPUImageMaskFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageMaskFilter.h; path = Source/GPUImageMaskFilter.h; sourceTree = SOURCE_ROOT; }; @@ -788,6 +817,10 @@ BC27A3CA15654F5A004F2D45 /* GPUImagePerlinNoiseFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImagePerlinNoiseFilter.m; path = Source/GPUImagePerlinNoiseFilter.m; sourceTree = SOURCE_ROOT; }; BC3AC8AE15E6F6170065144E /* GPUImageAverageColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageAverageColor.h; path = Source/GPUImageAverageColor.h; sourceTree = SOURCE_ROOT; }; BC3AC8AF15E6F6170065144E /* GPUImageAverageColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageAverageColor.m; path = Source/GPUImageAverageColor.m; sourceTree = SOURCE_ROOT; }; + BC44A42C1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageColourFASTFeatureDetector.h; path = Source/GPUImageColourFASTFeatureDetector.h; sourceTree = SOURCE_ROOT; }; + BC44A42D1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageColourFASTFeatureDetector.m; path = Source/GPUImageColourFASTFeatureDetector.m; sourceTree = SOURCE_ROOT; }; + BC44A42E1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageColourFASTSamplingOperation.h; path = Source/GPUImageColourFASTSamplingOperation.h; sourceTree = SOURCE_ROOT; }; + BC44A42F1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageColourFASTSamplingOperation.m; path = Source/GPUImageColourFASTSamplingOperation.m; sourceTree = SOURCE_ROOT; }; BC4D03CD160919AE00F64358 /* GPUImageHalftoneFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageHalftoneFilter.h; path = Source/GPUImageHalftoneFilter.h; sourceTree = SOURCE_ROOT; }; BC4D03CE160919AE00F64358 /* GPUImageHalftoneFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageHalftoneFilter.m; path = Source/GPUImageHalftoneFilter.m; sourceTree = SOURCE_ROOT; }; BC54D561151904FF003F4A41 /* GPUImageChromaKeyBlendFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageChromaKeyBlendFilter.h; path = Source/GPUImageChromaKeyBlendFilter.h; sourceTree = SOURCE_ROOT; }; @@ -857,6 +890,8 @@ BCA632851623D18B00EEB24F /* GPUImageParallelCoordinateLineTransformFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageParallelCoordinateLineTransformFilter.m; path = Source/GPUImageParallelCoordinateLineTransformFilter.m; sourceTree = SOURCE_ROOT; }; BCA632881623DD0E00EEB24F /* GPUImageThresholdSketchFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageThresholdSketchFilter.h; path = Source/GPUImageThresholdSketchFilter.h; sourceTree = SOURCE_ROOT; }; BCA632891623DD0E00EEB24F /* GPUImageThresholdSketchFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageThresholdSketchFilter.m; path = Source/GPUImageThresholdSketchFilter.m; sourceTree = SOURCE_ROOT; }; + BCAA73BA1C18E42400BC2D31 /* GPUImageFourInputFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageFourInputFilter.h; path = Source/GPUImageFourInputFilter.h; sourceTree = SOURCE_ROOT; }; + BCAA73BB1C18E42400BC2D31 /* GPUImageFourInputFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageFourInputFilter.m; path = Source/GPUImageFourInputFilter.m; sourceTree = SOURCE_ROOT; }; BCABED8A15263CF20098A93E /* GPUImagePolarPixellateFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImagePolarPixellateFilter.h; path = Source/GPUImagePolarPixellateFilter.h; sourceTree = SOURCE_ROOT; }; BCABED8B15263CF20098A93E /* GPUImagePolarPixellateFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImagePolarPixellateFilter.m; path = Source/GPUImagePolarPixellateFilter.m; sourceTree = SOURCE_ROOT; }; BCABED8C15263CF20098A93E /* GPUImageStretchDistortionFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageStretchDistortionFilter.h; path = Source/GPUImageStretchDistortionFilter.h; sourceTree = SOURCE_ROOT; }; @@ -1027,12 +1062,15 @@ BCF851BE15CF5D59000EBC8B /* GPUImageLocalBinaryPatternFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageLocalBinaryPatternFilter.m; path = Source/GPUImageLocalBinaryPatternFilter.m; sourceTree = SOURCE_ROOT; }; BCFB588515E03E4F00750F12 /* GPUImageLanczosResamplingFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageLanczosResamplingFilter.h; path = Source/GPUImageLanczosResamplingFilter.h; sourceTree = SOURCE_ROOT; }; BCFB588615E03E4F00750F12 /* GPUImageLanczosResamplingFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageLanczosResamplingFilter.m; path = Source/GPUImageLanczosResamplingFilter.m; sourceTree = SOURCE_ROOT; }; + BCFC5F641C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageColorLocalBinaryPatternFilter.h; path = Source/GPUImageColorLocalBinaryPatternFilter.h; sourceTree = SOURCE_ROOT; }; + BCFC5F651C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageColorLocalBinaryPatternFilter.m; path = Source/GPUImageColorLocalBinaryPatternFilter.m; sourceTree = SOURCE_ROOT; }; BEBE83B3155C092A00EEF8C3 /* GPUImageRGBFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageRGBFilter.h; path = Source/GPUImageRGBFilter.h; sourceTree = SOURCE_ROOT; }; BEBE83B4155C092A00EEF8C3 /* GPUImageRGBFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageRGBFilter.m; path = Source/GPUImageRGBFilter.m; sourceTree = SOURCE_ROOT; }; C04C8D1515F8059F00449601 /* GPUImageColorBlendFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageColorBlendFilter.h; path = Source/GPUImageColorBlendFilter.h; sourceTree = SOURCE_ROOT; }; C04C8D1615F8059F00449601 /* GPUImageColorBlendFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageColorBlendFilter.m; path = Source/GPUImageColorBlendFilter.m; sourceTree = SOURCE_ROOT; }; C2EDA90415BB136D007CBA0F /* GPUImageHueFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageHueFilter.h; path = Source/GPUImageHueFilter.h; sourceTree = SOURCE_ROOT; }; C2EDA90515BB136D007CBA0F /* GPUImageHueFilter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageHueFilter.m; path = Source/GPUImageHueFilter.m; sourceTree = SOURCE_ROOT; }; + D30ACF221BAFE3DD00E9759C /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; D443237817C81C0C00204484 /* GPUImageMovieComposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GPUImageMovieComposition.h; path = Source/GPUImageMovieComposition.h; sourceTree = SOURCE_ROOT; }; D443237917C81C0C00204484 /* GPUImageMovieComposition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPUImageMovieComposition.m; path = Source/GPUImageMovieComposition.m; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -1056,6 +1094,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D30ACF231BAFE3DD00E9759C /* AssetsLibrary.framework in Frameworks */, BCB5E77914E20BAF00701302 /* CoreMedia.framework in Frameworks */, BCB5E77714E20BA800701302 /* CoreVideo.framework in Frameworks */, BCB5E77514E20B9700701302 /* OpenGLES.framework in Frameworks */, @@ -1117,6 +1156,8 @@ BCC94ABA151E4FD6008554B4 /* GPUImageLuminanceThresholdFilter.m */, BCC1E5CA151EA6610006EFA5 /* GPUImageAdaptiveThresholdFilter.h */, BCC1E5CB151EA6610006EFA5 /* GPUImageAdaptiveThresholdFilter.m */, + 79F8FD131C8B2A620095AB3E /* GPUImageSolarizeFilter.h */, + 79F8FD141C8B2A620095AB3E /* GPUImageSolarizeFilter.m */, BCB79E7815EC2A8300965D92 /* GPUImageAverageLuminanceThresholdFilter.h */, BCB79E7915EC2A8300965D92 /* GPUImageAverageLuminanceThresholdFilter.m */, BC6ED9C01549CA0600966798 /* GPUImageHistogramFilter.h */, @@ -1282,6 +1323,8 @@ BC114897155AF65400F107AF /* GPUImageTwoInputFilter.m */, BCB030BC173400BC001A1A20 /* GPUImageThreeInputFilter.h */, BCB030BD173400BC001A1A20 /* GPUImageThreeInputFilter.m */, + BCAA73BA1C18E42400BC2D31 /* GPUImageFourInputFilter.h */, + BCAA73BB1C18E42400BC2D31 /* GPUImageFourInputFilter.m */, BCC93A1C1501E42E00958B26 /* GPUImageTwoPassFilter.h */, BCC93A1D1501E42F00958B26 /* GPUImageTwoPassFilter.m */, BC0690B6157C0C27009274F9 /* GPUImageTwoPassTextureSamplingFilter.h */, @@ -1325,6 +1368,8 @@ BCF1E641156AB332006B155F /* GPUImageRawDataInput.m */, BC56D8281579779700CC9C1E /* GPUImageUIElement.h */, BC56D8291579779700CC9C1E /* GPUImageUIElement.m */, + 574B5D8C1BEA3E5B00F4EC5A /* GPUImageColorConversion.h */, + 574B5D891BEA3CC000F4EC5A /* GPUImageColorConversion.m */, ); name = Sources; sourceTree = ""; @@ -1425,6 +1470,8 @@ BC0690F6157C5075009274F9 /* GPUImageColorPackingFilter.m */, BCF851BD15CF5D59000EBC8B /* GPUImageLocalBinaryPatternFilter.h */, BCF851BE15CF5D59000EBC8B /* GPUImageLocalBinaryPatternFilter.m */, + BCFC5F641C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.h */, + BCFC5F651C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.m */, BCFB588515E03E4F00750F12 /* GPUImageLanczosResamplingFilter.h */, BCFB588615E03E4F00750F12 /* GPUImageLanczosResamplingFilter.m */, BCB3B46315F2BA9300EDA3BE /* GPUImageLowPassFilter.h */, @@ -1445,6 +1492,10 @@ BCBC605616C8527C00B11741 /* GPUImageZoomBlurFilter.m */, BC8A583A1813060F00E6B507 /* GPUImageiOSBlurFilter.h */, BC8A583B1813060F00E6B507 /* GPUImageiOSBlurFilter.m */, + BC44A42C1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.h */, + BC44A42D1C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.m */, + BC44A42E1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.h */, + BC44A42F1C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.m */, ); name = "Image processing"; sourceTree = ""; @@ -1470,6 +1521,7 @@ BCF1A33614DDB1EC00852800 /* Frameworks */ = { isa = PBXGroup; children = ( + D30ACF221BAFE3DD00E9759C /* AssetsLibrary.framework */, BCB5E77814E20BAF00701302 /* CoreMedia.framework */, BCB5E77614E20BA800701302 /* CoreVideo.framework */, BCB5E77414E20B9700701302 /* OpenGLES.framework */, @@ -1658,6 +1710,7 @@ BCD81F11194404F3007133DB /* GPUImagePixellatePositionFilter.h in Headers */, BCD81F12194404F4007133DB /* GPUImagePolkaDotFilter.h in Headers */, BCD81F13194404F4007133DB /* GPUImageHalftoneFilter.h in Headers */, + BCFC5F681C18C3D300C7F43B /* GPUImageColorLocalBinaryPatternFilter.h in Headers */, BCD81F14194404F4007133DB /* GPUImagePolarPixellateFilter.h in Headers */, BCD81F15194404F4007133DB /* GPUImageCrosshatchFilter.h in Headers */, BCD81F16194404F4007133DB /* GPUImageSketchFilter.h in Headers */, @@ -1679,10 +1732,15 @@ BCD81F26194404F7007133DB /* GPUImageJFAVoronoiFilter.h in Headers */, BCD81F27194404F7007133DB /* GPUImageMosaicFilter.h in Headers */, BCD81F28194404F7007133DB /* GPUImageVoronoiConsumerFilter.h in Headers */, + BCAA73BE1C18E42D00BC2D31 /* GPUImageFourInputFilter.h in Headers */, BCD81F29194404F7007133DB /* GPUImageView.h in Headers */, BCD81F2A194404F7007133DB /* GPUImageMovieWriter.h in Headers */, BCD81F2B194404F8007133DB /* GPUImageTextureOutput.h in Headers */, + 574B5D8E1BEA3E5B00F4EC5A /* GPUImageColorConversion.h in Headers */, BCD81F2C194404F8007133DB /* GPUImageRawDataOutput.h in Headers */, + 79F8FD171C8B2AA00095AB3E /* GPUImageSolarizeFilter.h in Headers */, + BC3AA4B21C11104B003B7561 /* GPUImageColourFASTFeatureDetector.h in Headers */, + BC3AA4B31C11104E003B7561 /* GPUImageColourFASTSamplingOperation.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1691,6 +1749,7 @@ buildActionMask = 2147483647; files = ( BC8A583C1813060F00E6B507 /* GPUImageiOSBlurFilter.h in Headers */, + 79F8FD151C8B2A620095AB3E /* GPUImageSolarizeFilter.h in Headers */, BCF866C8172589A500912E34 /* GPUImage.h in Headers */, BC245DCA14DDBED7009FE7EB /* GPUImageFilter.h in Headers */, BCB5E75C14E2086300701302 /* GPUImageView.h in Headers */, @@ -1712,6 +1771,7 @@ BC982BED14F1CE600001FF6F /* GPUImageMultiplyBlendFilter.h in Headers */, BC982C4714F29E580001FF6F /* GPUImageKuwaharaFilter.h in Headers */, BC982C6E14F33C2A0001FF6F /* GPUImageMovie.h in Headers */, + BCAA73BC1C18E42400BC2D31 /* GPUImageFourInputFilter.h in Headers */, BC982C7014F33C2A0001FF6F /* GPUImageOverlayBlendFilter.h in Headers */, BC982C8114F34F0C0001FF6F /* GPUImageDarkenBlendFilter.h in Headers */, BC982C8314F34F0C0001FF6F /* GPUImageLightenBlendFilter.h in Headers */, @@ -1755,6 +1815,7 @@ BCC1E66B152368130006EFA5 /* GPUImageCGAColorspaceFilter.h in Headers */, BCC1E66D152368130006EFA5 /* GPUImageCrosshatchFilter.h in Headers */, BC7D95D51523EE67000DF037 /* GPUImageStillCamera.h in Headers */, + BCFC5F661C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.h in Headers */, BCABED8E15263CF20098A93E /* GPUImagePolarPixellateFilter.h in Headers */, BCBF617A16E4F44600E2784A /* GPUImageKuwaharaRadius3Filter.h in Headers */, BCABED9015263CF20098A93E /* GPUImageStretchDistortionFilter.h in Headers */, @@ -1770,6 +1831,7 @@ BC6ED9C21549CA0600966798 /* GPUImageHistogramFilter.h in Headers */, BCC11D72154B44DC0044F5A0 /* GPUImageHistogramGenerator.h in Headers */, BCAD0978154F39CA00278521 /* GPUImagePrewittEdgeDetectionFilter.h in Headers */, + BC44A4321C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.h in Headers */, BCAD097D154F3CB000278521 /* GPUImageXYDerivativeFilter.h in Headers */, BCAD0981154F7B2800278521 /* GPUImageHarrisCornerDetectionFilter.h in Headers */, BCAD0985154F931C00278521 /* GPUImageAlphaBlendFilter.h in Headers */, @@ -1802,6 +1864,7 @@ BC0690D0157C2EBA009274F9 /* GPUImageRGBDilationFilter.h in Headers */, BC1BBFA8193BC55B0025FC88 /* GPUImageFASTCornerDetectionFilter.h in Headers */, BC0690D5157C31C9009274F9 /* GPUImageRGBErosionFilter.h in Headers */, + BC44A4301C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.h in Headers */, BC0690D9157C33B9009274F9 /* GPUImageRGBOpeningFilter.h in Headers */, BC0690DD157C344D009274F9 /* GPUImageRGBClosingFilter.h in Headers */, BC0690F7157C5075009274F9 /* GPUImageColorPackingFilter.h in Headers */, @@ -1856,6 +1919,7 @@ BCB030BE173400BC001A1A20 /* GPUImageThreeInputFilter.h in Headers */, BCC887CC18A1CEEB008DB37D /* GPUImageFramebuffer.h in Headers */, BCC887D018A1D3AD008DB37D /* GPUImageFramebufferCache.h in Headers */, + 574B5D8D1BEA3E5B00F4EC5A /* GPUImageColorConversion.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1904,7 +1968,7 @@ isa = PBXProject; attributes = { LastTestingUpgradeCheck = 0510; - LastUpgradeCheck = 0600; + LastUpgradeCheck = 0700; ORGANIZATIONNAME = "Brad Larson"; TargetAttributes = { BCE209E41943F20C002FEED8 = { @@ -1995,6 +2059,7 @@ BCD81F4B19440604007133DB /* GPUImageRGBFilter.m in Sources */, BCD81F4C19440604007133DB /* GPUImageHSBFilter.m in Sources */, BCD81F4D19440604007133DB /* GPUImageHueFilter.m in Sources */, + 79F8FD181C8B2AA60095AB3E /* GPUImageSolarizeFilter.m in Sources */, BCD81F4E19440604007133DB /* GPUImageMonochromeFilter.m in Sources */, BCD81F4F19440604007133DB /* GPUImageFalseColorFilter.m in Sources */, BCD81F5019440604007133DB /* GPUImageHazeFilter.m in Sources */, @@ -2073,6 +2138,7 @@ BCD81F9919440605007133DB /* GPUImageColorDodgeBlendFilter.m in Sources */, BCD81F9A19440605007133DB /* GPUImageDarkenBlendFilter.m in Sources */, BCD81F9B19440605007133DB /* GPUImageDifferenceBlendFilter.m in Sources */, + BCAA73BF1C18E43400BC2D31 /* GPUImageFourInputFilter.m in Sources */, BCD81F9C19440605007133DB /* GPUImageDissolveBlendFilter.m in Sources */, BCD81F9D19440605007133DB /* GPUImageExclusionBlendFilter.m in Sources */, BCD81F9E19440605007133DB /* GPUImageHardLightBlendFilter.m in Sources */, @@ -2120,10 +2186,14 @@ BCD81FC819440606007133DB /* GPUImageJFAVoronoiFilter.m in Sources */, BCD81FC919440606007133DB /* GPUImageMosaicFilter.m in Sources */, BCD81FCA19440606007133DB /* GPUImageVoronoiConsumerFilter.m in Sources */, + BCFC5F691C18C3E200C7F43B /* GPUImageColorLocalBinaryPatternFilter.m in Sources */, BCD81FCB19440606007133DB /* GPUImageView.m in Sources */, BCD81FCC19440606007133DB /* GPUImageMovieWriter.m in Sources */, BCD81FCD19440606007133DB /* GPUImageTextureOutput.m in Sources */, BCD81FCE19440606007133DB /* GPUImageRawDataOutput.m in Sources */, + 574B5D8B1BEA3CC000F4EC5A /* GPUImageColorConversion.m in Sources */, + BC3AA4B41C111054003B7561 /* GPUImageColourFASTFeatureDetector.m in Sources */, + BC3AA4B51C111057003B7561 /* GPUImageColourFASTSamplingOperation.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2143,6 +2213,7 @@ BC982B5414F07F790001FF6F /* GPUImageColorInvertFilter.m in Sources */, BC982B5614F07F790001FF6F /* GPUImageSaturationFilter.m in Sources */, BC982B6814F092EF0001FF6F /* GPUImageContrastFilter.m in Sources */, + BCAA73BD1C18E42400BC2D31 /* GPUImageFourInputFilter.m in Sources */, BC982B7A14F098CC0001FF6F /* GPUImageBrightnessFilter.m in Sources */, BC982B7F14F09F980001FF6F /* GPUImageGammaFilter.m in Sources */, BC982B9A14F0B34E0001FF6F /* GPUImageSobelEdgeDetectionFilter.m in Sources */, @@ -2181,6 +2252,7 @@ 6EE27494150E8FC60040DDB6 /* GPUImageGrayscaleFilter.m in Sources */, BCC94CFB15101EB3002F9BC5 /* GPUImageTransformFilter.m in Sources */, BC54D564151904FF003F4A41 /* GPUImageChromaKeyBlendFilter.m in Sources */, + BC44A4331C110D4500B0DAA0 /* GPUImageColourFASTSamplingOperation.m in Sources */, 6D13DBE7151AA804000B23BA /* GPUImageHazeFilter.m in Sources */, BCC94ABC151E4FD6008554B4 /* GPUImageLuminanceThresholdFilter.m in Sources */, BCC1E5A9151E74B20006EFA5 /* GPUImagePosterizeFilter.m in Sources */, @@ -2196,6 +2268,7 @@ BCABED8F15263CF20098A93E /* GPUImagePolarPixellateFilter.m in Sources */, BCABED9115263CF20098A93E /* GPUImageStretchDistortionFilter.m in Sources */, BCF3D68C153CC124009A1FE5 /* GPUImageTextureInput.m in Sources */, + BC44A4311C110D4500B0DAA0 /* GPUImageColourFASTFeatureDetector.m in Sources */, BCF3D6DE153CFF61009A1FE5 /* GPUImageTiltShiftFilter.m in Sources */, BCF3D70B153DCC9A009A1FE5 /* GPUImage3x3ConvolutionFilter.m in Sources */, BCF3D710153DF9E7009A1FE5 /* GPUImageEmbossFilter.m in Sources */, @@ -2261,6 +2334,7 @@ BCFB588815E03E4F00750F12 /* GPUImageLanczosResamplingFilter.m in Sources */, BC3AC8B115E6F6170065144E /* GPUImageAverageColor.m in Sources */, BCB79E1115EBE1A700965D92 /* GPUImageSolidColorGenerator.m in Sources */, + BCFC5F671C18C3B100C7F43B /* GPUImageColorLocalBinaryPatternFilter.m in Sources */, BCB79E6015EC131A00965D92 /* GPUImageLuminosity.m in Sources */, BCB79E7B15EC2A8400965D92 /* GPUImageAverageLuminanceThresholdFilter.m in Sources */, BC99234F15EFFC8700ED2C8C /* GPUImageChromaKeyFilter.m in Sources */, @@ -2288,6 +2362,7 @@ 84FFC80C1936408F00994258 /* GPUImagePicture+TextureSubimage.m in Sources */, BCBC604E16C58B0900B11741 /* GPUImageMotionBlurFilter.m in Sources */, BCBC605816C8527C00B11741 /* GPUImageZoomBlurFilter.m in Sources */, + 79F8FD161C8B2A620095AB3E /* GPUImageSolarizeFilter.m in Sources */, BCBF617B16E4F44700E2784A /* GPUImageKuwaharaRadius3Filter.m in Sources */, BC6C55411730679D00EB222D /* GPUImageLaplacianFilter.m in Sources */, BCB030BF173400BC001A1A20 /* GPUImageThreeInputFilter.m in Sources */, @@ -2295,6 +2370,7 @@ BC8A583D1813060F00E6B507 /* GPUImageiOSBlurFilter.m in Sources */, BCC887CD18A1CEEB008DB37D /* GPUImageFramebuffer.m in Sources */, BCC887D118A1D3AD008DB37D /* GPUImageFramebufferCache.m in Sources */, + 574B5D8A1BEA3CC000F4EC5A /* GPUImageColorConversion.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2342,6 +2418,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = Source/iOS/Framework/module.modulemap; + PRODUCT_BUNDLE_IDENTIFIER = "com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_MODULE_NAME = GPUImage; PRODUCT_NAME = GPUImage; SKIP_INSTALL = YES; @@ -2373,6 +2450,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = Source/iOS/Framework/module.modulemap; + PRODUCT_BUNDLE_IDENTIFIER = "com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_MODULE_NAME = GPUImage; PRODUCT_NAME = GPUImage; SKIP_INSTALL = YES; @@ -2397,8 +2475,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; 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", @@ -2438,6 +2518,7 @@ COPY_PHASE_STRIP = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; diff --git a/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme b/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme index 9fb5352ca..73c9f5f03 100644 --- a/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme +++ b/framework/GPUImage.xcodeproj/xcshareddata/xcschemes/Documentation.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> + + + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -39,15 +39,18 @@ + + + shouldUseLaunchSchemeArgsEnv = "YES"> + + { @@ -9,7 +10,11 @@ @interface GPUImageMovie () GPUImageMovieWriter *synchronizedMovieWriter; AVAssetReader *reader; AVPlayerItemVideoOutput *playerItemOutput; +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE CADisplayLink *displayLink; +#else + CVDisplayLinkRef displayLink; +#endif CMTime previousFrameTime, processingFrameTime; CFAbsoluteTime previousActualFrameTime; BOOL keepLooping; @@ -134,6 +139,8 @@ - (void)yuvConversionSetup; - (void)dealloc { + [playerItemOutput setDelegate:nil queue:nil]; + // Moved into endProcessing //if (self.playerItem && (displayLink != nil)) //{ @@ -214,7 +221,11 @@ - (AVAssetReader*)createAssetReader if (shouldRecordAudioTrack) { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE [self.audioEncodingTarget setShouldInvalidateAudioSampleWhenDone:YES]; +#else +#warning Missing OSX implementation +#endif // This might need to be extended to handle movies with more than one audio track AVAssetTrack* audioTrack = [audioTracks objectAtIndex:0]; @@ -255,14 +266,21 @@ - (void)processAsset if (synchronizedMovieWriter != nil) { [synchronizedMovieWriter setVideoInputReadyCallback:^{ - return [weakSelf readNextVideoFrameFromOutput:readerVideoTrackOutput]; + BOOL success = [weakSelf readNextVideoFrameFromOutput:readerVideoTrackOutput]; +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE + return success; +#endif }]; [synchronizedMovieWriter setAudioInputReadyCallback:^{ - return [weakSelf readNextAudioSampleFromOutput:readerAudioTrackOutput]; + BOOL success = [weakSelf readNextAudioSampleFromOutput:readerAudioTrackOutput]; +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE + return success; +#endif }]; - + [synchronizedMovieWriter enableSynchronizationCallbacks]; + } else { @@ -297,9 +315,24 @@ - (void)processAsset - (void)processPlayerItem { runSynchronouslyOnVideoProcessingQueue(^{ + +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkCallback:)]; [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [displayLink setPaused:YES]; +#else + // Suggested implementation: use CVDisplayLink http://stackoverflow.com/questions/14158743/alternative-of-cadisplaylink-for-mac-os-x + CGDirectDisplayID displayID = CGMainDisplayID(); + CVReturn error = kCVReturnSuccess; + error = CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink); + if (error) + { + NSLog(@"DisplayLink created with error:%d", error); + displayLink = NULL; + } + CVDisplayLinkSetOutputCallback(displayLink, renderCallback, (__bridge void *)self); + CVDisplayLinkStop(displayLink); +#endif dispatch_queue_t videoProcessingQueue = [GPUImageContext sharedContextQueue]; NSMutableDictionary *pixBuffAttributes = [NSMutableDictionary dictionary]; @@ -319,10 +352,15 @@ - (void)processPlayerItem - (void)outputMediaDataWillChange:(AVPlayerItemOutput *)sender { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE // Restart display link. [displayLink setPaused:NO]; +#else + CVDisplayLinkStart(displayLink); +#endif } +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE - (void)displayLinkCallback:(CADisplayLink *)sender { /* @@ -335,15 +373,43 @@ - (void)displayLinkCallback:(CADisplayLink *)sender CMTime outputItemTime = [playerItemOutput itemTimeForHostTime:nextVSync]; - if ([playerItemOutput hasNewPixelBufferForItemTime:outputItemTime]) { + [self processPixelBufferAtTime:outputItemTime]; + +} +#else +static CVReturn renderCallback(CVDisplayLinkRef displayLink, + const CVTimeStamp *inNow, + const CVTimeStamp *inOutputTime, + CVOptionFlags flagsIn, + CVOptionFlags *flagsOut, + void *displayLinkContext) +{ + // Sample code taken from here https://developer.apple.com/library/mac/samplecode/AVGreenScreenPlayer/Listings/AVGreenScreenPlayer_GSPlayerView_m.html + + GPUImageMovie *self = (__bridge GPUImageMovie *)displayLinkContext; + AVPlayerItemVideoOutput *playerItemOutput = self->playerItemOutput; + + + // The displayLink calls back at every vsync (screen refresh) + // Compute itemTime for the next vsync + CMTime outputItemTime = [playerItemOutput itemTimeForCVTimeStamp:*inOutputTime]; + + [self processPixelBufferAtTime:outputItemTime]; + + return kCVReturnSuccess; +} +#endif + +- (void)processPixelBufferAtTime:(CMTime)outputItemTime { + if ([playerItemOutput hasNewPixelBufferForItemTime:outputItemTime]) { __unsafe_unretained GPUImageMovie *weakSelf = self; - CVPixelBufferRef pixelBuffer = [playerItemOutput copyPixelBufferForItemTime:outputItemTime itemTimeForDisplay:NULL]; + CVPixelBufferRef pixelBuffer = [playerItemOutput copyPixelBufferForItemTime:outputItemTime itemTimeForDisplay:NULL]; if( pixelBuffer ) runSynchronouslyOnVideoProcessingQueue(^{ [weakSelf processMovieFrame:pixelBuffer withSampleTime:outputItemTime]; CFRelease(pixelBuffer); }); - } + } } - (BOOL)readNextVideoFrameFromOutput:(AVAssetReaderOutput *)readerVideoTrackOutput; @@ -507,12 +573,22 @@ - (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)cu if ([GPUImageContext supportsFastTextureUpload]) { + +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE CVOpenGLESTextureRef luminanceTextureRef = NULL; CVOpenGLESTextureRef chrominanceTextureRef = NULL; +#else + CVOpenGLTextureRef luminanceTextureRef = NULL; + CVOpenGLTextureRef chrominanceTextureRef = NULL; +#endif // if (captureAsYUV && [GPUImageContext deviceSupportsRedTextures]) if (CVPixelBufferGetPlaneCount(movieFrame) > 0) // Check for YUV planar inputs to do RGB conversion { + + // fix issue 2221 + CVPixelBufferLockBaseAddress(movieFrame,0); + if ( (imageBufferWidth != bufferWidth) && (imageBufferHeight != bufferHeight) ) { @@ -525,18 +601,30 @@ - (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)cu glActiveTexture(GL_TEXTURE4); if ([GPUImageContext deviceSupportsRedTextures]) { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, GL_TEXTURE_2D, GL_LUMINANCE, bufferWidth, bufferHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &luminanceTextureRef); +#else + err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, &luminanceTextureRef); +#endif } else { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, GL_TEXTURE_2D, GL_LUMINANCE, bufferWidth, bufferHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0, &luminanceTextureRef); +#else + err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, &luminanceTextureRef); +#endif } if (err) { NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); } +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE luminanceTexture = CVOpenGLESTextureGetName(luminanceTextureRef); +#else + luminanceTexture = CVOpenGLTextureGetName(luminanceTextureRef); +#endif glBindTexture(GL_TEXTURE_2D, luminanceTexture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -545,18 +633,30 @@ - (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)cu glActiveTexture(GL_TEXTURE5); if ([GPUImageContext deviceSupportsRedTextures]) { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, bufferWidth/2, bufferHeight/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &chrominanceTextureRef); +#else + err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, &chrominanceTextureRef); +#endif } else { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, GL_TEXTURE_2D, GL_LUMINANCE_ALPHA, bufferWidth/2, bufferHeight/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, &chrominanceTextureRef); +#else + err = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], movieFrame, NULL, &chrominanceTextureRef); +#endif } if (err) { NSLog(@"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err); } +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE chrominanceTexture = CVOpenGLESTextureGetName(chrominanceTextureRef); +#else + chrominanceTexture = CVOpenGLTextureGetName(chrominanceTextureRef); +#endif glBindTexture(GL_TEXTURE_2D, chrominanceTexture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -674,7 +774,11 @@ - (void)processMovieFrame:(CVPixelBufferRef)movieFrame withSampleTime:(CMTime)cu - (void)endProcessing; { keepLooping = NO; +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE [displayLink setPaused:YES]; +#else + CVDisplayLinkStop(displayLink); +#endif for (id currentTarget in targets) { @@ -683,14 +787,25 @@ - (void)endProcessing; if (synchronizedMovieWriter != nil) { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE [synchronizedMovieWriter setVideoInputReadyCallback:^{return NO;}]; [synchronizedMovieWriter setAudioInputReadyCallback:^{return NO;}]; +#else + // I'm not sure about this, meybe setting a nil will be more appropriate then an empty block + [synchronizedMovieWriter setVideoInputReadyCallback:^{}]; + [synchronizedMovieWriter setAudioInputReadyCallback:^{}]; +#endif } if (self.playerItem && (displayLink != nil)) { +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE [displayLink invalidate]; // remove from all run loops displayLink = nil; +#else + CVDisplayLinkStop(displayLink); + displayLink = NULL; +#endif } if ([self.delegate respondsToSelector:@selector(didCompletePlayingMovie)]) { diff --git a/framework/Source/GPUImageOutput.h b/framework/Source/GPUImageOutput.h index a1af54d70..c10121a93 100755 --- a/framework/Source/GPUImageOutput.h +++ b/framework/Source/GPUImageOutput.h @@ -17,6 +17,7 @@ typedef NS_ENUM(NSInteger, UIImageOrientation) { }; #endif +dispatch_queue_attr_t GPUImageDefaultQueueAttribute(void); void runOnMainQueueWithoutDeadlocking(void (^block)(void)); void runSynchronouslyOnVideoProcessingQueue(void (^block)(void)); void runAsynchronouslyOnVideoProcessingQueue(void (^block)(void)); diff --git a/framework/Source/GPUImageOutput.m b/framework/Source/GPUImageOutput.m index 2817a4456..d9bdaefa3 100755 --- a/framework/Source/GPUImageOutput.m +++ b/framework/Source/GPUImageOutput.m @@ -3,6 +3,17 @@ #import "GPUImagePicture.h" #import +dispatch_queue_attr_t GPUImageDefaultQueueAttribute(void) +{ +#if TARGET_OS_IPHONE + if ([[[UIDevice currentDevice] systemVersion] compare:@"9.0" options:NSNumericSearch] != NSOrderedAscending) + { + return dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0); + } +#endif + return nil; +} + void runOnMainQueueWithoutDeadlocking(void (^block)(void)) { if ([NSThread isMainThread]) diff --git a/framework/Source/GPUImageRawDataInput.m b/framework/Source/GPUImageRawDataInput.m index 4b6bfa74a..cfa3b1287 100644 --- a/framework/Source/GPUImageRawDataInput.m +++ b/framework/Source/GPUImageRawDataInput.m @@ -72,7 +72,7 @@ - (void)uploadBytes:(GLubyte *)bytesToUpload; outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:uploadedImageSize textureOptions:self.outputTextureOptions onlyTexture:YES]; glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]); - glTexImage2D(GL_TEXTURE_2D, 0, _pixelFormat==GPUPixelFormatRGB ? GL_RGB : GL_RGBA, (int)uploadedImageSize.width, (int)uploadedImageSize.height, 0, (GLint)_pixelFormat, (GLenum)_pixelType, bytesToUpload); + glTexImage2D(GL_TEXTURE_2D, 0, _pixelFormat, (int)uploadedImageSize.width, (int)uploadedImageSize.height, 0, (GLint)_pixelFormat, (GLenum)_pixelType, bytesToUpload); } - (void)updateDataFromBytes:(GLubyte *)bytesToUpload size:(CGSize)imageSize; diff --git a/framework/Source/GPUImageSkinToneFilter.h b/framework/Source/GPUImageSkinToneFilter.h new file mode 100644 index 000000000..0dd6f866c --- /dev/null +++ b/framework/Source/GPUImageSkinToneFilter.h @@ -0,0 +1,47 @@ +// +// GPUImageSkinToneFilter.h +// +// +// Created by github.com/r3mus on 8/14/15. +// +// + +#import "GPUImageTwoInputFilter.h" + +typedef NS_ENUM(NSUInteger, GPUImageSkinToneUpperColor) { + GPUImageSkinToneUpperColorGreen, + GPUImageSkinToneUpperColorOrange +}; + +extern NSString *const kGPUImageSkinToneFragmentShaderString; + +@interface GPUImageSkinToneFilter : GPUImageFilter +{ + GLint skinToneAdjustUniform; + GLint skinHueUniform; + GLint skinHueThresholdUniform; + GLint maxHueShiftUniform; + GLint maxSaturationShiftUniform; + GLint upperSkinToneColorUniform; +} + +// The amount of effect to apply, between -1.0 (pink) and +1.0 (orange OR green). Default is 0.0. +@property (nonatomic, readwrite) CGFloat skinToneAdjust; + +// The initial hue of skin to adjust. Default is 0.05 (a common skin red). +@property (nonatomic, readwrite) CGFloat skinHue; + +// The bell curve "breadth" of the skin hue adjustment (i.e. how different from the original skinHue will the modifications effect). +// Default is 40.0 +@property (nonatomic, readwrite) CGFloat skinHueThreshold; + +// The maximum amount of hue shift allowed in the adjustments that affect hue (pink, green). Default = 0.25. +@property (nonatomic, readwrite) CGFloat maxHueShift; + +// The maximum amount of saturation shift allowed in the adjustments that affect saturation (orange). Default = 0.4. +@property (nonatomic, readwrite) CGFloat maxSaturationShift; + +// Defines whether the upper range (> 0.0) will change the skin tone to green (hue) or orange (saturation) +@property (nonatomic, readwrite) GPUImageSkinToneUpperColor upperSkinToneColor; + +@end diff --git a/framework/Source/GPUImageSkinToneFilter.m b/framework/Source/GPUImageSkinToneFilter.m new file mode 100644 index 000000000..0db9ac7c9 --- /dev/null +++ b/framework/Source/GPUImageSkinToneFilter.m @@ -0,0 +1,246 @@ +// +// GPUImageSkinToneFilter.m +// +// +// Created by github.com/r3mus on 8/13/15. +// +// + +#import "GPUImageSkinToneFilter.h" + +@implementation GPUImageSkinToneFilter + +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE +NSString *const kGPUImageSkinToneFragmentShaderString = SHADER_STRING +( + varying highp vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + + // [-1;1] <=> [pink;orange] + uniform highp float skinToneAdjust; // will make reds more pink + + // Other parameters + uniform mediump float skinHue; + uniform mediump float skinHueThreshold; + uniform mediump float maxHueShift; + uniform mediump float maxSaturationShift; + uniform int upperSkinToneColor; + + // RGB <-> HSV conversion, thanks to http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl + highp vec3 rgb2hsv(highp vec3 c) +{ + highp vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + highp vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + highp vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + highp float d = q.x - min(q.w, q.y); + highp float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + + // HSV <-> RGB conversion, thanks to http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl + highp vec3 hsv2rgb(highp vec3 c) +{ + highp vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + highp vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + // Main + void main () +{ + + // Sample the input pixel + highp vec4 colorRGB = texture2D(inputImageTexture, textureCoordinate); + + // Convert color to HSV, extract hue + highp vec3 colorHSV = rgb2hsv(colorRGB.rgb); + highp float hue = colorHSV.x; + + // check how far from skin hue + highp float dist = hue - skinHue; + if (dist > 0.5) + dist -= 1.0; + if (dist < -0.5) + dist += 1.0; + dist = abs(dist)/0.5; // normalized to [0,1] + + // Apply Gaussian like filter + highp float weight = exp(-dist*dist*skinHueThreshold); + weight = clamp(weight, 0.0, 1.0); + + // Using pink/green, so only adjust hue + if (upperSkinToneColor == 0) { + colorHSV.x += skinToneAdjust * weight * maxHueShift; + // Using pink/orange, so adjust hue < 0 and saturation > 0 + } else if (upperSkinToneColor == 1) { + // We want more orange, so increase saturation + if (skinToneAdjust > 0.0) + colorHSV.y += skinToneAdjust * weight * maxSaturationShift; + // we want more pinks, so decrease hue + else + colorHSV.x += skinToneAdjust * weight * maxHueShift; + } + + // final color + highp vec3 finalColorRGB = hsv2rgb(colorHSV.rgb); + + // display + gl_FragColor = vec4(finalColorRGB, 1.0); +} +); +#else +NSString *const kGPUImageSkinToneFragmentShaderString = SHADER_STRING +( + varying vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + + // [-1;1] <=> [pink;orange] + uniform float skinToneAdjust; // will make reds more pink + + // Other parameters + uniform float skinHue; + uniform float skinHueThreshold; + uniform float maxHueShift; + uniform float maxSaturationShift; + uniform int upperSkinToneColor; + + // RGB <-> HSV conversion, thanks to http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl + highp vec3 rgb2hsv(highp vec3 c) +{ + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + + // HSV <-> RGB conversion, thanks to http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl + highp vec3 hsv2rgb(highp vec3 c) +{ + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + // Main + void main () +{ + + // Sample the input pixel + vec4 colorRGB = texture2D(inputImageTexture, textureCoordinate); + + // Convert color to HSV, extract hue + vec3 colorHSV = rgb2hsv(colorRGB.rgb); + float hue = colorHSV.x; + + // check how far from skin hue + float dist = hue - skinHue; + if (dist > 0.5) + dist -= 1.0; + if (dist < -0.5) + dist += 1.0; + dist = abs(dist)/0.5; // normalized to [0,1] + + // Apply Gaussian like filter + float weight = exp(-dist*dist*skinHueThreshold); + weight = clamp(weight, 0.0, 1.0); + + // Using pink/green, so only adjust hue + if (upperSkinToneColor == 0) { + colorHSV.x += skinToneAdjust * weight * maxHueShift; + // Using pink/orange, so adjust hue < 0 and saturation > 0 + } else if (upperSkinToneColor == 1) { + // We want more orange, so increase saturation + if (skinToneAdjust > 0.0) + colorHSV.y += skinToneAdjust * weight * maxSaturationShift; + // we want more pinks, so decrease hue + else + colorHSV.x += skinToneAdjust * weight * maxHueShift; + } + + // final color + vec3 finalColorRGB = hsv2rgb(colorHSV.rgb); + + // display + gl_FragColor = vec4(finalColorRGB, 1.0); +} + ); +#endif + +#pragma mark - +#pragma mark Initialization and teardown +@synthesize skinToneAdjust; +@synthesize skinHue; +@synthesize skinHueThreshold; +@synthesize maxHueShift; +@synthesize maxSaturationShift; +@synthesize upperSkinToneColor; + +- (id)init +{ + if(! (self = [super initWithFragmentShaderFromString:kGPUImageSkinToneFragmentShaderString]) ) + { + return nil; + } + + skinToneAdjustUniform = [filterProgram uniformIndex:@"skinToneAdjust"]; + skinHueUniform = [filterProgram uniformIndex:@"skinHue"]; + skinHueThresholdUniform = [filterProgram uniformIndex:@"skinHueThreshold"]; + maxHueShiftUniform = [filterProgram uniformIndex:@"maxHueShift"]; + maxSaturationShiftUniform = [filterProgram uniformIndex:@"maxSaturationShift"]; + upperSkinToneColorUniform = [filterProgram uniformIndex:@"upperSkinToneColor"]; + + self.skinHue = 0.05; + self.skinHueThreshold = 40.0; + self.maxHueShift = 0.25; + self.maxSaturationShift = 0.4; + self.upperSkinToneColor = GPUImageSkinToneUpperColorGreen; + + return self; +} + +#pragma mark - +#pragma mark Accessors + +- (void)setSkinToneAdjust:(CGFloat)newValue +{ + skinToneAdjust = newValue; + [self setFloat:newValue forUniform:skinToneAdjustUniform program:filterProgram]; +} + +- (void)setSkinHue:(CGFloat)newValue +{ + skinHue = newValue; + [self setFloat:newValue forUniform:skinHueUniform program:filterProgram]; +} + +- (void)setSkinHueThreshold:(CGFloat)newValue +{ + skinHueThreshold = newValue; + [self setFloat:newValue forUniform:skinHueThresholdUniform program:filterProgram]; +} + +- (void)setMaxHueShift:(CGFloat)newValue +{ + maxHueShift = newValue; + [self setFloat:newValue forUniform:maxHueShiftUniform program:filterProgram]; +} + +- (void)setMaxSaturationShift:(CGFloat)newValue +{ + maxSaturationShift = newValue; + [self setFloat:newValue forUniform:maxSaturationShiftUniform program:filterProgram]; +} + +- (void)setUpperSkinToneColor:(GPUImageSkinToneUpperColor)newValue +{ + upperSkinToneColor = newValue; + [self setInteger:newValue forUniform:upperSkinToneColorUniform program:filterProgram]; +} + +@end \ No newline at end of file diff --git a/framework/Source/GPUImageSolarizeFilter.h b/framework/Source/GPUImageSolarizeFilter.h new file mode 100644 index 000000000..ba01c15a9 --- /dev/null +++ b/framework/Source/GPUImageSolarizeFilter.h @@ -0,0 +1,14 @@ +#import "GPUImageFilter.h" + +/** Pixels with a luminance above the threshold will invert their color + */ +@interface GPUImageSolarizeFilter : GPUImageFilter +{ + GLint thresholdUniform; +} + +/** Anything above this luminance will be inverted, and anything below normal. Ranges from 0.0 to 1.0, with 0.5 as the default + */ +@property(readwrite, nonatomic) CGFloat threshold; + +@end \ No newline at end of file diff --git a/framework/Source/GPUImageSolarizeFilter.m b/framework/Source/GPUImageSolarizeFilter.m new file mode 100644 index 000000000..616cb5b21 --- /dev/null +++ b/framework/Source/GPUImageSolarizeFilter.m @@ -0,0 +1,76 @@ +#import "GPUImageSolarizeFilter.h" + +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE +NSString *const kGPUImageSolarizeFragmentShaderString = SHADER_STRING +( + varying highp vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + uniform highp float threshold; + + const highp vec3 W = vec3(0.2125, 0.7154, 0.0721); + + void main() + { + highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + highp float luminance = dot(textureColor.rgb, W); + highp float thresholdResult = step(luminance, threshold); + highp vec3 finalColor = abs(thresholdResult - textureColor.rgb); + + gl_FragColor = vec4(finalColor, textureColor.w); + } +); +#else +NSString *const kGPUImageSolarizeFragmentShaderString = SHADER_STRING +( + varying vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + uniform float threshold; + + const vec3 W = vec3(0.2125, 0.7154, 0.0721); + + void main() + { + vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); + float luminance = dot(textureColor.rgb, W); + float thresholdResult = step(luminance, threshold); + vec3 finalColor = abs(thresholdResult - textureColor.rgb); + + gl_FragColor = vec4(vec3(finalColor), textureColor.w); + } +); +#endif + +@implementation GPUImageSolarizeFilter; + +@synthesize threshold = _threshold; + +#pragma mark - +#pragma mark Initialization + +- (id)init; +{ + if (!(self = [super initWithFragmentShaderFromString:kGPUImageSolarizeFragmentShaderString])) + { + return nil; + } + + thresholdUniform = [filterProgram uniformIndex:@"threshold"]; + self.threshold = 0.5; + + return self; +} + +#pragma mark - +#pragma mark Accessors + +- (void)setThreshold:(CGFloat)newValue; +{ + _threshold = newValue; + + [self setFloat:_threshold forUniform:thresholdUniform program:filterProgram]; +} + + +@end \ No newline at end of file diff --git a/framework/Source/GPUImageVibranceFilter.h b/framework/Source/GPUImageVibranceFilter.h new file mode 100644 index 000000000..9daddd79c --- /dev/null +++ b/framework/Source/GPUImageVibranceFilter.h @@ -0,0 +1,20 @@ +// +// GPUImageVibranceFilter.h +// +// +// Created by github.com/r3mus on 8/14/15. +// +// + +#import "GPUImageFilter.h" + +@interface GPUImageVibranceFilter : GPUImageFilter +{ + GLint vibranceUniform; +} + +// Modifies the saturation of desaturated colors, leaving saturated colors unmodified. +// Value -1 to 1 (-1 is minimum vibrance, 0 is no change, and 1 is maximum vibrance) +@property (readwrite, nonatomic) GLfloat vibrance; + +@end diff --git a/framework/Source/GPUImageVibranceFilter.m b/framework/Source/GPUImageVibranceFilter.m new file mode 100644 index 000000000..76f3930c9 --- /dev/null +++ b/framework/Source/GPUImageVibranceFilter.m @@ -0,0 +1,78 @@ +// +// GPUImageVibranceFilter.m +// +// +// Created by github.com/r3mus on 8/13/15. +// +// + +#import "GPUImageVibranceFilter.h" + +#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE +NSString *const kGPUImageVibranceFragmentShaderString = SHADER_STRING +( + varying highp vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + uniform lowp float vibrance; + + void main() { + lowp vec4 color = texture2D(inputImageTexture, textureCoordinate); + lowp float average = (color.r + color.g + color.b) / 3.0; + lowp float mx = max(color.r, max(color.g, color.b)); + lowp float amt = (mx - average) * (-vibrance * 3.0); + color.rgb = mix(color.rgb, vec3(mx), amt); + gl_FragColor = color; + } +); +#else +NSString *const kGPUImageVibranceFragmentShaderString = SHADER_STRING +( + varying vec2 textureCoordinate; + + uniform sampler2D inputImageTexture; + uniform float vibrance; + + void main() { + vec4 color = texture2D(inputImageTexture, textureCoordinate); + float average = (color.r + color.g + color.b) / 3.0; + float mx = max(color.r, max(color.g, color.b)); + float amt = (mx - average) * (-vibrance * 3.0); + color.rgb = mix(color.rgb, vec3(mx), amt); + gl_FragColor = color; + } +); +#endif + +@implementation GPUImageVibranceFilter + +@synthesize vibrance = _vibrance; + +#pragma mark - +#pragma mark Initialization and teardown + +- (id)init; +{ + if (!(self = [super initWithFragmentShaderFromString:kGPUImageVibranceFragmentShaderString])) + { + return nil; + } + + vibranceUniform = [filterProgram uniformIndex:@"vibrance"]; + self.vibrance = 0.0; + + return self; +} + +#pragma mark - +#pragma mark Accessors + +- (void)setVibrance:(GLfloat)vibrance; +{ + _vibrance = vibrance; + + [self setFloat:_vibrance forUniform:vibranceUniform program:filterProgram]; +} + +@end + diff --git a/framework/Source/GPUImageVideoCamera.h b/framework/Source/GPUImageVideoCamera.h index 22ccb942b..458020cfe 100755 --- a/framework/Source/GPUImageVideoCamera.h +++ b/framework/Source/GPUImageVideoCamera.h @@ -3,13 +3,12 @@ #import #import "GPUImageContext.h" #import "GPUImageOutput.h" +#import "GPUImageColorConversion.h" -extern const GLfloat kColorConversion601[]; -extern const GLfloat kColorConversion601FullRange[]; -extern const GLfloat kColorConversion709[]; -extern NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString; -extern NSString *const kGPUImageYUVFullRangeConversionForLAFragmentShaderString; -extern NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString; +//Optionally override the YUV to RGB matrices +void setColorConversion601( GLfloat conversionMatrix[9] ); +void setColorConversion601FullRange( GLfloat conversionMatrix[9] ); +void setColorConversion709( GLfloat conversionMatrix[9] ); //Delegate Protocal for Face Detection. @@ -44,6 +43,9 @@ extern NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString __unsafe_unretained id _delegate; } +/// Whether or not the underlying AVCaptureSession is running +@property(readonly, nonatomic) BOOL isRunning; + /// The AVCaptureSession used to capture from the camera @property(readonly, retain, nonatomic) AVCaptureSession *captureSession; diff --git a/framework/Source/GPUImageVideoCamera.m b/framework/Source/GPUImageVideoCamera.m index b84f88aad..18aa60c32 100644 --- a/framework/Source/GPUImageVideoCamera.m +++ b/framework/Source/GPUImageVideoCamera.m @@ -2,92 +2,20 @@ #import "GPUImageMovieWriter.h" #import "GPUImageFilter.h" -// Color Conversion Constants (YUV to RGB) including adjustment from 16-235/16-240 (video range) - -// BT.601, which is the standard for SDTV. -const GLfloat kColorConversion601[] = { - 1.164, 1.164, 1.164, - 0.0, -0.392, 2.017, - 1.596, -0.813, 0.0, -}; - -// BT.709, which is the standard for HDTV. -const GLfloat kColorConversion709[] = { - 1.164, 1.164, 1.164, - 0.0, -0.213, 2.112, - 1.793, -0.533, 0.0, -}; - -// BT.601 full range (ref: http://www.equasys.de/colorconversion.html) -const GLfloat kColorConversion601FullRange[] = { - 1.0, 1.0, 1.0, - 0.0, -0.343, 1.765, - 1.4, -0.711, 0.0, -}; - -NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString = SHADER_STRING -( - varying highp vec2 textureCoordinate; - - uniform sampler2D luminanceTexture; - uniform sampler2D chrominanceTexture; - uniform mediump mat3 colorConversionMatrix; - - void main() - { - mediump vec3 yuv; - lowp vec3 rgb; - - yuv.x = texture2D(luminanceTexture, textureCoordinate).r; - yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5); - rgb = colorConversionMatrix * yuv; - - gl_FragColor = vec4(rgb, 1); - } - ); - -NSString *const kGPUImageYUVFullRangeConversionForLAFragmentShaderString = SHADER_STRING -( - varying highp vec2 textureCoordinate; - - uniform sampler2D luminanceTexture; - uniform sampler2D chrominanceTexture; - uniform mediump mat3 colorConversionMatrix; - - void main() - { - mediump vec3 yuv; - lowp vec3 rgb; - - yuv.x = texture2D(luminanceTexture, textureCoordinate).r; - yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5); - rgb = colorConversionMatrix * yuv; - - gl_FragColor = vec4(rgb, 1); - } - ); - -NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRING -( - varying highp vec2 textureCoordinate; - - uniform sampler2D luminanceTexture; - uniform sampler2D chrominanceTexture; - uniform mediump mat3 colorConversionMatrix; - - void main() - { - mediump vec3 yuv; - lowp vec3 rgb; - - yuv.x = texture2D(luminanceTexture, textureCoordinate).r - (16.0/255.0); - yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5); - rgb = colorConversionMatrix * yuv; - - gl_FragColor = vec4(rgb, 1); - } - ); +void setColorConversion601( GLfloat conversionMatrix[9] ) +{ + kColorConversion601 = conversionMatrix; +} + +void setColorConversion601FullRange( GLfloat conversionMatrix[9] ) +{ + kColorConversion601FullRange = conversionMatrix; +} +void setColorConversion709( GLfloat conversionMatrix[9] ) +{ + kColorConversion709 = conversionMatrix; +} #pragma mark - #pragma mark Private methods and instance variables @@ -402,6 +330,11 @@ - (void)addTarget:(id)newTarget atTextureLocation:(NSInteger)text #pragma mark - #pragma mark Manage the camera video stream +- (BOOL)isRunning; +{ + return [_captureSession isRunning]; +} + - (void)startCameraCapture; { if (![_captureSession isRunning]) diff --git a/framework/Source/Mac/GPUImage.h b/framework/Source/Mac/GPUImage.h index 9c4d73f8c..054674080 100755 --- a/framework/Source/Mac/GPUImage.h +++ b/framework/Source/Mac/GPUImage.h @@ -5,11 +5,14 @@ #import // Sources +#import +#import #import #import #import #import #import +#import // Filters #import @@ -89,6 +92,7 @@ #import #import #import +#import #import #import #import @@ -98,6 +102,7 @@ #import #import #import +#import #import #import #import @@ -147,12 +152,16 @@ #import #import #import +#import #import #import #import #import #import +#import +#import // Outputs #import #import +#import diff --git a/framework/Source/Mac/GPUImageAVCamera.m b/framework/Source/Mac/GPUImageAVCamera.m index 828082243..4b26c753d 100644 --- a/framework/Source/Mac/GPUImageAVCamera.m +++ b/framework/Source/Mac/GPUImageAVCamera.m @@ -1,69 +1,7 @@ #import "GPUImageAVCamera.h" #import "GPUImageMovieWriter.h" #import "GPUImageFilter.h" - -NSString *const kGPUImageYUVVideoRangeConversionForRGFragmentShaderString = SHADER_STRING -( - varying vec2 textureCoordinate; - - uniform sampler2D luminanceTexture; - uniform sampler2D chrominanceTexture; - - void main() - { - vec3 yuv; - vec3 rgb; - - yuv.x = texture2D(luminanceTexture, textureCoordinate).r; - yuv.yz = texture2D(chrominanceTexture, textureCoordinate).rg - vec2(0.5, 0.5); - - // BT.601, which is the standard for SDTV is provided as a reference - /* - rgb = mat3( 1, 1, 1, - 0, -.39465, 2.03211, - 1.13983, -.58060, 0) * yuv; - */ - - // Using BT.709 which is the standard for HDTV - rgb = mat3( 1, 1, 1, - 0, -.21482, 2.12798, - 1.28033, -.38059, 0) * yuv; - - gl_FragColor = vec4(rgb, 1); - } -); - -NSString *const kGPUImageYUVVideoRangeConversionForLAFragmentShaderString = SHADER_STRING -( - varying vec2 textureCoordinate; - - uniform sampler2D luminanceTexture; - uniform sampler2D chrominanceTexture; - - void main() - { - vec3 yuv; - vec3 rgb; - - yuv.x = texture2D(luminanceTexture, textureCoordinate).r; - yuv.yz = texture2D(chrominanceTexture, textureCoordinate).ra - vec2(0.5, 0.5); - - // BT.601, which is the standard for SDTV is provided as a reference - /* - rgb = mat3( 1, 1, 1, - 0, -.39465, 2.03211, - 1.13983, -.58060, 0) * yuv; - */ - - // Using BT.709 which is the standard for HDTV - rgb = mat3( 1, 1, 1, - 0, -.21482, 2.12798, - 1.28033, -.38059, 0) * yuv; - - gl_FragColor = vec4(rgb, 1); - } - ); - +#import "GPUImageColorConversion.h" #pragma mark - #pragma mark Private methods and instance variables diff --git a/framework/Source/Mac/GPUImageContext.h b/framework/Source/Mac/GPUImageContext.h index 356b288aa..d599601e3 100755 --- a/framework/Source/Mac/GPUImageContext.h +++ b/framework/Source/Mac/GPUImageContext.h @@ -14,6 +14,7 @@ typedef enum { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, k @property(readonly, nonatomic) dispatch_queue_t contextQueue; @property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram; @property(readonly, retain, nonatomic) NSOpenGLContext *context; +@property(readonly) CVOpenGLTextureCacheRef coreVideoTextureCache; @property(readonly) GPUImageFramebufferCache *framebufferCache; + (void *)contextKey; diff --git a/framework/Source/Mac/GPUImageContext.m b/framework/Source/Mac/GPUImageContext.m index 28523d3f8..0532d95aa 100755 --- a/framework/Source/Mac/GPUImageContext.m +++ b/framework/Source/Mac/GPUImageContext.m @@ -5,6 +5,7 @@ @interface GPUImageContext() { NSMutableDictionary *shaderProgramCache; CGLShareGroupObj *_sharegroup; + NSOpenGLPixelFormat *_pixelFormat; } @end @@ -14,6 +15,7 @@ @implementation GPUImageContext @synthesize context = _context; @synthesize currentShaderProgram = _currentShaderProgram; @synthesize contextQueue = _contextQueue; +@synthesize coreVideoTextureCache = _coreVideoTextureCache; @synthesize framebufferCache = _framebufferCache; static void *openGLESContextQueueKey; @@ -196,18 +198,35 @@ - (NSOpenGLContext *)createContext; 0 }; - NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes]; - if (pixelFormat == nil) + _pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes]; + if (_pixelFormat == nil) { NSLog(@"Error: No appropriate pixel format found"); } // TODO: Take into account the sharegroup - NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:_pixelFormat shareContext:nil]; NSAssert(context != nil, @"Unable to create an OpenGL context. The GPUImage framework requires OpenGL support to work."); return context; } +- (CVOpenGLTextureCacheRef)coreVideoTextureCache; +{ + if (_coreVideoTextureCache == NULL) + { + + CVReturn err = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[self context], [_pixelFormat CGLPixelFormatObj], NULL, &_coreVideoTextureCache); + + if (err) + { + NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d", err); + } + + } + + return _coreVideoTextureCache; +} + #pragma mark - #pragma mark Manage fast texture upload diff --git a/framework/Source/iOS/Framework/GPUImageFramework.h b/framework/Source/iOS/Framework/GPUImageFramework.h index ea12ac09a..3de78bf4b 100644 --- a/framework/Source/iOS/Framework/GPUImageFramework.h +++ b/framework/Source/iOS/Framework/GPUImageFramework.h @@ -137,6 +137,7 @@ FOUNDATION_EXPORT const unsigned char GPUImageFrameworkVersionString[]; #import #import #import +#import #import #import #import @@ -167,6 +168,10 @@ FOUNDATION_EXPORT const unsigned char GPUImageFrameworkVersionString[]; #import #import #import +#import #import #import #import +#import +#import +#import diff --git a/framework/Source/iOS/Framework/Info.plist b/framework/Source/iOS/Framework/Info.plist index 8f69573d0..5c4419d84 100644 --- a/framework/Source/iOS/Framework/Info.plist +++ b/framework/Source/iOS/Framework/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.sunsetlakesoftware.${PRODUCT_NAME:rfc1034identifier} + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/framework/Source/iOS/GPUImageContext.h b/framework/Source/iOS/GPUImageContext.h index 7e4fa0352..71142b886 100755 --- a/framework/Source/iOS/GPUImageContext.h +++ b/framework/Source/iOS/GPUImageContext.h @@ -4,7 +4,16 @@ #define GPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal) -typedef enum { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizonal, kGPUImageRotateRightFlipVertical, kGPUImageRotateRightFlipHorizontal, kGPUImageRotate180 } GPUImageRotationMode; +typedef NS_ENUM(NSUInteger, GPUImageRotationMode) { + kGPUImageNoRotation, + kGPUImageRotateLeft, + kGPUImageRotateRight, + kGPUImageFlipVertical, + kGPUImageFlipHorizonal, + kGPUImageRotateRightFlipVertical, + kGPUImageRotateRightFlipHorizontal, + kGPUImageRotate180 +}; @interface GPUImageContext : NSObject diff --git a/framework/Source/iOS/GPUImageContext.m b/framework/Source/iOS/GPUImageContext.m index 19546ba91..c167d15d2 100755 --- a/framework/Source/iOS/GPUImageContext.m +++ b/framework/Source/iOS/GPUImageContext.m @@ -4,6 +4,8 @@ #define MAXSHADERPROGRAMSALLOWEDINCACHE 40 +extern dispatch_queue_attr_t GPUImageDefaultQueueAttribute(void); + @interface GPUImageContext() { NSMutableDictionary *shaderProgramCache; @@ -31,7 +33,7 @@ - (id)init; } openGLESContextQueueKey = &openGLESContextQueueKey; - _contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL); + _contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", GPUImageDefaultQueueAttribute()); #if OS_OBJECT_USE_OBJC dispatch_queue_set_specific(_contextQueue, openGLESContextQueueKey, (__bridge void *)self, NULL); diff --git a/framework/Source/iOS/GPUImageMovieWriter.m b/framework/Source/iOS/GPUImageMovieWriter.m index 8ced0dfe9..addc0a79a 100755 --- a/framework/Source/iOS/GPUImageMovieWriter.m +++ b/framework/Source/iOS/GPUImageMovieWriter.m @@ -27,8 +27,10 @@ @interface GPUImageMovieWriter () GPUImageFramebuffer *firstInputFramebuffer; + BOOL discont; CMTime startTime, previousFrameTime, previousAudioTime; - + CMTime offsetTime; + dispatch_queue_t audioQueue, videoQueue; BOOL audioEncodingIsFinished, videoEncodingIsFinished; @@ -85,6 +87,7 @@ - (id)initWithMovieURL:(NSURL *)newMovieURL size:(CGSize)newSize fileType:(NSStr videoEncodingIsFinished = NO; audioEncodingIsFinished = NO; + discont = NO; videoSize = newSize; movieURL = newMovieURL; fileType = newFileType; @@ -199,9 +202,9 @@ - (void)initializeMovieWithOutputSettings:(NSDictionary *)outputSettings; // custom output settings specified else { - NSString *videoCodec = [outputSettings objectForKey:AVVideoCodecKey]; - NSNumber *width = [outputSettings objectForKey:AVVideoWidthKey]; - NSNumber *height = [outputSettings objectForKey:AVVideoHeightKey]; + __unused NSString *videoCodec = [outputSettings objectForKey:AVVideoCodecKey]; + __unused NSNumber *width = [outputSettings objectForKey:AVVideoWidthKey]; + __unused NSNumber *height = [outputSettings objectForKey:AVVideoHeightKey]; NSAssert(videoCodec && width && height, @"OutputSettings is missing required parameters."); @@ -362,7 +365,7 @@ - (void)finishRecordingWithCompletionHandler:(void (^)(void))handler; - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; { - if (!isRecording) + if (!isRecording || _paused) { return; } @@ -396,6 +399,34 @@ - (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer; CFRelease(audioBuffer); return; } + + if (discont) { + discont = NO; + + CMTime current; + if (offsetTime.value > 0) { + current = CMTimeSubtract(currentSampleTime, offsetTime); + } else { + current = currentSampleTime; + } + + CMTime offset = CMTimeSubtract(current, previousAudioTime); + + if (offsetTime.value == 0) { + offsetTime = offset; + } else { + offsetTime = CMTimeAdd(offsetTime, offset); + } + } + + if (offsetTime.value > 0) { + CFRelease(audioBuffer); + audioBuffer = [self adjustTime:audioBuffer by:offsetTime]; + CFRetain(audioBuffer); + } + + // record most recent time so we know the length of the pause + currentSampleTime = CMSampleBufferGetPresentationTimeStamp(audioBuffer); previousAudioTime = currentSampleTime; @@ -470,7 +501,7 @@ - (void)enableSynchronizationCallbacks; { [assetWriter startWriting]; } - videoQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.videoReadingQueue", NULL); + videoQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.videoReadingQueue", GPUImageDefaultQueueAttribute()); [assetWriterVideoInput requestMediaDataWhenReadyOnQueue:videoQueue usingBlock:^{ if( _paused ) { @@ -499,7 +530,7 @@ - (void)enableSynchronizationCallbacks; if (audioInputReadyCallback != NULL) { - audioQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.audioReadingQueue", NULL); + audioQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.audioReadingQueue", GPUImageDefaultQueueAttribute()); [assetWriterAudioInput requestMediaDataWhenReadyOnQueue:audioQueue usingBlock:^{ if( _paused ) { @@ -579,7 +610,7 @@ - (void)createDataFBO; } - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + __unused GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); NSAssert(status == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", status); } @@ -666,12 +697,35 @@ - (void)renderAtInternalSizeUsingFramebuffer:(GPUImageFramebuffer *)inputFramebu - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex; { - if (!isRecording) + if (!isRecording || _paused) { [firstInputFramebuffer unlock]; return; } + if (discont) { + discont = NO; + CMTime current; + + if (offsetTime.value > 0) { + current = CMTimeSubtract(frameTime, offsetTime); + } else { + current = frameTime; + } + + CMTime offset = CMTimeSubtract(current, previousFrameTime); + + if (offsetTime.value == 0) { + offsetTime = offset; + } else { + offsetTime = CMTimeAdd(offsetTime, offset); + } + } + + if (offsetTime.value > 0) { + frameTime = CMTimeSubtract(frameTime, offsetTime); + } + // Drop frames forced by images and other things with no time constants // Also, if two consecutive times with the same value are added to the movie, it aborts recording, so I bail on that case if ( (CMTIME_IS_INVALID(frameTime)) || (CMTIME_COMPARE_INLINE(frameTime, ==, previousFrameTime)) || (CMTIME_IS_INDEFINITE(frameTime)) ) @@ -931,4 +985,32 @@ - (AVAssetWriter*)assetWriter { return assetWriter; } +- (void)setPaused:(BOOL)newValue { + if (_paused != newValue) { + _paused = newValue; + + if (_paused) { + discont = YES; + } + } +} + +- (CMSampleBufferRef)adjustTime:(CMSampleBufferRef) sample by:(CMTime) offset { + CMItemCount count; + CMSampleBufferGetSampleTimingInfoArray(sample, 0, nil, &count); + CMSampleTimingInfo* pInfo = malloc(sizeof(CMSampleTimingInfo) * count); + CMSampleBufferGetSampleTimingInfoArray(sample, count, pInfo, &count); + + for (CMItemCount i = 0; i < count; i++) { + pInfo[i].decodeTimeStamp = CMTimeSubtract(pInfo[i].decodeTimeStamp, offset); + pInfo[i].presentationTimeStamp = CMTimeSubtract(pInfo[i].presentationTimeStamp, offset); + } + + CMSampleBufferRef sout; + CMSampleBufferCreateCopyWithNewTiming(nil, sample, count, pInfo, &sout); + free(pInfo); + + return sout; +} + @end diff --git a/framework/Source/iOS/GPUImagePicture.h b/framework/Source/iOS/GPUImagePicture.h index 1ae0ef4a0..4c4b99429 100755 --- a/framework/Source/iOS/GPUImagePicture.h +++ b/framework/Source/iOS/GPUImagePicture.h @@ -16,6 +16,10 @@ - (id)initWithCGImage:(CGImageRef)newImageSource; - (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; +- (id)initWithImage:(UIImage *)newImageSource removePremultiplication:(BOOL)removePremultiplication; +- (id)initWithCGImage:(CGImageRef)newImageSource removePremultiplication:(BOOL)removePremultiplication; +- (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput removePremultiplication:(BOOL)removePremultiplication; +- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput removePremultiplication:(BOOL)removePremultiplication; // Image rendering - (void)processImage; diff --git a/framework/Source/iOS/GPUImagePicture.m b/framework/Source/iOS/GPUImagePicture.m index 97602cf1c..c525f4dcf 100755 --- a/framework/Source/iOS/GPUImagePicture.m +++ b/framework/Source/iOS/GPUImagePicture.m @@ -54,6 +54,26 @@ - (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothly } - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; +{ + return [self initWithCGImage:newImageSource smoothlyScaleOutput:smoothlyScaleOutput removePremultiplication:NO]; +} + +- (id)initWithImage:(UIImage *)newImageSource removePremultiplication:(BOOL)removePremultiplication; +{ + return [self initWithCGImage:[newImageSource CGImage] smoothlyScaleOutput:NO removePremultiplication:removePremultiplication]; +} + +- (id)initWithCGImage:(CGImageRef)newImageSource removePremultiplication:(BOOL)removePremultiplication; +{ + return [self initWithCGImage:newImageSource smoothlyScaleOutput:NO removePremultiplication:removePremultiplication]; +} + +- (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput removePremultiplication:(BOOL)removePremultiplication; +{ + return [self initWithCGImage:[newImageSource CGImage] smoothlyScaleOutput:smoothlyScaleOutput removePremultiplication:removePremultiplication]; +} + +- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput removePremultiplication:(BOOL)removePremultiplication; { if (!(self = [super init])) { @@ -101,7 +121,10 @@ - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoot GLubyte *imageData = NULL; CFDataRef dataFromImageDataProvider = NULL; GLenum format = GL_BGRA; - + BOOL isLitteEndian = YES; + BOOL alphaFirst = NO; + BOOL premultiplied = NO; + if (!shouldRedrawUsingCoreGraphics) { /* Check that the memory layout is compatible with GL, as we cannot use glPixelStore to * tell GL about the memory layout with GLES. @@ -127,6 +150,7 @@ - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoot shouldRedrawUsingCoreGraphics = YES; } } else if (byteOrderInfo == kCGBitmapByteOrderDefault || byteOrderInfo == kCGBitmapByteOrder32Big) { + isLitteEndian = NO; /* Big endian, for alpha-last we can use this bitmap directly in GL */ CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; if (alphaInfo != kCGImageAlphaPremultipliedLast && alphaInfo != kCGImageAlphaLast && @@ -134,7 +158,9 @@ - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoot shouldRedrawUsingCoreGraphics = YES; } else { /* Can access directly using GL_RGBA pixel format */ - format = GL_RGBA; + premultiplied = alphaInfo == kCGImageAlphaPremultipliedLast || alphaInfo == kCGImageAlphaPremultipliedLast; + alphaFirst = alphaInfo == kCGImageAlphaFirst || alphaInfo == kCGImageAlphaPremultipliedFirst; + format = GL_RGBA; } } } @@ -155,6 +181,9 @@ - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoot CGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pixelSizeToUseForTexture.width, pixelSizeToUseForTexture.height), newImageSource); CGContextRelease(imageContext); CGColorSpaceRelease(genericRGBColorspace); + isLitteEndian = YES; + alphaFirst = YES; + premultiplied = YES; } else { @@ -162,7 +191,45 @@ - (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoot dataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(newImageSource)); imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider); } - + + if (removePremultiplication && premultiplied) { + NSUInteger totalNumberOfPixels = round(pixelSizeToUseForTexture.width * pixelSizeToUseForTexture.height); + uint32_t *pixelP = (uint32_t *)imageData; + uint32_t pixel; + CGFloat srcR, srcG, srcB, srcA; + + for (NSUInteger idx=0; idx> 24) / 255.0f; + } + else { + srcA = (CGFloat)(pixel & 0x000000ff) / 255.0f; + pixel >>= 8; + } + + srcR = (CGFloat)((pixel & 0x00ff0000) >> 16) / 255.0f; + srcG = (CGFloat)((pixel & 0x0000ff00) >> 8) / 255.0f; + srcB = (CGFloat)(pixel & 0x000000ff) / 255.0f; + + srcR /= srcA; srcG /= srcA; srcB /= srcA; + + pixel = (uint32_t)(srcR * 255.0) << 16; + pixel |= (uint32_t)(srcG * 255.0) << 8; + pixel |= (uint32_t)(srcB * 255.0); + + if (alphaFirst) { + pixel |= (uint32_t)(srcA * 255.0) << 24; + } + else { + pixel <<= 8; + pixel |= (uint32_t)(srcA * 255.0); + } + *pixelP = isLitteEndian ? CFSwapInt32HostToLittle(pixel) : CFSwapInt32HostToBig(pixel); + } + } + // elapsedTime = (CFAbsoluteTimeGetCurrent() - startTime) * 1000.0; // NSLog(@"Core Graphics drawing time: %f", elapsedTime); diff --git a/framework/Source/iOS/GPUImageView.h b/framework/Source/iOS/GPUImageView.h index 03e12ee5e..b42651d3c 100755 --- a/framework/Source/iOS/GPUImageView.h +++ b/framework/Source/iOS/GPUImageView.h @@ -1,11 +1,13 @@ #import #import "GPUImageContext.h" -typedef enum { +typedef NS_ENUM(NSUInteger, GPUImageFillModeType) { kGPUImageFillModeStretch, // Stretch to fill the full view, which may distort the image outside of its normal aspect ratio kGPUImageFillModePreserveAspectRatio, // Maintains the aspect ratio of the source image, adding bars of the specified background color kGPUImageFillModePreserveAspectRatioAndFill // Maintains the aspect ratio of the source image, zooming in on its center to fill the view -} GPUImageFillModeType; +}; + + /** UIView subclass to use as an endpoint for displaying GPUImage outputs diff --git a/framework/Source/iOS/GPUImageView.m b/framework/Source/iOS/GPUImageView.m index 5def624cd..e092b80ee 100755 --- a/framework/Source/iOS/GPUImageView.m +++ b/framework/Source/iOS/GPUImageView.m @@ -139,8 +139,9 @@ - (void)layoutSubviews { runSynchronouslyOnVideoProcessingQueue(^{ [self destroyDisplayFramebuffer]; [self createDisplayFramebuffer]; - [self recalculateViewGeometry]; }); + } else if (!CGSizeEqualToSize(self.bounds.size, CGSizeZero)) { + [self recalculateViewGeometry]; } } @@ -184,9 +185,11 @@ - (void)createDisplayFramebuffer; glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, displayRenderbuffer); - GLuint framebufferCreationStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + __unused GLuint framebufferCreationStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); NSAssert(framebufferCreationStatus == GL_FRAMEBUFFER_COMPLETE, @"Failure with display framebuffer generation for display of size: %f, %f", self.bounds.size.width, self.bounds.size.height); boundsSizeAtFrameBufferEpoch = self.bounds.size; + + [self recalculateViewGeometry]; } - (void)destroyDisplayFramebuffer; @@ -337,10 +340,10 @@ + (const GLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationM }; static const GLfloat rotateRightHorizontalFlipTextureCoordinates[] = { - 1.0f, 1.0f, - 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, + 1.0f, 0.0f, }; static const GLfloat rotate180TextureCoordinates[] = {