BradLarson / GPUImage2

GPUImage 2 is a BSD-licensed Swift framework for GPU-accelerated video and image processing.
BSD 3-Clause "New" or "Revised" License
4.87k stars 609 forks source link

Switching filters in real-time #51

Open andrewabdalla opened 8 years ago

andrewabdalla commented 8 years ago

Hi,

I just wanted to confirm the proper steps to change filters in real time as with the first GPUImage one had to remove targets and add the targets of the new filter they wanted to display.

Thanks

BradLarson commented 8 years ago

Yes, that should be the same between the two.

andrewabdalla commented 8 years ago

Once I perform .removeAllTargets the camera completely freezes. What am I missing? This is what I have:

let sat1 = ToonFilter() camera?.removeAllTargets() camera! --> sat1 --> renderView

Thank you!

BradLarson commented 8 years ago

Is your camera going directly to the renderView, or is there another operation between there and the view? If so, you'll need to remove the targets of the thing that is currently targeted at the view. The view can only take one input at a time.

The old framework let you do this, which lead to bizarre image corruption and flickering if you weren't careful. You should be seeing warnings on the console about trying to add too many inputs to the view, if that's the case.

0x6368 commented 7 years ago

Hi Brad,

I have the same problem. I initialize the view with camera = try Camera(sessionPreset:AVCaptureSessionPreset1280x720) camera --> getCurrentFilter() --> previewView camera.logFPS = true camera.startCapture()

Once I call the function to get a new filter, the previewView freezes. camera.removeAllTargets() camera --> getCurrentFilter() --> previewView

As you noted in the previous comment, I have to

remove the targets of the thing that is currently targeted at the view

which is in my case the targets of camera, right? But I removed them by calling camera.removeAllTargets(). I don't get any warnings in the console either.

Any idea on what the problem could be?

zubco commented 7 years ago

@0x6368 Hi, your question is same as #85. Somewhere in yourgetCurrentFilter() method, you should have smth like: previousFilter.removeAllTargets(). Cheers :smile:

BradLarson commented 7 years ago

@0x6368 - Before attaching a new filter to previewView, you have to make sure the old one has been removed from it. Otherwise, it will remain the only input to that view, and trying to add any additional inputs will be rejected. A view can only have one input at a time.

0x6368 commented 7 years ago

@zubco @BradLarson Thank you guys, fixed it by adding this in front of the removal of the targets from the camera:

for (target, _) in camera.targets {
    if (target is BasicOperation) {
        (target as! BasicOperation).removeAllTargets()
    }
}

I think this issue can be closed.

joshbernfeld commented 6 years ago
func removeAllTargets(rootTarget: ImageSource) {
    //Only this type of iterator is supported for TargetContainer
    for (target, _) in rootTarget.targets {
        //Can this target also have targets of its own?
        if let target = target as? ImageSource {
            self.removeAllTargets(rootTarget: target)
        }
    }
    rootTarget.removeAllTargets()
}

Thanks @0x6368. Here is the recursive solution if you have more than one item in your pipeline. Pass in your camera as the rootTarget.