I'm attempting to convert CVPixelBufferRef
s from a video source to CGImageRef
s using vImage convert libraries on 10.10. This for the most part works fine. However, each time I initialize a new vImage_Buffer
from my CVPixelBufferRef
, memory is gobbled up that is never returned.
Here is a simplified version of the conversion, that should ideally use no memory at the end of the day:
CVPixelBufferRef pixelBuffer = ...; // retained CVPixelBufferRef from somewhere else
vImage_Buffer buffer;
vImage_CGImageFormat format = {.bitsPerComponent = 8, .bitsPerPixel = 32, .colorSpace = NULL, .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, .version = 0, .decode = NULL, .renderingIntent = kCGRenderingIntentAbsoluteColorimetric};
vImage_Error imageError = vImageBuffer_InitWithCVPixelBuffer(&buffer, &format, pixelBuffer, NULL, NULL, kvImagePrintDiagnosticsToConsole);
// Do conversion here
free(buffer.data);
Commenting out the last two lines (the init and free) effectively uses no more memory than what I started with. With the two lines there, however, 6 MB are being consumed each time.
If I only comment out the free
, even more memory is being consumed, so the free is definitely doing something, but I can only assume vImageBuffer_InitWithCVPixelBuffer
is using more memory than it is supposed to. Has anyone else seen this?
For completion, here is the whole conversion method to go from CVPixelBufferRef
to NSImage
:
CVPixelBufferRef pixelBuffer = ...; // retained CVPixelBufferRef from somewhere else
NSImage *image = nil;
vImage_Buffer buffer;
vImage_CGImageFormat format = {.bitsPerComponent = 8, .bitsPerPixel = 32, .colorSpace = NULL, .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, .version = 0, .decode = NULL, .renderingIntent = kCGRenderingIntentAbsoluteColorimetric};
vImage_Error imageError = vImageBuffer_InitWithCVPixelBuffer(&buffer, &format, pixelBuffer, NULL, NULL, kvImagePrintDiagnosticsToConsole);
if (imageError != 0) {
NSLog(@"vImageBuffer_InitWithCVPixelBuffer Error: %zd", imageError);
} else {
CGImageRef imageRef = vImageCreateCGImageFromBuffer(&buffer, &format, NULL, NULL, kvImagePrintDiagnosticsToConsole|kvImageHighQualityResampling, &imageError);
if (!imageRef) {
NSLog(@"vImageCreateCGImageFromBuffer Error: %zd", imageError);
} else {
image = [[NSImage alloc] initWithCGImage:imageRef size:NSMakeSize(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef))];
CGImageRelease(imageRef);
NSAssert(image != nil, @"Creating the image failed!");
}
}
free(buffer.data);