CIImage和CIDetector与AVCaptureOutput内存泄漏一起使用

时间:2016-10-19 22:20:39

标签: ios memory-leaks avcapturesession core-image

我正在使用CIContext,CIDetector和CIImage来检测从captureOutput中的样本派生的vImage_Buffer中的矩形:didOutputSampleBuffer:fromConnection:。似乎探测器或CIImage保留了内存,无法释放。 这是有问题的代码 - 跳过此代码显示内存保持不变,否则会增加直到崩溃应用程序:

// ...rotatedBuf and format managed outside scope

// Use a CIDetector to find any potential subslices to process
CVPixelBufferRef cvBuffer;
vImageCVImageFormatRef cvFormat = vImageCVImageFormat_CreateWithCVPixelBuffer(pixelBuffer);
CVPixelBufferCreate(kCFAllocatorSystemDefault, rotatedBuf.width, rotatedBuf.height, kCVPixelFormatType_32BGRA, NULL, &cvBuffer);
CVPixelBufferLockBaseAddress(cvBuffer, kCVPixelBufferLock_ReadOnly);
err = vImageBuffer_CopyToCVPixelBuffer(&rotatedBuf, &format, cvBuffer, cvFormat, NULL, kvImageNoFlags);
CVPixelBufferUnlockBaseAddress(cvBuffer, kCVPixelBufferLock_ReadOnly);
if (![self vImageDidError:err]) {
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:cvBuffer];
    NSArray *feats = [self.ciDetector featuresInImage:ciImage options:nil];
    if (feats && [feats count]) {
        for (CIFeature *feat in feats) {
            // The frame is currently in image space, so we must convert it to a unitless space like the other rects.
            CGRect frame = feat.bounds;
            CGRect clip  = CGRectMake(frame.origin.x / rotatedBuf.width, frame.origin.y / rotatedBuf.height,
                                      frame.size.width / rotatedBuf.width, frame.size.height / rotatedBuf.height);
            rects = [rects arrayByAddingObject:[NSValue valueWithCGRect:clip]];
        }
    }
}
CVPixelBufferRelease(cvBuffer);
vImageCVImageFormat_Release(cvFormat);

其他答案似乎建议在自动释放池中包装或每帧创建一个新的CIDector,但都不会影响内存使用。

CIDetector isn't releasing memory

CIDetector won't release memory - swift

编辑:将调度队列切换到dispatch_main_queue以外的其他队列似乎已清除内存问题并保持UI响应。

1 个答案:

答案 0 :(得分:0)

我找到了一个不同的解决方案 - 在我的情况下,我在主调度队列上运行了所有处理。修复这种情况的原因是创建了一个新的队列来运行处理。我意识到,当我的大部分CPU时间用于对featuresInImage:options:的调用时,可能就是这种情况。它没有解释导致内存问题的原因,但现在我在一个单独的队列中运行,内存很好而且不变。