【问题标题】:Memory leak when creating pixel buffer of image创建图像的像素缓冲区时发生内存泄漏
【发布时间】:2015-10-14 16:27:32
【问题描述】:

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

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

我尝试将变量 pixelBufferPointer 和 pxData 作为类变量,并在创建视频后销毁/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()
}

【问题讨论】:

    标签: ios swift core-video


    【解决方案1】:

    Unmanaged&lt;CVPixelBuffer&gt; 正在泄漏。

    我更喜欢 Russell Austin 的回答,但我不知道如何在没有语法错误的情况下将 pixelBufferPointer 传递给 CVPixelBufferCreate (swift noob)。做不到这一点,换行

    return pixelBufferPointer.memory!.takeUnretainedValue()
    

    return pixelBufferPointer.memory!.takeRetainedValue()
    

    修复漏洞

    【讨论】:

    • 哪个问题@RB1509?
    • 感谢您的回复 :) 我有一个关于记录视图的问题,我无法提出问题,所以请您帮我缩短它吗?
    • var buffer:CVPixelBuffer? autoreleasepool { buffer = self.pixelBufferFromImage(image: image) } if buffer != nil { let result = self.adapter.append(buffer!, withPresentationTime: present) if !result { print(self.writer.error) } buffer =无}
    • 那是我的代码,我无法提供完整的代码,但我也调试了,这段代码在记录视图时在我的设备上占用高达 1.34 Gb 的内存,它会发生崩溃。代码在 writeVideoFromImageFrames 中的另一件事,它将用于从图像转换视频。
    • 您需要显示更多代码,尤其是pixelBufferFromImage - 为什么不能提问?
    【解决方案2】:

    看看Memory leak on CIContext createCGImage at iOS 9?

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

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

    在此处了解更多上下文信息:Memory Leak in CMSampleBufferGetImageBuffer

    【讨论】:

    • 感谢您的快速回复。我不确定这是否是相同的错误,因为我在 iOS 8.3 上运行此代码并且我也没有使用 createCGImage
    • 没错,但我有一些怀疑,事实上这些原语 CVPixelBufferGetBaseAddress、CGBitmapContextCreate、CGContextDrawImage 与使用 CIContext 处理 createCGImage 时使用的相同。我确定它们是相关的。
    【解决方案3】:

    您不必使用 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 和像素缓冲池。那应该更有效率。 See this example

    【讨论】:

    • 我已经设置了该代码,但似乎在循环帧时缓冲区内存泄漏。
    【解决方案4】:

    使用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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-08-10
      相关资源
      最近更新 更多