创建图像像素缓冲区时内存泄漏

Memory leak when creating pixel buffer of image

我正在尝试使用 AVAssetWriterInput 创建带有图像输入的视频,为此我需要创建图像的像素缓冲区。

为此,我调用了下面的函数,但在创建了一些视频后,该应用程序收到了内存警告并崩溃了。我已经使用 Instruments 对其进行了调试,但似乎存在内存泄漏 here.

我曾尝试将变量 pixelBufferPointer 和 pxData 作为 class 变量,并在创建视频后将其作为 destroy/dealloc,但这似乎没有任何区别。我应该做些什么来释放这段内存?

func createPixelBufferFromCGImage(image: CGImageRef) -> CVPixelBufferRef {
    let options = [
        "kCVPixelBufferCGImageCompatibilityKey": true,
        "kCVPixelBufferCGBitmapContextCompatibilityKey": true
    ]

    var videoWidth = 496
    var videoHeight = 668

    let frameSize = CGSizeMake(CGFloat(videoWidth), CGFloat(videoHeight))

    var pixelBufferPointer = UnsafeMutablePointer<Unmanaged<CVPixelBuffer>?>.alloc(1)

    var status:CVReturn = CVPixelBufferCreate(
        kCFAllocatorDefault,
        Int(frameSize.width),
        Int(frameSize.height),
        OSType(kCVPixelFormatType_32ARGB),
        options,
        pixelBufferPointer
    )

    var lockStatus:CVReturn = CVPixelBufferLockBaseAddress(pixelBufferPointer.memory?.takeUnretainedValue(), 0)

    var pxData:UnsafeMutablePointer<(Void)> = CVPixelBufferGetBaseAddress(pixelBufferPointer.memory?.takeUnretainedValue())

    let bitmapinfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.NoneSkipFirst.rawValue)
    let rgbColorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()

    var context:CGContextRef = CGBitmapContextCreate(
        pxData,
        Int(frameSize.width),
        Int(frameSize.height),
        8,
        //4 * CGImageGetWidth(image),
        4 * Int(frameSize.width),
        rgbColorSpace,
        bitmapinfo
    )

    CGContextDrawImage(context, CGRectMake(0, 0, frameSize.width, frameSize.height), image)

    CVPixelBufferUnlockBaseAddress(pixelBufferPointer.memory?.takeUnretainedValue(), 0)

    UIGraphicsEndImageContext()

    return pixelBufferPointer.memory!.takeUnretainedValue()
}

看看Memory leak on CIContext createCGImage at iOS 9?

我遇到了类似的问题,泄漏是由于以下代码

CGImageRef processedCGImage = [_context createCGImage:ciImage
                                                             fromRect:[ciImage extent]];

这里有更多上下文信息:Memory Leak in CMSampleBufferGetImageBuffer

您不必使用 UnsafeMutablePointer 类型。您可能正在尝试从某些 Objective-C 示例进行转换。我在做同样的事情,但最终找到了没有它的方法。尝试

var pixelBufferPointer: CVPixelBuffer?
...
var status:CVReturn = CVPixelBufferCreate(
    kCFAllocatorDefault,
    Int(frameSize.width),
    Int(frameSize.height),
    OSType(kCVPixelFormatType_32ARGB),
    options,
    &pixelBufferPointer
)

var pxData = CVPixelBufferGetBaseAddress(pixelBufferPointer)

那你就不用做takeUnRetainedValue等了

您也可以尝试使用 AVAssetWriterInputPixelBufferAdaptor 和像素缓冲池。这应该更有效率。

Unmanaged<CVPixelBuffer> 正在泄漏。

我更喜欢 Russell Austin 的回答,但我不知道如何在没有语法错误的情况下将 pixelBufferPointer 传递给 CVPixelBufferCreate(swift 菜鸟)。如果失败,请更改行

return pixelBufferPointer.memory!.takeUnretainedValue()

return pixelBufferPointer.memory!.takeRetainedValue()

修复漏洞

当使用 CVPixelBufferCreate 时,UnsafeMutablePointer 必须在取回 memory 之后 销毁

当我创建一个 CVPixelBuffer 时,我是这样做的:

func allocPixelBuffer() -> CVPixelBuffer {
    let pixelBufferAttributes : CFDictionary = [...]
    let pixelBufferOut = UnsafeMutablePointer<CVPixelBuffer?>.alloc(1)
    _ = CVPixelBufferCreate(kCFAllocatorDefault, 
                            Int(Width), 
                            Int(Height), 
                            OSType(kCVPixelFormatType_32ARGB),
                            pixelBufferAttributes, 
                            pixelBufferOut)

    let pixelBuffer = pixelBufferOut.memory!
    pixelBufferOut.destroy()
    return pixelBuffer
}