简体   繁体   中英

UIImage to CVPixelBuffer memory issue

I have a swift function that takes an UIImage and returns a CVPixelBuffer. When running this function multiple times, the memory keeps growing, leading to a crash.

What I already figured out:

  1. With instruments I isolated the memory problem in the image.draw line of code. It shows a lot of CGImage data kept in memory over the time.
  2. I isolated the function, so I'm sure that the problem is not in something that happen outside of it (in the caller), cause I removed all the code from there and the memory keeps growing.
  3. I tried dispatching the calls to this method, with some delay, to give time to the system to deallocate, but it's not working
  4. I tried wrapping multiple part of the code in autoreleasepool, still not working.
  5. I tried on the main thread, on utility.qos thread, etc, nothing changes
  6. I read every other question on StackOverflow, but looks like other people solutions aren't working in my case.

This is my code. Any help is appreciated, since I'm really banging my head on this one.

fileprivate func CreatePixelBufferFromImage(_ image: UIImage) -> CVPixelBuffer?{

    let size = image.size;

    var pxbuffer : CVPixelBuffer?

    let status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, self.exportingAdaptor!.pixelBufferPool!, &pxbuffer)

    guard (status == kCVReturnSuccess) else{
        return nil
    }

    CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));
    let pxdata = CVPixelBufferGetBaseAddress(pxbuffer!);

    let rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    let context = CGContext(data: pxdata, width: Int(size.width),
                            height: Int(size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pxbuffer!), space: rgbColorSpace,
                            bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue);

    context?.translateBy(x: 0, y: image.size.height);
    context?.scaleBy(x: 1.0, y: -1.0);

    UIGraphicsPushContext(context!)
    image.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height));
    //
    UIGraphicsPopContext()
    CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0));

    return pxbuffer
}

I found out that the problem was not the pixelbuffer, but the image reference.
It looks like (it's just my opinion based on the behaviour here) when I draw the image in the context, a lot of image pixel data gets stored in the image.cgimage object. So I solved by releasing my reference to the image I just draw after every call to this function, and the memory remained stable for all the process.

You need to drop the reference you created or the pixel buffer will remain held and then a new one gets created on each call. Dropping the ref to the pixel buffer puts it back into the pool so that it can be used on the next call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM