diff --git a/Package.swift b/Package.swift new file mode 100755 index 00000000..800b41c0 --- /dev/null +++ b/Package.swift @@ -0,0 +1,33 @@ +// swift-tools-version:4.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +#if os(macOS) +let platformDepedencies: [Package.Dependency] = [] +let platformExcludes = ["iOS", "Linux", "Operations/Shaders"] +#elseif os(iOS) +let platformDepedencies: [Package.Dependency] = [] +let platformExcludes = ["Linux", "Mac", "Operations/Shaders"] +#elseif os(Linux) +// TODO: Add back in RPi support +let platformDepedencies: [Package.Dependency] = [.package(url: "https://github.com/BradLarson/COpenGL.git", from: "1.0.2"), .package(url: "https://github.com/BradLarson/CFreeGLUT.git", from: "1.0.1"), .package(url: "https://github.com/BradLarson/CVideo4Linux.git", from: "1.0.2")] +let platformExcludes = ["iOS", "Mac", "Operations/Shaders", "Linux/RPiRenderWindow.swift", "Linux/OpenGLContext-RPi.swift", "Linux/V4LSupplement"] +#endif + + +let package = Package( + name: "GPUImage", + products: [ + .library( + name: "GPUImage", + targets: ["GPUImage"]), + ], + dependencies: platformDepedencies, + targets: [ + .target( + name: "GPUImage", + path: "framework/Source", + exclude: platformExcludes), + ] +) diff --git a/framework/GPUImage.xcodeproj/project.pbxproj b/framework/GPUImage.xcodeproj/project.pbxproj index 9ff93151..45f33459 100755 --- a/framework/GPUImage.xcodeproj/project.pbxproj +++ b/framework/GPUImage.xcodeproj/project.pbxproj @@ -379,7 +379,7 @@ BC1E12FD1C9F5283008F844F /* OpenGLContext_Shared.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OpenGLContext_Shared.swift; path = Source/OpenGLContext_Shared.swift; sourceTree = ""; }; BC1E13281C9F6282008F844F /* PictureInput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PictureInput.swift; path = Source/Mac/PictureInput.swift; sourceTree = ""; }; BC2C48031CB80E860085E4BC /* Crop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Crop.swift; path = Source/Operations/Crop.swift; sourceTree = ""; }; - BC4C85ED1C9F042900FD95D8 /* ConvertedShaders_GL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConvertedShaders_GL.swift; path = Source/Operations/Shaders/ConvertedShaders_GL.swift; sourceTree = SOURCE_ROOT; }; + BC4C85ED1C9F042900FD95D8 /* ConvertedShaders_GL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConvertedShaders_GL.swift; path = Source/Operations/ConvertedShaders_GL.swift; sourceTree = SOURCE_ROOT; }; BC4C85F01C9F054100FD95D8 /* Luminance_GL.fsh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.glsl; name = Luminance_GL.fsh; path = Source/Operations/Shaders/Luminance_GL.fsh; sourceTree = ""; }; BC4C85F11C9F05EB00FD95D8 /* Luminance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Luminance.swift; path = Source/Operations/Luminance.swift; sourceTree = ""; }; BC4C85F71C9F167B00FD95D8 /* Saturation_GL.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Saturation_GL.fsh; path = Source/Operations/Shaders/Saturation_GL.fsh; sourceTree = ""; }; @@ -582,7 +582,7 @@ BC9E35491E524DC100B8604F /* Crosshair_GLES.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Crosshair_GLES.fsh; path = Source/Operations/Shaders/Crosshair_GLES.fsh; sourceTree = ""; }; BC9E354B1E524DD400B8604F /* Line_GLES.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Line_GLES.fsh; path = Source/Operations/Shaders/Line_GLES.fsh; sourceTree = ""; }; BC9E354D1E524E0300B8604F /* Circle_GLES.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Circle_GLES.fsh; path = Source/Operations/Shaders/Circle_GLES.fsh; sourceTree = ""; }; - BC9E35531E52521F00B8604F /* ConvertedShaders_GLES.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConvertedShaders_GLES.swift; path = Source/Operations/Shaders/ConvertedShaders_GLES.swift; sourceTree = SOURCE_ROOT; }; + BC9E35531E52521F00B8604F /* ConvertedShaders_GLES.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConvertedShaders_GLES.swift; path = Source/Operations/ConvertedShaders_GLES.swift; sourceTree = SOURCE_ROOT; }; BC9E355C1E5252E900B8604F /* Passthrough_GLES.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Passthrough_GLES.fsh; path = Source/Operations/Shaders/Passthrough_GLES.fsh; sourceTree = ""; }; BCA4E22F1CC31276007B51BA /* Solarize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Solarize.swift; path = Source/Operations/Solarize.swift; sourceTree = ""; }; BCA4E2311CC312EF007B51BA /* Solarize_GL.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Solarize_GL.fsh; path = Source/Operations/Shaders/Solarize_GL.fsh; sourceTree = ""; }; @@ -1316,6 +1316,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = BC6E7CA11C39A9D8006DF678; @@ -1799,7 +1800,7 @@ SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -1851,7 +1852,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.9; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; diff --git a/framework/Package.swift b/framework/Package.swift deleted file mode 100644 index 66277ad0..00000000 --- a/framework/Package.swift +++ /dev/null @@ -1,51 +0,0 @@ -import PackageDescription - -/** - Better to create variables for the excludes so you dont have the - package def wrapped with macros . - - Also need to trap if os is not support like watch and tv -*/ -#if os(macOS) - -let excludes = ["iOS", "Linux"] - -#elseif os(iOS) - -let excludes = ["Linux", "Mac"] - -#elseif os(Linux) - -let excludes = ["iOS", "Mac"] - -#endif - - -#if os(Linux) || os(macOS) || os(Linux) - -let package = Package( - name: "GPUImage", - providers: [ - .Apt("libv4l-dev"), - ], - targets: [ - Target(name: "GPUImage") - ], - dependencies:[], - exclude: excludes - ) - -#if os(Linux) - package.dependencies.append([ - .Package(url: "./Packages/CVideo4Linux", majorVersion: 1), - .Package(url: "./Packages/COpenGL", majorVersion: 1), - .Package(url: "./Packages/CFreeGLUT", majorVersion: 1), - ]) -#endif - - -#else - - fatalError("Unsupported OS") - -#endif diff --git a/framework/Source/FillMode.swift b/framework/Source/FillMode.swift index 650e9c96..865fae75 100644 --- a/framework/Source/FillMode.swift +++ b/framework/Source/FillMode.swift @@ -1,16 +1,17 @@ #if os(Linux) import Glibc -#if GLES - import COpenGLES.gles2 - #else - import COpenGL #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGL) +import OpenGL.GL3 +#endif + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGL) +import COpenGL #endif diff --git a/framework/Source/Framebuffer.swift b/framework/Source/Framebuffer.swift index dbbc385f..c9c2bd97 100755 --- a/framework/Source/Framebuffer.swift +++ b/framework/Source/Framebuffer.swift @@ -1,17 +1,22 @@ #if os(Linux) import Glibc -#if GLES - import COpenGLES.gles2 - let GL_BGRA = GL_RGBA // A hack: Raspberry Pi needs this or framebuffer creation fails -#else - import COpenGL #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGL) +import OpenGL.GL3 +#endif + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 +let GL_BGRA = GL_RGBA // A hack: Raspberry Pi needs this or framebuffer creation fails +#endif + +#if canImport(COpenGL) +import COpenGL #endif import Foundation diff --git a/framework/Source/FramebufferCache.swift b/framework/Source/FramebufferCache.swift index f62575c7..81bbb5ac 100755 --- a/framework/Source/FramebufferCache.swift +++ b/framework/Source/FramebufferCache.swift @@ -1,15 +1,17 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif // TODO: Add mechanism to purge framebuffers on low memory diff --git a/framework/Source/Linux/V4LCamera.swift b/framework/Source/Linux/V4LSupplement/V4LCamera.swift similarity index 100% rename from framework/Source/Linux/V4LCamera.swift rename to framework/Source/Linux/V4LSupplement/V4LCamera.swift diff --git a/framework/Source/Linux/v4lfuncs.c b/framework/Source/Linux/V4LSupplement/v4lfuncs.c similarity index 100% rename from framework/Source/Linux/v4lfuncs.c rename to framework/Source/Linux/V4LSupplement/v4lfuncs.c diff --git a/framework/Source/Linux/v4lfuncs.h b/framework/Source/Linux/V4LSupplement/v4lfuncs.h similarity index 100% rename from framework/Source/Linux/v4lfuncs.h rename to framework/Source/Linux/V4LSupplement/v4lfuncs.h diff --git a/framework/Source/Mac/MovieOutput.swift b/framework/Source/Mac/MovieOutput.swift index d816fe4d..da12adc5 100644 --- a/framework/Source/Mac/MovieOutput.swift +++ b/framework/Source/Mac/MovieOutput.swift @@ -27,7 +27,7 @@ public class MovieOutput: ImageConsumer, AudioEncodingTarget { return assetWriterVideoInput.transform } set { - assetWriterVideoInput.transform = transform + assetWriterVideoInput.transform = newValue } } @@ -193,14 +193,14 @@ public class MovieOutput: ImageConsumer, AudioEncodingTarget { public extension Timestamp { - public init(_ time:CMTime) { + init(_ time:CMTime) { self.value = time.value self.timescale = time.timescale self.flags = TimestampFlags(rawValue:time.flags.rawValue) self.epoch = time.epoch } - public var asCMTime:CMTime { + var asCMTime:CMTime { get { return CMTimeMakeWithEpoch(value, timescale, epoch) } diff --git a/framework/Source/Mac/PictureInput.swift b/framework/Source/Mac/PictureInput.swift index 6d63207b..6dce1e0e 100755 --- a/framework/Source/Mac/PictureInput.swift +++ b/framework/Source/Mac/PictureInput.swift @@ -121,8 +121,7 @@ public class PictureInput: ImageSource { } public convenience init(imageName:String, smoothlyScaleOutput:Bool = false, orientation:ImageOrientation = .portrait) { - let imageName = NSImage.Name(rawValue: imageName) - guard let image = NSImage(named:imageName) else { fatalError("No such image named: \(imageName) in your application bundle") } + guard let image = NSImage(named:NSImage.Name(imageName)) else { fatalError("No such image named: \(imageName) in your application bundle") } self.init(image:image.cgImage(forProposedRect:nil, context:nil, hints:nil)!, smoothlyScaleOutput:smoothlyScaleOutput, orientation:orientation) } diff --git a/framework/Source/Mac/PictureOutput.swift b/framework/Source/Mac/PictureOutput.swift index b9e27ff0..c7887068 100644 --- a/framework/Source/Mac/PictureOutput.swift +++ b/framework/Source/Mac/PictureOutput.swift @@ -95,7 +95,7 @@ public class PictureOutput: ImageConsumer { } public extension ImageSource { - public func saveNextFrameToURL(_ url:URL, format:PictureFileFormat) { + func saveNextFrameToURL(_ url:URL, format:PictureFileFormat) { let pictureOutput = PictureOutput() pictureOutput.saveNextFrameToURL(url, format:format) self --> pictureOutput @@ -103,13 +103,13 @@ public extension ImageSource { } public extension NSImage { - public func filterWithOperation(_ operation:T) -> NSImage { + func filterWithOperation(_ operation:T) -> NSImage { return filterWithPipeline{input, output in input --> operation --> output } } - public func filterWithPipeline(_ pipeline:(PictureInput, PictureOutput) -> ()) -> NSImage { + func filterWithPipeline(_ pipeline:(PictureInput, PictureOutput) -> ()) -> NSImage { let picture = PictureInput(image:self) var outputImage:NSImage? let pictureOutput = PictureOutput() diff --git a/framework/Source/Matrix.swift b/framework/Source/Matrix.swift index 475fff5b..ed563fdf 100644 --- a/framework/Source/Matrix.swift +++ b/framework/Source/Matrix.swift @@ -95,7 +95,7 @@ func orthographicMatrix(_ left:Float, right:Float, bottom:Float, top:Float, near #if !os(Linux) public extension Matrix4x4 { - public init (_ transform3D:CATransform3D) { + init (_ transform3D:CATransform3D) { self.m11 = Float(transform3D.m11) self.m12 = Float(transform3D.m12) self.m13 = Float(transform3D.m13) @@ -117,7 +117,7 @@ public extension Matrix4x4 { self.m44 = Float(transform3D.m44) } - public init (_ transform:CGAffineTransform) { + init (_ transform:CGAffineTransform) { self.init(CATransform3DMakeAffineTransform(transform)) } } diff --git a/framework/Source/OpenGLContext_Shared.swift b/framework/Source/OpenGLContext_Shared.swift index 20473a30..81aee9c3 100755 --- a/framework/Source/OpenGLContext_Shared.swift +++ b/framework/Source/OpenGLContext_Shared.swift @@ -1,18 +1,20 @@ +#if canImport(OpenGL) +import OpenGL.GL3 +#endif -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGLES) +import OpenGLES #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif + import Foundation public let sharedImageProcessingContext = OpenGLContext() diff --git a/framework/Source/OpenGLRendering.swift b/framework/Source/OpenGLRendering.swift index 020b0b12..1a935433 100755 --- a/framework/Source/OpenGLRendering.swift +++ b/framework/Source/OpenGLRendering.swift @@ -1,18 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - let GL_DEPTH24_STENCIL8 = GL_DEPTH24_STENCIL8_OES - let GL_TRUE = GLboolean(1) - let GL_FALSE = GLboolean(0) -#else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES -#else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 +let GL_DEPTH24_STENCIL8 = GL_DEPTH24_STENCIL8_OES +let GL_TRUE = GLboolean(1) +let GL_FALSE = GLboolean(0) +#endif + +#if canImport(COpenGL) +import COpenGL #endif import Foundation diff --git a/framework/Source/Operations/AverageColorExtractor.swift b/framework/Source/Operations/AverageColorExtractor.swift index 1e4911ab..6478eeaa 100755 --- a/framework/Source/Operations/AverageColorExtractor.swift +++ b/framework/Source/Operations/AverageColorExtractor.swift @@ -1,16 +1,22 @@ #if os(Linux) import Glibc -#if GLES - import COpenGLES.gles2 - #else - import COpenGL #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGL) +import OpenGL.GL3 +#endif + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 +let GL_BGRA = GL_RGBA // A hack: Raspberry Pi needs this or framebuffer creation fails +#endif + +#if canImport(COpenGL) +import COpenGL #endif import Foundation diff --git a/framework/Source/Operations/AverageLuminanceExtractor.swift b/framework/Source/Operations/AverageLuminanceExtractor.swift index 57e22336..82357aa4 100644 --- a/framework/Source/Operations/AverageLuminanceExtractor.swift +++ b/framework/Source/Operations/AverageLuminanceExtractor.swift @@ -1,15 +1,17 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif public class AverageLuminanceExtractor: BasicOperation { diff --git a/framework/Source/Operations/CircleGenerator.swift b/framework/Source/Operations/CircleGenerator.swift index 84a5f593..17f0865d 100644 --- a/framework/Source/Operations/CircleGenerator.swift +++ b/framework/Source/Operations/CircleGenerator.swift @@ -1,17 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif +#if canImport(COpenGL) +import COpenGL +#endif + + public class CircleGenerator: ImageGenerator { let circleShader:ShaderProgram diff --git a/framework/Source/Operations/Shaders/ConvertedShaders_GL.swift b/framework/Source/Operations/ConvertedShaders_GL.swift similarity index 99% rename from framework/Source/Operations/Shaders/ConvertedShaders_GL.swift rename to framework/Source/Operations/ConvertedShaders_GL.swift index 7eb18a5e..da75ffb7 100644 --- a/framework/Source/Operations/Shaders/ConvertedShaders_GL.swift +++ b/framework/Source/Operations/ConvertedShaders_GL.swift @@ -1,3 +1,6 @@ + +#if canImport(OpenGL) || canImport(COpenGL) + public let AdaptiveThresholdFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;\n float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;\n float thresholdResult = step(blurredInput - 0.05, localLuminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), 1.0);\n }\n " public let AddBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n vec4 base = texture2D(inputImageTexture, textureCoordinate);\n vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n float r;\n if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n r = overlay.r + base.r;\n }\n \n float g;\n if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n g = overlay.g + base.g;\n }\n \n float b;\n if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n b = overlay.b + base.b;\n }\n \n float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(r, g, b, a);\n }\n " public let AlphaBlendFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform float mixturePercent;\n \n void main()\n {\n vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n }\n " @@ -142,3 +145,5 @@ public let YUVConversionFullRangeUVPlanarFragmentShader = "varying vec2 textureC public let YUVConversionFullRangeFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mat3 colorConversionMatrix;\n \n void main()\n {\n vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r;\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " public let YUVConversionVideoRangeFragmentShader = "varying vec2 textureCoordinate;\n varying vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mat3 colorConversionMatrix;\n \n void main()\n {\n vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r - (16.0/255.0);\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " public let ZoomBlurFragmentShader = "varying vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform vec2 blurCenter;\n uniform float blurSize;\n \n void main()\n {\n // TODO: Do a more intelligent scaling based on resolution here\n vec2 samplingOffset = 1.0/100.0 * (blurCenter - textureCoordinate) * blurSize;\n \n vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (4.0 * samplingOffset)) * 0.05;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (4.0 * samplingOffset)) * 0.05;\n \n gl_FragColor = fragmentColor;\n }\n " + +#endif diff --git a/framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift b/framework/Source/Operations/ConvertedShaders_GLES.swift similarity index 99% rename from framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift rename to framework/Source/Operations/ConvertedShaders_GLES.swift index 8e934039..11666248 100644 --- a/framework/Source/Operations/Shaders/ConvertedShaders_GLES.swift +++ b/framework/Source/Operations/ConvertedShaders_GLES.swift @@ -1,3 +1,5 @@ +#if canImport(OpenGLES) || canImport(COpenGLES) + public let AdaptiveThresholdFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2; \n \n void main()\n {\n highp float blurredInput = texture2D(inputImageTexture, textureCoordinate).r;\n highp float localLuminance = texture2D(inputImageTexture2, textureCoordinate2).r;\n highp float thresholdResult = step(blurredInput - 0.05, localLuminance);\n \n gl_FragColor = vec4(vec3(thresholdResult), 1.0);\n }\n " public let AddBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n void main()\n {\n lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 overlay = texture2D(inputImageTexture2, textureCoordinate2);\n \n mediump float r;\n if (overlay.r * base.a + base.r * overlay.a >= overlay.a * base.a) {\n r = overlay.a * base.a + overlay.r * (1.0 - base.a) + base.r * (1.0 - overlay.a);\n } else {\n r = overlay.r + base.r;\n }\n \n mediump float g;\n if (overlay.g * base.a + base.g * overlay.a >= overlay.a * base.a) {\n g = overlay.a * base.a + overlay.g * (1.0 - base.a) + base.g * (1.0 - overlay.a);\n } else {\n g = overlay.g + base.g;\n }\n \n mediump float b;\n if (overlay.b * base.a + base.b * overlay.a >= overlay.a * base.a) {\n b = overlay.a * base.a + overlay.b * (1.0 - base.a) + base.b * (1.0 - overlay.a);\n } else {\n b = overlay.b + base.b;\n }\n \n mediump float a = overlay.a + base.a - overlay.a * base.a;\n \n gl_FragColor = vec4(r, g, b, a);\n }\n " public let AlphaBlendFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform lowp float mixturePercent;\n \n void main()\n {\n lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n \n gl_FragColor = vec4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * mixturePercent), textureColor.a);\n }\n " @@ -142,3 +144,5 @@ public let YUVConversionFullRangeUVPlanarFragmentShader = "varying highp vec2 te public let YUVConversionFullRangeFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mediump mat3 colorConversionMatrix;\n \n void main()\n {\n mediump vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r;\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n lowp vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " public let YUVConversionVideoRangeFragmentShader = "varying highp vec2 textureCoordinate;\n varying highp vec2 textureCoordinate2;\n \n uniform sampler2D inputImageTexture;\n uniform sampler2D inputImageTexture2;\n \n uniform mediump mat3 colorConversionMatrix;\n \n void main()\n {\n mediump vec3 yuv;\n \n yuv.x = texture2D(inputImageTexture, textureCoordinate).r - (16.0/255.0);\n yuv.yz = texture2D(inputImageTexture2, textureCoordinate).ra - vec2(0.5, 0.5);\n lowp vec3 rgb = colorConversionMatrix * yuv;\n \n gl_FragColor = vec4(rgb, 1.0);\n }\n " public let ZoomBlurFragmentShader = "varying highp vec2 textureCoordinate;\n \n uniform sampler2D inputImageTexture;\n \n uniform highp vec2 blurCenter;\n uniform highp float blurSize;\n \n void main()\n {\n // TODO: Do a more intelligent scaling based on resolution here\n highp vec2 samplingOffset = 1.0/100.0 * (blurCenter - textureCoordinate) * blurSize;\n \n lowp vec4 fragmentColor = texture2D(inputImageTexture, textureCoordinate) * 0.18;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate + (4.0 * samplingOffset)) * 0.05;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - samplingOffset) * 0.15;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (2.0 * samplingOffset)) * 0.12;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (3.0 * samplingOffset)) * 0.09;\n fragmentColor += texture2D(inputImageTexture, textureCoordinate - (4.0 * samplingOffset)) * 0.05;\n \n gl_FragColor = fragmentColor;\n }\n " + +#endif diff --git a/framework/Source/Operations/CrosshairGenerator.swift b/framework/Source/Operations/CrosshairGenerator.swift index 0960a3ae..4254f733 100644 --- a/framework/Source/Operations/CrosshairGenerator.swift +++ b/framework/Source/Operations/CrosshairGenerator.swift @@ -1,17 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 -#else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL #endif -#else -#if GLES - import OpenGLES -#else - import OpenGL.GL + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 +#endif + +#if canImport(COpenGL) +import COpenGL #endif + public class CrosshairGenerator: ImageGenerator { public var crosshairWidth:Float = 5.0 { didSet { uniformSettings["crosshairWidth"] = crosshairWidth } } @@ -32,7 +35,7 @@ public class CrosshairGenerator: ImageGenerator { public func renderCrosshairs(_ positions:[Position]) { imageFramebuffer.activateFramebufferForRendering() imageFramebuffer.timingStyle = .stillImage -#if GL +#if canImport(OpenGL) || canImport(COpenGL) glEnable(GLenum(GL_POINT_SPRITE)) glEnable(GLenum(GL_VERTEX_PROGRAM_POINT_SIZE)) #else diff --git a/framework/Source/Operations/HarrisCornerDetector.swift b/framework/Source/Operations/HarrisCornerDetector.swift index abb031cf..0ba75c05 100644 --- a/framework/Source/Operations/HarrisCornerDetector.swift +++ b/framework/Source/Operations/HarrisCornerDetector.swift @@ -1,17 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif +#if canImport(COpenGL) +import COpenGL +#endif + + /* Harris corner detector First pass: reduce to luminance and take the derivative of the luminance texture (GPUImageXYDerivativeFilter) diff --git a/framework/Source/Operations/Histogram.swift b/framework/Source/Operations/Histogram.swift index 5c9c1a78..bddcea35 100755 --- a/framework/Source/Operations/Histogram.swift +++ b/framework/Source/Operations/Histogram.swift @@ -1,17 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif +#if canImport(COpenGL) +import COpenGL +#endif + + /* Unlike other filters, this one uses a grid of GL_POINTs to sample the incoming image in a grid. A custom vertex shader reads the color in the texture at its position and outputs a bin position in the final histogram as the vertex position. That point is then written into the image of the histogram using translucent pixels. The degree of translucency is controlled by the scalingFactor, which lets you adjust the dynamic range of the histogram. The histogram can only be generated for one diff --git a/framework/Source/Operations/LineGenerator.swift b/framework/Source/Operations/LineGenerator.swift index 0120a184..eaf44893 100644 --- a/framework/Source/Operations/LineGenerator.swift +++ b/framework/Source/Operations/LineGenerator.swift @@ -1,17 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif +#if canImport(COpenGL) +import COpenGL +#endif + + public enum Line { case infinite(slope:Float, intercept:Float) case segment(p1:Position, p2:Position) diff --git a/framework/Source/Operations/TransformOperation.swift b/framework/Source/Operations/TransformOperation.swift index 6b87a377..0ad05982 100644 --- a/framework/Source/Operations/TransformOperation.swift +++ b/framework/Source/Operations/TransformOperation.swift @@ -1,17 +1,20 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif +#if canImport(COpenGL) +import COpenGL +#endif + + public class TransformOperation: BasicOperation { public var transform:Matrix4x4 = Matrix4x4.identity { didSet { uniformSettings["transformMatrix"] = transform } } var normalizedImageVertices:[GLfloat]! diff --git a/framework/Source/Pipeline.swift b/framework/Source/Pipeline.swift index 65611ea7..08934f2f 100755 --- a/framework/Source/Pipeline.swift +++ b/framework/Source/Pipeline.swift @@ -1,6 +1,7 @@ // MARK: - // MARK: Basic types import Foundation +import Dispatch public protocol ImageSource { var targets:TargetContainer { get } @@ -31,7 +32,7 @@ infix operator --> : AdditionPrecedence // MARK: Extensions and supporting types public extension ImageSource { - public func addTarget(_ target:ImageConsumer, atTargetIndex:UInt? = nil) { + func addTarget(_ target:ImageConsumer, atTargetIndex:UInt? = nil) { if let targetIndex = atTargetIndex { target.setSource(self, atIndex:targetIndex) targets.append(target, indexAtTarget:targetIndex) @@ -44,14 +45,14 @@ public extension ImageSource { } } - public func removeAllTargets() { + func removeAllTargets() { for (target, index) in targets { target.removeSourceAtIndex(index) } targets.removeAll() } - public func updateTargetsWithFramebuffer(_ framebuffer:Framebuffer) { + func updateTargetsWithFramebuffer(_ framebuffer:Framebuffer) { if targets.count == 0 { // Deal with the case where no targets are attached by immediately returning framebuffer to cache framebuffer.lock() framebuffer.unlock() @@ -68,15 +69,15 @@ public extension ImageSource { } public extension ImageConsumer { - public func addSource(_ source:ImageSource) -> UInt? { + func addSource(_ source:ImageSource) -> UInt? { return sources.append(source, maximumInputs:maximumInputs) } - public func setSource(_ source:ImageSource, atIndex:UInt) { + func setSource(_ source:ImageSource, atIndex:UInt) { _ = sources.insert(source, atIndex:atIndex, maximumInputs:maximumInputs) } - public func removeSourceAtIndex(_ index:UInt) { + func removeSourceAtIndex(_ index:UInt) { sources.removeAtIndex(index) } } @@ -93,43 +94,22 @@ class WeakImageConsumer { public class TargetContainer:Sequence { var targets = [WeakImageConsumer]() var count:Int { get {return targets.count}} -#if !os(Linux) let dispatchQueue = DispatchQueue(label:"com.sunsetlakesoftware.GPUImage.targetContainerQueue", attributes: []) -#endif public init() { } public func append(_ target:ImageConsumer, indexAtTarget:UInt) { // TODO: Don't allow the addition of a target more than once -#if os(Linux) - self.targets.append(WeakImageConsumer(value:target, indexAtTarget:indexAtTarget)) -#else dispatchQueue.async{ self.targets.append(WeakImageConsumer(value:target, indexAtTarget:indexAtTarget)) } -#endif } public func makeIterator() -> AnyIterator<(ImageConsumer, UInt)> { var index = 0 return AnyIterator { () -> (ImageConsumer, UInt)? in -#if os(Linux) - if (index >= self.targets.count) { - return nil - } - - while (self.targets[index].value == nil) { - self.targets.remove(at:index) - if (index >= self.targets.count) { - return nil - } - } - - index += 1 - return (self.targets[index - 1].value!, self.targets[index - 1].indexAtTarget) -#else return self.dispatchQueue.sync{ if (index >= self.targets.count) { return nil @@ -145,18 +125,13 @@ public class TargetContainer:Sequence { index += 1 return (self.targets[index - 1].value!, self.targets[index - 1].indexAtTarget) } -#endif } } public func removeAll() { -#if os(Linux) - self.targets.removeAll() -#else dispatchQueue.async{ self.targets.removeAll() } -#endif } } diff --git a/framework/Source/RawDataInput.swift b/framework/Source/RawDataInput.swift index c918045f..46af0cf5 100644 --- a/framework/Source/RawDataInput.swift +++ b/framework/Source/RawDataInput.swift @@ -1,15 +1,18 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 +let GL_BGRA = GL_RGBA // A hack: Raspberry Pi needs this or framebuffer creation fails #endif + +#if canImport(COpenGL) +import COpenGL #endif public enum PixelFormat { diff --git a/framework/Source/RawDataOutput.swift b/framework/Source/RawDataOutput.swift index dac09d7b..2803179d 100644 --- a/framework/Source/RawDataOutput.swift +++ b/framework/Source/RawDataOutput.swift @@ -1,15 +1,17 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif public class RawDataOutput: ImageConsumer { diff --git a/framework/Source/SerialDispatch.swift b/framework/Source/SerialDispatch.swift index 9f48a4e9..c564787f 100755 --- a/framework/Source/SerialDispatch.swift +++ b/framework/Source/SerialDispatch.swift @@ -1,38 +1,20 @@ import Foundation -#if os(Linux) -// For now, disable GCD on Linux and run everything on the main thread - -protocol SerialDispatch { -} - -extension SerialDispatch { - func runOperationAsynchronously(operation:() -> ()) { - operation() - } - - func runOperationSynchronously(operation:() throws -> T) rethrows -> T { - return try operation() +public var standardProcessingQueue:DispatchQueue { +if #available(iOS 10, OSX 10.10, *) { + return DispatchQueue.global(qos: .default) +} else { + return DispatchQueue.global(priority: .default) } } -#else - - public var standardProcessingQueue:DispatchQueue { - if #available(iOS 10, OSX 10.10, *) { - return DispatchQueue.global(qos: .default) - } else { - return DispatchQueue.global(priority: .default) - } - } - - public var lowProcessingQueue:DispatchQueue { - if #available(iOS 10, OSX 10.10, *) { - return DispatchQueue.global(qos: .background) - } else { - return DispatchQueue.global(priority: .low) - } +public var lowProcessingQueue:DispatchQueue { +if #available(iOS 10, OSX 10.10, *) { + return DispatchQueue.global(qos: .background) +} else { + return DispatchQueue.global(priority: .low) } +} func runAsynchronouslyOnMainQueue(_ mainThreadOperation:@escaping () -> ()) { if (Thread.isMainThread) { @@ -68,14 +50,14 @@ public protocol SerialDispatch { } public extension SerialDispatch { - public func runOperationAsynchronously(_ operation:@escaping () -> ()) { + func runOperationAsynchronously(_ operation:@escaping () -> ()) { self.serialDispatchQueue.async { self.makeCurrentContext() operation() } } - public func runOperationSynchronously(_ operation:() -> ()) { + func runOperationSynchronously(_ operation:() -> ()) { // TODO: Verify this works as intended if (DispatchQueue.getSpecific(key:self.dispatchQueueKey) == 81) { operation() @@ -87,7 +69,7 @@ public extension SerialDispatch { } } - public func runOperationSynchronously(_ operation:() throws -> ()) throws { + func runOperationSynchronously(_ operation:() throws -> ()) throws { var caughtError:Error? = nil runOperationSynchronously { do { @@ -99,7 +81,7 @@ public extension SerialDispatch { if (caughtError != nil) {throw caughtError!} } - public func runOperationSynchronously(_ operation:() throws -> T) throws -> T { + func runOperationSynchronously(_ operation:() throws -> T) throws -> T { var returnedValue: T! try runOperationSynchronously { returnedValue = try operation() @@ -107,7 +89,7 @@ public extension SerialDispatch { return returnedValue } - public func runOperationSynchronously(_ operation:() -> T) -> T { + func runOperationSynchronously(_ operation:() -> T) -> T { var returnedValue: T! runOperationSynchronously { returnedValue = operation() @@ -115,4 +97,3 @@ public extension SerialDispatch { return returnedValue } } -#endif diff --git a/framework/Source/ShaderProgram.swift b/framework/Source/ShaderProgram.swift index abf50b63..4577d270 100755 --- a/framework/Source/ShaderProgram.swift +++ b/framework/Source/ShaderProgram.swift @@ -1,17 +1,19 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 -#else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES -#else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES #endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif - + +#if canImport(COpenGL) +import COpenGL +#endif + import Foundation diff --git a/framework/Source/ShaderUniformSettings.swift b/framework/Source/ShaderUniformSettings.swift index f67aed30..7e0618b2 100644 --- a/framework/Source/ShaderUniformSettings.swift +++ b/framework/Source/ShaderUniformSettings.swift @@ -1,15 +1,17 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif public struct ShaderUniformSettings { diff --git a/framework/Source/TextureInput.swift b/framework/Source/TextureInput.swift index b2a782bf..9beef7c9 100644 --- a/framework/Source/TextureInput.swift +++ b/framework/Source/TextureInput.swift @@ -1,15 +1,17 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif public class TextureInput: ImageSource { diff --git a/framework/Source/TextureOutput.swift b/framework/Source/TextureOutput.swift index 072e07c6..e2486d87 100644 --- a/framework/Source/TextureOutput.swift +++ b/framework/Source/TextureOutput.swift @@ -1,15 +1,17 @@ -#if os(Linux) -#if GLES - import COpenGLES.gles2 - #else - import COpenGL +#if canImport(OpenGL) +import OpenGL.GL3 #endif -#else -#if GLES - import OpenGLES - #else - import OpenGL.GL3 + +#if canImport(OpenGLES) +import OpenGLES +#endif + +#if canImport(COpenGLES) +import COpenGLES.gles2 #endif + +#if canImport(COpenGL) +import COpenGL #endif public class TextureOutput: ImageConsumer { diff --git a/framework/Source/iOS/MovieOutput.swift b/framework/Source/iOS/MovieOutput.swift index 5ef92250..917d9ef7 100644 --- a/framework/Source/iOS/MovieOutput.swift +++ b/framework/Source/iOS/MovieOutput.swift @@ -226,14 +226,14 @@ public class MovieOutput: ImageConsumer, AudioEncodingTarget { public extension Timestamp { - public init(_ time:CMTime) { + init(_ time:CMTime) { self.value = time.value self.timescale = time.timescale self.flags = TimestampFlags(rawValue:time.flags.rawValue) self.epoch = time.epoch } - public var asCMTime:CMTime { + var asCMTime:CMTime { get { return CMTimeMakeWithEpoch(value, timescale, epoch) } diff --git a/framework/Source/iOS/PictureOutput.swift b/framework/Source/iOS/PictureOutput.swift index 63adb261..e21b5229 100644 --- a/framework/Source/iOS/PictureOutput.swift +++ b/framework/Source/iOS/PictureOutput.swift @@ -106,7 +106,7 @@ public class PictureOutput: ImageConsumer { } public extension ImageSource { - public func saveNextFrameToURL(_ url:URL, format:PictureFileFormat) { + func saveNextFrameToURL(_ url:URL, format:PictureFileFormat) { let pictureOutput = PictureOutput() pictureOutput.saveNextFrameToURL(url, format:format) self --> pictureOutput @@ -114,13 +114,13 @@ public extension ImageSource { } public extension UIImage { - public func filterWithOperation(_ operation:T) -> UIImage { + func filterWithOperation(_ operation:T) -> UIImage { return filterWithPipeline{input, output in input --> operation --> output } } - public func filterWithPipeline(_ pipeline:(PictureInput, PictureOutput) -> ()) -> UIImage { + func filterWithPipeline(_ pipeline:(PictureInput, PictureOutput) -> ()) -> UIImage { let picture = PictureInput(image:self) var outputImage:UIImage? let pictureOutput = PictureOutput()