Skip to content

Commit 7b81c12

Browse files
committed
revert(camera): revert backgrounds for webcam as was unable to resolve halo effect
1 parent ca93a7b commit 7b81c12

12 files changed

Lines changed: 8 additions & 652 deletions

Reframed.xcodeproj/project.pbxproj

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,7 @@
133133
A9000000000000000000000C /* CursorSmoothing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9000000000000000000000C /* CursorSmoothing.swift */; };
134134
A20000000000000000000020 /* PropertiesPanel+AnimationsTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = B20000000000000000000020 /* PropertiesPanel+AnimationsTab.swift */; };
135135
A20000000000000000000021 /* PropertiesPanel+AudioTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = B20000000000000000000021 /* PropertiesPanel+AudioTab.swift */; };
136-
CA0000000000000000000001 /* CameraBackgroundStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0000000000000000000001 /* CameraBackgroundStyle.swift */; };
137136
CA0000000000000000000002 /* CIImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0000000000000000000002 /* CIImageExtensions.swift */; };
138-
CA0000000000000000000003 /* WebcamFrameProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0000000000000000000003 /* WebcamFrameProcessor.swift */; };
139-
CA0000000000000000000004 /* PropertiesPanel+CameraBackgroundSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0000000000000000000004 /* PropertiesPanel+CameraBackgroundSection.swift */; };
140137
/* End PBXBuildFile section */
141138

142139
/* Begin PBXFileReference section */
@@ -268,10 +265,7 @@
268265
B9000000000000000000000C /* CursorSmoothing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CursorSmoothing.swift; sourceTree = "<group>"; };
269266
B20000000000000000000020 /* PropertiesPanel+AnimationsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PropertiesPanel+AnimationsTab.swift"; sourceTree = "<group>"; };
270267
B20000000000000000000021 /* PropertiesPanel+AudioTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PropertiesPanel+AudioTab.swift"; sourceTree = "<group>"; };
271-
CB0000000000000000000001 /* CameraBackgroundStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraBackgroundStyle.swift; sourceTree = "<group>"; };
272268
CB0000000000000000000002 /* CIImageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageExtensions.swift; sourceTree = "<group>"; };
273-
CB0000000000000000000003 /* WebcamFrameProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebcamFrameProcessor.swift; sourceTree = "<group>"; };
274-
CB0000000000000000000004 /* PropertiesPanel+CameraBackgroundSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PropertiesPanel+CameraBackgroundSection.swift"; sourceTree = "<group>"; };
275269
/* End PBXFileReference section */
276270

277271
/* Begin PBXFrameworksBuildPhase section */
@@ -541,8 +535,6 @@
541535
B9000000000000000000000C /* CursorSmoothing.swift */,
542536
B20000000000000000000020 /* PropertiesPanel+AnimationsTab.swift */,
543537
B20000000000000000000021 /* PropertiesPanel+AudioTab.swift */,
544-
CB0000000000000000000003 /* WebcamFrameProcessor.swift */,
545-
CB0000000000000000000004 /* PropertiesPanel+CameraBackgroundSection.swift */,
546538
);
547539
path = Editor;
548540
sourceTree = "<group>";
@@ -551,7 +543,6 @@
551543
isa = PBXGroup;
552544
children = (
553545
B20000000000000000000013 /* BackgroundStyle.swift */,
554-
CB0000000000000000000001 /* CameraBackgroundStyle.swift */,
555546
B20000000000000000000004 /* CameraLayout.swift */,
556547
B2000000000000000000000F /* CameraVideoCompositor.swift */,
557548
B2000000000000000000001A /* CompositionInstruction.swift */,
@@ -756,10 +747,7 @@
756747
A9000000000000000000000C /* CursorSmoothing.swift in Sources */,
757748
A20000000000000000000020 /* PropertiesPanel+AnimationsTab.swift in Sources */,
758749
A20000000000000000000021 /* PropertiesPanel+AudioTab.swift in Sources */,
759-
CA0000000000000000000001 /* CameraBackgroundStyle.swift in Sources */,
760750
CA0000000000000000000002 /* CIImageExtensions.swift in Sources */,
761-
CA0000000000000000000003 /* WebcamFrameProcessor.swift in Sources */,
762-
CA0000000000000000000004 /* PropertiesPanel+CameraBackgroundSection.swift in Sources */,
763751
);
764752
};
765753
/* End PBXSourcesBuildPhase section */

Reframed/Compositor/CameraBackgroundStyle.swift

Lines changed: 0 additions & 53 deletions
This file was deleted.

Reframed/Compositor/CameraVideoCompositor.swift

Lines changed: 4 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import AVFoundation
2-
import CoreImage
32
import CoreVideo
4-
import Vision
53

