gpt4 book ai didi

ios - GPUImageFilter 单例断言失败(useNextFrameForImageCapture)

转载 作者:行者123 更新时间:2023-11-28 18:33:14 25 4
gpt4 key购买 nike

我正在尝试通过使用包含可供我在任何地方使用的图像过滤器的单例对象来优化某些图像过滤。我遇到了一个问题,我相信我一次调用了过滤器几次(显示了几个单元格,在下载图像之后,在显示之前,我正在用过滤器处理图像,这可能几乎同时发生) .

我遇到了这个问题:

NSAssert(framebufferReferenceCount > 0, @"试图过度释放帧缓冲区,您是否忘记在使用 -imageFromCurrentFramebuffer 之前调用 -useNextFrameForImageCapture?");

https://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageFramebuffer.m#L269

这是我的代码:

接口(interface):

#import <GPUImage/GPUImage.h>

@interface GPUImageFilterManager : NSObject

+ (GPUImageFilterManager*)sharedInstance;

@property (nonatomic, strong) GPUImageiOSBlurFilter *blurFilter;
@property (nonatomic, strong) GPUImageLuminanceThresholdFilter *luminanceFilter;

@end

实现:

#import "GPUImageFilterManager.h"

@implementation GPUImageFilterManager

+ (GPUImageFilterManager*)sharedInstance {
static GPUImageFilterManager *_sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [GPUImageFilterManager new];
});
return _sharedInstance;
}

- (instancetype)init {
self = [super init];
if (self) {
self.luminanceFilter = [[GPUImageLuminanceThresholdFilter alloc] init];
self.luminanceFilter.threshold = 0.5;

self.blurFilter = [[GPUImageiOSBlurFilter alloc] init];
[self.blurFilter setBlurRadiusInPixels:BLUR_RADIUS];
[self.blurFilter setSaturation:SATURATION];
[self.blurFilter setDownsampling:DOWNSAMPLING];
[self.blurFilter setRangeReductionFactor:RANGEREDUCTION];
}
return self;
}

-(GPUImageiOSBlurFilter*)blurFilter {
[_blurFilter useNextFrameForImageCapture];
return _blurFilter;
}

-(GPUImageLuminanceThresholdFilter*)luminanceFilter {
[_luminanceFilter useNextFrameForImageCapture];
return _luminanceFilter;
}

在我的代码中我调用:

[[[GPUImageFilterManager sharedInstance] blurFilter] imageByFilteringImage:image];

以前,我在每个单元格中都有一个 GPUImageLuminanceThresholdFilter 属性,我想对其进行优化以仅使用它的一个实例,但现在看来我无法同时处理多个图像。这里有什么想法或建议吗?

最佳答案

我对这里出了什么问题的猜测是 -imageByFilteringImage: 并不是真正的原子操作,如果您同时在多个线程上触发它,您将得到奇怪的行为。看看该方法内部发生了什么(通过 -newCGImageByFilteringCGImage: 方法):

- (CGImageRef)newCGImageByFilteringCGImage:(CGImageRef)imageToFilter;
{
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithCGImage:imageToFilter];

[self useNextFrameForImageCapture];
[stillImageSource addTarget:(id<GPUImageInput>)self];
[stillImageSource processImage];

CGImageRef processedImage = [self newCGImageFromCurrentlyProcessedOutput];

[stillImageSource removeTarget:(id<GPUImageInput>)self];
return processedImage;
}

创建一个 GPUImagePicture,附加到过滤器,进行处理,并提取输出。如果您在多个线程中使用相同的过滤器,并且调用此方法,则很可能您会在不同的点中断此方法并创建奇怪的过滤路径。因此出现上述错误(以及其他潜在的崩溃和图像损坏)。

如果你想在单例中使用这个过滤器,我的建议是设置一个串行调度队列,并将对该过滤器的访问包装在对该队列的调度中。特别是,我会围绕你的 -imageByFilteringImage: 将同步调度包装到这个队列,以保证它总是完全执行并返回一个图像,然后再被不同的图像和线程触发。

GPUImage OpenGL ES 上下文一次只能执行一个渲染操作,因此通过将对过滤器的访问限制为一次只有一个线程,您不会损失太多。它的实现也非常简单,我在整个框架中使用这种通过 GCD 队列限制对共享资源的访问的模式。

关于ios - GPUImageFilter 单例断言失败(useNextFrameForImageCapture),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23894303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com