开发者

CGDataProvider doesn't free up data on callback

开发者 https://www.devze.com 2023-01-09 12:01 出处:网络
I am creating a very big buffer (called buffer2 in the code) using CGDataProviderRef with the following code:

I am creating a very big buffer (called buffer2 in the code) using CGDataProviderRef with the following code:

-(UIImage *) glToUIImage {
NSInteger myDataLength = 768 * 1024 * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

// gl renders "upside down" so swap top to bottom into new array.
// there's gotta be a better way, but this works.
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y <1024; y++)
{
        for(int x = 0; x <768 * 4; x++)
        {
                buffer2[(1023 - y) * 768 * 4 + x] = buffer[y * 4 * 768 + x];
        }
}

 // make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, &releaseBufferData);

// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * 768;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInf开发者_开发技巧o = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

// make the cgimage
CGImageRef imageRef = CGImageCreate(768, 1024, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];

free(buffer);
//[provider autorelease];
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(imageRef);

return myImage;

}

I expect CGProvider to call back the releaseBufferData method when it is done with buffer2 so that I can free up the memory it's taken. The code for this method is:

static void releaseBufferData (void *info, const void *data, size_t size){  
 free(data);  
}

However, even though my callback method is called, the memory that data (buffer2) takes is never freed and hence it results in massive memory leaks. What am I doing wrong?


Have you ever CGDataProviderRelease your provider? The callback will not be called if you don't release the data provider.


For some peculiar reason this is not an issue anymore.


Just in case this helps someone else. I was having the same problem. It started working once I called

CGImageRelease(imageRef);

right before the

CGDataProviderRelease(provider);


malloc isn't freed in a "release" callback when it allocates on one thread but the callback that deallocates it is executed on another. Wrap both your allocation and deallocation in this:

dispatch_async(dispatch_get_main_queue(), ^{
 // *malloc* and *free* go here; don't call &releaseCallBack or some such anywhere 
});

A second thing to try is a completion block. Instead of returning an image in the traditional way (via a method return property), use a completion block. The UIImage will be freed as soon as the completion block is closed.

For example, if you're trying to save multiple images to the Photos library, but the malloc'd data isn't freeing after each image is created, then pass the image back via a completion block, making sure you create no new instance of the image that is passed back, and it will be gone as soon as it hits the };

A third thing is calloc instead of malloc:

GLubyte *buffer = (GLubyte *)calloc(myDataLength, sizeof(GLubyte));

That's what I use now where I once had malloc, which obviates the need for the prior two suggestions. I use OpenGL to populate a collection view consisting of a single row of cells, each with one frame from a video. To skim the video, you slide the collection view, if you see a frame you want to save as an image, you long press it; if you want to advance to that frame in the video, you tap it. As you know, even short videos have a lot of frames; the calloc solution knocks about 256 MB off total memory usage every call to the release callback, to which it builds when you scroll blurry fast.

0

精彩评论

暂无评论...
验证码 换一张
取 消