【问题标题】:iOS - CMSampleBufferRef is not being released from captureOutput:didOutputSampleBuffer:fromConnectioniOS - CMSampleBufferRef 未从 captureOutput:didOutputSampleBuffer:fromConnection 中释放
【发布时间】:2013-08-26 12:41:59
【问题描述】:

我正在使用代码从相机捕捉帧:

- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
        :(AVCaptureConnection *)connection
{
    // Create a UIImage from the sample buffer data
    UIImage *image = [self imageFromSampleBuffer:sampleBuffer];

    if(delegate && [delegate respondsToSelector:@selector(captureManagerCapturedFrame:withFrameImage:withFrameBuffer:)]) {
        [delegate captureManagerCapturedFrame:self withFrameImage:image withFrameBuffer:sampleBuffer];
    }

}

我这样做是因为在委托方法captureManagerCapturedFrame:withFrameImage:withFrameBuffer: 中我有一个标志告诉应用程序使用返回的uiimage 或返回的sampleBuffer

委托方法是:

- (void) captureManagerCapturedFrame:(AVCamCaptureManager *)captureManager
                      withFrameImage:(UIImage *)image
                     withFrameBuffer:(CMSampleBufferRef)frameBuffer {

    if(_screen1) {
        NSLog(@"Only display camera image\n");
    }
    else if(_screen2) {
        //Enable IR
        NSLog(@"Display AND Process camera image\n");
        [self imageReconigitionProcessFrame:frameBuffer];
    }
}

imageReconigitionProcessFrame: 在哪里:

-(void)imageReconigitionProcessFrame:(CMSampleBufferRef)frameBuffer {

    //CFRetain(frameBuffer);
    MSImage *qry = [[MSImage alloc] initWithBuffer:frameBuffer orientation:AVCaptureVideoOrientationPortrait]; //MEMORY LEAK HERE???
    qry = nil;
    //CFRelease(frameBuffer);
}

此代码有效。 但这是我的问题。当此代码在仪器中运行和分析时,我看到使用的 overall bytes 快速增加,但分配分析器似乎没有增加。使用泄漏工具也看不到任何“泄漏”。但很明显,每次调用imageReconigitionProcessFrame: 都会快速增加内存,并且应用程序会在几秒钟后崩溃。当我将frameBuffer 设置为nil 时,内存不会增加(或者当然我也没有帧缓冲区来进行任何处理)。

我曾尝试使用CFRetainCFRelease(在上面的代码中注释掉)转移frameBuffer 的所有权,但这些似乎也没有任何作用。

有谁知道我可能在这个函数中泄漏内存的地方??? [[MSImage alloc] initWithBuffer: 方法是第三方 SDK(Moodstocks,这是一个很棒的图像识别 SDK),它在他们的演示中运行良好,所以我认为问题不在于这个函数。

【问题讨论】:

    标签: iphone ios objective-c core-foundation


    【解决方案1】:

    首先,感谢您提及 Moodstocks(我为他们工作):我们很高兴您发现我们的 SDK 有用!

    要回答您的问题,我猜您的代码确实包含泄漏:在imageReconigitionProcessFrame 方法的末尾,您应该调用[qry release]。 Obj-C 中的规则很简单:每当你在一个对象上手动调用alloc 时,它也应该被手动释放!

    顺便说一句,Moodstocks SDK 包装器中所做的事情:如果您查看 [MSScannerSession session: didOutputSampleBuffer:] 方法,您会发现我们确实在处理完 MSImage 对象后手动释放它。

    至于为什么profiler没有发现这个泄漏,我猜是因为默认情况下每10秒分析一次泄漏:在这种情况下,内存泄漏非常严重(1280x720帧,15+ FPS(如果您在 iPhone 5 上,持续 10 秒:至少泄漏 130 MB)代码必须在前 10 秒之前崩溃。

    希望这会有所帮助!

    【讨论】:

    • 我的项目启用了 ARC,因此添加 [qry release] 语句是不行的。我尝试将[[MSImage alloc] initWithBuffer: 直接添加到captureOutput:didOutputSampleBuffer:fromConnection 方法中(而不是通过委托类将缓冲区传回,同样的问题仍然存在。
    • 好吧,不幸的是,我不熟悉 ARC...我通常是这里的 Android 开发人员:D。尽管如此,我会尝试检查是否调用了 [MSImage dealloc] 方法:如果是这样,那么负责泄漏的对象不是 qry 而是其他东西......
    • [MSImage dealloc] 实际上正在被调用。这是我认为它与帧缓冲区有关的另一个原因,而不是 MSImage 的创建。
    • 我仍然不确定这是否是 Moodstocks 问题,但我正在向 help.moodstocks.com 发送一封电子邮件,其中包含可重现该问题的演示应用程序。演示托管在:dl.dropboxusercontent.com/u/4402291/…
    • 如果您在工具中分析它(带有分配),您应该看到“总字节数”值上升到超过一个 gb - 然后它应该崩溃。该值在您的环境中是否稳定?你能给我发电子邮件吗:brett.spurrier (at) gmail (dot) com。也许我们可以散列对其他 SO 读者不重要的细节。感谢您的帮助!
    猜你喜欢
    • 2014-09-26
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2011-10-16
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多