BradLarson / GPUImage

An open source iOS framework for GPU-based image and video processing
http://www.sunsetlakesoftware.com/2012/02/12/introducing-gpuimage-framework
BSD 3-Clause "New" or "Revised" License
20.24k stars 4.61k forks source link

Crash when using GPUImagePicture with multiple GPUImageViews #2358

Open mofojed opened 8 years ago

mofojed commented 8 years ago

I've been playing with the GPUImage framework, and have been trying to build an Instagram type UI where you can take a picture and apply filters. So far what I've got is here: https://github.com/mofojed/GPUImage (under FilterCarousel in the "examples" folder; basically takes the FilterShowcase and puts it in an Instagram like UI @BradLarson if you like it, feel free to include it as an example showcasing the filters).

I've got the filters working properly while still in camera preview mode, but after capturing a picture, it crashes when applying filters in the carousel.

The crash happens with a few different filters, but it seems to usually be on a glDrawArrays call, for example, one case occurs in the GPUImageHistogramFilter, get an EXC_BAD_ACCESS on line 305: glDrawArrays(GL_POINTS, 0, inputTextureSize.width * inputTextureSize.height / (CGFloat)_downsamplingFactor);

To capture the photo, I'm doing the following:

    GPUImageFilter *cleanFilter = [[GPUImageFilter alloc] init];
    [self.camera addTarget:cleanFilter];

    [self.camera capturePhotoAsImageProcessedUpToFilter:cleanFilter withOrientation:UIImageOrientationUp withCompletionHandler:^(UIImage *processedImage, NSError *error) {
        [self.camera removeTarget:cleanFilter];

        if (error) {
            NSLog(@"There was an error: %@", error);
            return;
        }

        self.capturedImage = processedImage;
        self.capturedImageSource = [[GPUImagePicture alloc] initWithImage:self.capturedImage];

        [self.camera removeAllTargets];

        [self updateMainView];

        [self.previewCollectionView reloadData];
    }];

Then I route this to a bunch of GPUImageViews in a UICollectionView, and this is when bad things happen:

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
    PreviewCollectionViewCell *previewCell = (PreviewCollectionViewCell*)cell;
    GPUImageFilterWrapper *wrapper = self.filters[indexPath.row];

    [wrapper.filter addTarget:previewCell.gpuImageView];

    if (nil != self.capturedImageSource) {
        // Set up the filter to read from the captured image
        [self.capturedImageSource addTarget:wrapper.filter];
        [wrapper.filter useNextFrameForImageCapture];
        [self.capturedImageSource processImage];
    } else {
        [self.camera addTarget:wrapper.filter];
    }
    previewCell.nameLabel.text = wrapper.title;
}

I suspect it has something to do with calling the GPUImagePicture processImage method repeatedly while adding/removing filters as the UICollectionView scrolls, but my understanding is that I have to call the processImage after adding a new filter. Any idea what could be causing these crashes? I suspect there is something I'm missing and I'm misusing the framework, but I can't figure it out.