首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GPUImage内存错误

GPUImage内存错误
EN

Stack Overflow用户
提问于 2014-12-08 19:20:53
回答 2查看 1.1K关注 0票数 2

我正在为iOS上录制的视频的帧图像添加失真效果。对于分辨率为640x640的14秒视频,应用程序崩溃并出现内存错误。我认为所有的内存都得到了适当的释放。

我发现很奇怪,分析器告诉我这个应用程序最多消耗了20MB!我也找不到内存泄漏。CoreImage库在整个处理时间内确实积累了大约580MB的内存,但在每个处理帧之后都会释放内存,因此不会导致崩溃。

如果我注释掉失真过滤器,一切都正常,所以我假设错误在过滤部分。我在安装了iOS 8的iPhone 5s上进行测试。

这是GPUImage中的错误吗?为什么我不能分析过多的内存消耗?

感谢您的每一个回答!:)

下面是相关的代码片段:

代码语言:javascript
复制
- (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;
}
EN

回答 2

Stack Overflow用户

发布于 2014-12-09 00:50:52

我突然想到的一件事是,您在每个传入帧上都创建了一个新图像和一组新滤镜。这将是非常低效的,并且可能会使GPUImage中的内部帧缓冲区缓存系统超载。

相反,应从GPUImage纹理输入开始创建过滤器链。分配滤镜一次,只需在每个新帧上更改其属性。对于输入,如果您将核心图像输出渲染到由纹理支持的OpenGL ES上下文中,然后将该纹理馈送到GPUImage中,您将避免非常昂贵的GPU->CPU->GPU路径,并将所有内容都保留在GPU上。

对于创建一次并为每个帧重用的过滤器,内部帧缓冲区缓存机制应该能够将内存使用量限制在一个恒定且相对较低的值。

由于这里的退化情况,可能确实存在泄漏(我不经常使用这种频率构建和拆除过滤器,因此在释放时可能存在竞争条件),但尝试重新处理以重用过滤器在任何情况下都可能是一种更好的方法。

关于您报告的20MB值,这很可能来自Allocations工具,它隐藏了OpenGL ES内存使用情况。取而代之的是查看内存监视器,以获得应用程序总内存使用量的真实读数。我敢打赌,它会高得多。

票数 0
EN

Stack Overflow用户

发布于 2016-07-14 17:22:51

代码语言:javascript
复制
- (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];
}
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27356855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档