2

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
}
1
  • Could you post standalone code? What is for example exportingAdaptor? Commented Jan 29, 2020 at 12:20

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I know this question is old, but I think I am facing the same problem. How did you exactly solve this? How did you release the reference to the image?
0

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.

1 Comment

Tried like this: var buffer = self.CreatePixelBufferFromImage(image); buffer = nil; It's still not working. Memory goes up

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.