64
final class CameraVideoCompositor: NSObject, AVVideoCompositing, @unchecked Sendable {
75
var sourcePixelBufferAttributes: [String: any Sendable]? {
@@ -236,22 +234,7 @@ final class CameraVideoCompositor: NSObject, AVVideoCompositing, @unchecked Send
236234
$0.containsTime(compositionTime)
237235
}
238236

239-
let rawWebcamImage = createImage(from: webcamBuffer, colorSpace: colorSpace)
240-
var mirrorHandledBySegmentation = false
241-
let webcamImage: CGImage? = {
242-
guard let raw = rawWebcamImage else { return nil }
243-
if case .none = instruction.cameraBackgroundStyle { return raw }
244-
if let segmented = processWebcamSegmentation(
245-
webcamBuffer: webcamBuffer,
246-
webcamImage: raw,
247-
instruction: instruction,
248-
colorSpace: colorSpace
249-
) {
250-
mirrorHandledBySegmentation = true
251-
return segmented
252-
}
253-
return raw
254-
}()
237+
let webcamImage = createImage(from: webcamBuffer, colorSpace: colorSpace)
255238

256239
if let webcamImage {
257240
if isCamFullscreen {
@@ -260,7 +243,7 @@ final class CameraVideoCompositor: NSObject, AVVideoCompositing, @unchecked Send
260243
let fitRect = AVMakeRect(aspectRatio: webcamAspect, insideRect: fullRect)
261244
context.saveGState()
262245
drawBackground(in: context, rect: fullRect, instruction: instruction, colorSpace: colorSpace)
263-
if instruction.cameraMirrored && !mirrorHandledBySegmentation {
246+
if instruction.cameraMirrored {
264247
context.translateBy(x: fitRect.midX, y: 0)
265248
context.scaleBy(x: -1, y: 1)
266249
context.translateBy(x: -fitRect.midX, y: 0)
@@ -321,7 +304,7 @@ final class CameraVideoCompositor: NSObject, AVVideoCompositing, @unchecked Send
321304
context.saveGState()
322305
context.addPath(innerPath)
323306
context.clip()
324-
if instruction.cameraMirrored && !mirrorHandledBySegmentation {
307+
if instruction.cameraMirrored {
325308
context.translateBy(x: insetRect.midX, y: 0)
326309
context.scaleBy(x: -1, y: 1)
327310
context.translateBy(x: -insetRect.midX, y: 0)
@@ -339,7 +322,7 @@ final class CameraVideoCompositor: NSObject, AVVideoCompositing, @unchecked Send
339322
context.saveGState()
340323
context.addPath(path)
341324
context.clip()
342-
if instruction.cameraMirrored && !mirrorHandledBySegmentation {
325+
if instruction.cameraMirrored {
343326
context.translateBy(x: drawRect.midX, y: 0)
344327
context.scaleBy(x: -1, y: 1)
345328
context.translateBy(x: -drawRect.midX, y: 0)
@@ -353,64 +336,6 @@ final class CameraVideoCompositor: NSObject, AVVideoCompositing, @unchecked Send
353336
}
354337
}
355338

356-
private static func processWebcamSegmentation(
357-
webcamBuffer: CVPixelBuffer,
358-
webcamImage: CGImage,
359-
instruction: CompositionInstruction,
360-
colorSpace: CGColorSpace
361-
) -> CGImage? {
362-
let request = VNGeneratePersonSegmentationRequest()
363-
request.qualityLevel = .accurate
364-
365-
let handler = VNImageRequestHandler(cvPixelBuffer: webcamBuffer, options: [:])
366-
try? handler.perform([request])
367-
368-
guard let maskBuffer = request.results?.first?.pixelBuffer else { return nil }
369-
370-
let ciContext = CIContext(options: [.useSoftwareRenderer: false])
371-
let foreground = CIImage(cvPixelBuffer: webcamBuffer)
372-
let maskImage = CIImage(cvPixelBuffer: maskBuffer).resized(to: foreground.extent.size)
373-
let size = foreground.extent.size
374-
375-
let background: CIImage
376-
switch instruction.cameraBackgroundStyle {
377-
case .none:
378-
return nil
379-
case .transparent:
380-
background = CIImage(color: CIColor(red: 0, green: 0, blue: 0, alpha: 0)).cropped(to: foreground.extent)
381-
case .solidColor(let color):
382-
background = CIImage(color: CIColor(red: color.r, green: color.g, blue: color.b, alpha: color.a)).cropped(to: foreground.extent)
383-
case .gradient(let id):
384-
if let grad = CIImage.renderGradientCIImage(presetId: id, size: size) {
385-
background = grad
386-
} else {
387-
background = CIImage(color: CIColor.black).cropped(to: foreground.extent)
388-
}
389-
case .image:
390-
if let bgCGImage = instruction.cameraBackgroundImage {
391-
background = CIImage(cgImage: bgCGImage).resizedToFill(size)
392-
} else {
393-
background = CIImage(color: CIColor.black).cropped(to: foreground.extent)
394-
}
395-
}
396-
397-
guard let blendFilter = CIFilter(name: "CIBlendWithMask") else { return nil }
398-
blendFilter.setValue(foreground, forKey: kCIInputImageKey)
399-
blendFilter.setValue(background, forKey: kCIInputBackgroundImageKey)
400-
blendFilter.setValue(maskImage, forKey: kCIInputMaskImageKey)
401-
402-
guard var output = blendFilter.outputImage else { return nil }
403-
404-
if instruction.cameraMirrored {
405-
output =
406-
output
407-
.transformed(by: CGAffineTransform(scaleX: -1, y: 1))
408-
.transformed(by: CGAffineTransform(translationX: size.width, y: 0))
409-
}
410-
411-
return ciContext.createCGImage(output, from: output.extent)
412-
}
413-
414339
private static func aspectFillRect(imageSize: CGSize, in rect: CGRect) -> CGRect {
415340
let imageAspect = imageSize.width / max(imageSize.height, 1)
416341
let rectAspect = rect.width / max(rect.height, 1)

Reframed/Compositor/CompositionInstruction.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ final class CompositionInstruction: NSObject, AVVideoCompositionInstructionProto
3737
let zoomTimeline: ZoomTimeline?
3838
let trimStartSeconds: Double
3939
let cameraFullscreenRegions: [CMTimeRange]
40-
let cameraBackgroundStyle: CameraBackgroundStyle
41-
let cameraBackgroundImage: CGImage?
4240

4341
init(
4442
timeRange: CMTimeRange,
@@ -68,9 +66,7 @@ final class CompositionInstruction: NSObject, AVVideoCompositionInstructionProto
6866
zoomFollowCursor: Bool = true,
6967
zoomTimeline: ZoomTimeline? = nil,
7068
trimStartSeconds: Double = 0,
71-
cameraFullscreenRegions: [CMTimeRange] = [],
72-
cameraBackgroundStyle: CameraBackgroundStyle = .none,
73-
cameraBackgroundImage: CGImage? = nil
69+
cameraFullscreenRegions: [CMTimeRange] = []
7470
) {
7571
self.timeRange = timeRange
7672
self.screenTrackID = screenTrackID
@@ -100,8 +96,6 @@ final class CompositionInstruction: NSObject, AVVideoCompositionInstructionProto
10096
self.zoomTimeline = zoomTimeline
10197
self.trimStartSeconds = trimStartSeconds
10298
self.cameraFullscreenRegions = cameraFullscreenRegions
103-
self.cameraBackgroundStyle = cameraBackgroundStyle
104-
self.cameraBackgroundImage = cameraBackgroundImage
10599

106100
var trackIDs: [NSValue] = [NSNumber(value: screenTrackID)]
107101
if let wid = webcamTrackID {

Reframed/Compositor/VideoCompositor.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ enum VideoCompositor {
4343
micAudioVolume: Float = 1.0,
4444
micNoiseReductionEnabled: Bool = false,
4545
micNoiseReductionIntensity: Float = 0.5,
46-
cameraBackgroundStyle: CameraBackgroundStyle = .none,
47-
cameraBackgroundImage: CGImage? = nil,
4846
progressHandler: (@MainActor @Sendable (Double, Double?) -> Void)? = nil
4947
) async throws -> URL {
5048
let composition = AVMutableComposition()
@@ -113,16 +111,12 @@ enum VideoCompositor {
113111
hasNonDefaultBackground || canvasAspect != .original || padding > 0 || videoCornerRadius > 0
114112
|| videoShadow > 0
115113
let hasWebcam = result.webcamVideoURL != nil
116-
let hasCameraBackground: Bool = {
117-
if case .none = cameraBackgroundStyle { return false }
118-
return true
119-
}()
120114
let hasCursor = cursorSnapshot != nil
121115
let hasZoom = zoomTimeline != nil
122116
let needsReencode =
123117
exportSettings.codec != .h264 || exportSettings.resolution != .original
124118
|| exportSettings.fps != .original
125-
let needsCompositor = hasVisualEffects || hasWebcam || needsReencode || hasCursor || hasZoom || hasCameraBackground
119+
let needsCompositor = hasVisualEffects || hasWebcam || needsReencode || hasCursor || hasZoom
126120

127121
let canvasSize: CGSize
128122
if let baseSize = canvasAspect.size(for: screenNaturalSize) {
@@ -238,8 +232,6 @@ enum VideoCompositor {
238232
end: CMTimeSubtract(overlapEnd, effectiveTrim.start)
239233
)
240234
},
241-
cameraBackgroundStyle: cameraBackgroundStyle,
242-
cameraBackgroundImage: cameraBackgroundImage
243235
)
244236

245237
let videoComposition = AVMutableVideoComposition()

0 commit comments

Comments
 (0)