Gradual memory leak in loop over contents of QTMovie
- by Benji XVI
I have a simple foundation tool that exports every frame of a movie as a .tiff file. Here is the relevant code:
NSString* movieLoc = [NSString stringWithCString:argv[1]];
QTMovie *sourceMovie = [QTMovie movieWithFile:movieLoc error:nil];
int i=0;
while (QTTimeCompare([sourceMovie currentTime], [sourceMovie duration]) != NSOrderedSame) {
// save image of movie to disk
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSString *filePath = [NSString stringWithFormat:@"/somelocation_%d.tiff", i++];
NSData *currentImageData = [[sourceMovie currentFrameImage] TIFFRepresentation];
[currentImageData writeToFile:filePath atomically:NO];
NSLog(@"%@", filePath);
[sourceMovie stepForward];
[arp release];
}
[pool drain];
return 0;
As you can see, in order to prevent very large memory buildups with the various transparently-autoreleased variables in the loop, we create, and flush, an autoreleasepool with every run through the loop.
However, over the course of stepping through a movie, the amount of memory used by the program still gradually increases. Instruments is not detecting any memory leaks per se, but the object trace shows certain General Data blocks to be increasing in size.
[Edited out reference to slowdown as it doesn't seem to be as much of a problem as I thought.]
Edit: let's knock out some parts of the code inside the loop & see what we find out...
Test 1
while (banana) {
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSString *filePath = [NSString stringWithFormat:@"/somelocation_%d.tiff", i++];
NSLog(@"%@", filePath);
[sourceMovie stepForward];
[arp release];
}
Here we simply loop over the whole movie, creating the filename and logging it.
Memory characteristics: remains at 15MB usage for the duration.
Test 2
while (banana) {
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSImage *image = [sourceMovie currentFrameImage];
[sourceMovie stepForward];
[arp release];
}
Here we add back in the creation of the NSImage from the current frame.
Memory characteristics: gradually increasing memory usage. RSIZE is at 60MB by frame 200; 75MB by f300.
Test 3
while (banana) {
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
NSImage *image = [sourceMovie currentFrameImage];
NSData *imageData = [image TIFFRepresentation];
[sourceMovie stepForward];
[arp release];
}
We've added back in the creation of an NSData object from the NSImage.
Memory characteristics: Memory usage is again increasing: 62MB at f200; 75MB at f300. In other words, largely identical.
It looks like a memory leak in the underlying system QTMovie uses to do currentFrameImage, to me.