我正在为iOS上录制的视频的帧图像添加失真效果。对于分辨率为640x640的14秒视频,应用程序崩溃并出现内存错误。我认为所有的内存都得到了适当的释放。
我发现很奇怪,分析器告诉我这个应用程序最多消耗了20MB!我也找不到内存泄漏。CoreImage库在整个处理时间内确实积累了大约580MB的内存,但在每个处理帧之后都会释放内存,因此不会导致崩溃。
如果我注释掉失真过滤器,一切都正常,所以我假设错误在过滤部分。我在安装了iOS 8的iPhone 5s上进行测试。
这是GPUImage中的错误吗?为什么我不能分析过多的内存消耗?
感谢您的每一个回答!:)
下面是相关的代码片段:
- (CIImage *) render:(CIImage*)targetImage imageContext:(CIContext*) imageContext
facialFeatures:(NSArray*)facialFeatures currentFrameInd:(int)frameInd
{
if ( !facialFeatures ) return targetImage;
@autoreleasepool {
CGImageRef inputImage = [imageContext createCGImage:targetImage fromRect:[targetImage extent]];
GPUImagePicture *sourcePicture = [[GPUImagePicture alloc] initWithCGImage:inputImage];
GPUImageOutput *currentOutput = sourcePicture;
// Search through multiple faces.
for ( ArtechFacialFeature *facialFeature in facialFeatures ) {
// Create the distortion for one face.
for ( ArtechImageDistortionDescription *distortion in distortions ) {
GPUImageFilter *imageFilter = [self createDistortionFilter:distortion
facialFeature:facialFeature imageExtent:targetImage.extent];
[currentOutput addTarget:imageFilter];
currentOutput = imageFilter;
}
}
[currentOutput useNextFrameForImageCapture];
[sourcePicture processImage];
UIImage *currentFilteredVideoFrame = [currentOutput imageFromCurrentFramebuffer];
targetImage = [targetImage initWithCGImage:currentFilteredVideoFrame.CGImage];
[sourcePicture removeAllTargets];
currentFilteredVideoFrame = nil;
sourcePicture = nil;
currentOutput = nil;
CFRelease( inputImage );
}
return targetImage;
}发布于 2014-12-09 00:50:52
我突然想到的一件事是,您在每个传入帧上都创建了一个新图像和一组新滤镜。这将是非常低效的,并且可能会使GPUImage中的内部帧缓冲区缓存系统超载。
相反,应从GPUImage纹理输入开始创建过滤器链。分配滤镜一次,只需在每个新帧上更改其属性。对于输入,如果您将核心图像输出渲染到由纹理支持的OpenGL ES上下文中,然后将该纹理馈送到GPUImage中,您将避免非常昂贵的GPU->CPU->GPU路径,并将所有内容都保留在GPU上。
对于创建一次并为每个帧重用的过滤器,内部帧缓冲区缓存机制应该能够将内存使用量限制在一个恒定且相对较低的值。
由于这里的退化情况,可能确实存在泄漏(我不经常使用这种频率构建和拆除过滤器,因此在释放时可能存在竞争条件),但尝试重新处理以重用过滤器在任何情况下都可能是一种更好的方法。
关于您报告的20MB值,这很可能来自Allocations工具,它隐藏了OpenGL ES内存使用情况。取而代之的是查看内存监视器,以获得应用程序总内存使用量的真实读数。我敢打赌,它会高得多。
发布于 2016-07-14 17:22:51
- (void)addObservers {
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)removeObservers {
[[NSNotificationCenter defaultCenter]removeObserver:self
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter]removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
}https://stackoverflow.com/questions/27356855
复制相似问题