ofxQTKitRecorder/Grabber maximum size/framerate issue

I’m working with obviousJim/gameover’s fantastic ofxQTKit Recorder/Grabber and it works perfectly with my external logitech webcam when it is called via the qtkit record grabber (ie it displays the resolution I specify…lets say 640x480)

but if I call initRecording it immediately starts grabbing at whatever the logitech considers it’s maximum sensor size which results in something like 2fps with blurring because of the amount of data.

My temporary fix has been to run the webcam through CamTwist to force the input resolution, but I can’t for the life of me figure out where initRecording is resetting/re-initializing the size. Now I’d like to cut out camtwist because the project is launching soon and it would help with some performance/setup issues (been getting weird framerates of output videos like 20.36 and 21.3 so I’m trying to speed up whatever I can to normalize those)

This has also happened with any of those webcams that have 8mp/10mp sensors

I’ve spent the last few hours looking over initRecording versus initGrabber and tried a few things but I’m coming up empty handed because of my lack of obj-c skills

Here are the places I’m looking inside the addon:

  
- (void) initRecording:(NSString*)_selectedVideoCodec audioCodec:(NSString*)_selectedAudioCodec  
{  
	BOOL success = YES;	  
	NSError *error = nil;  
	  
	// Create the movie file output and add it to the session		[added by gameover]  
	captureMovieFileOutput = [[QTCaptureMovieFileOutput alloc] init];  
     [captureMovieFileOutput setMaximumVideoSize:NSMakeSize(640,480)]; //LASERPILOT: tried adding this piece but did not see a difference  
  
  
  
	success = [self.session addOutput:captureMovieFileOutput error:&error];  
	if (!success) {  
		ofLog(OF_LOG_ERROR, "ofxQTKitVideoGrabber - ERROR - Error adding capture output to session");  
	} else {  
		  
		[self setVideoCodec:_selectedVideoCodec];  
		[self setAudioCodec:_selectedAudioCodec];  
		  
		isRecordReady = YES;  
	}  
}  

  
void ofxQTKitVideoGrabber::initRecording(){  
	if(confirmInit()){  
		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
          
		NSString * NSvideoCodec = [NSString stringWithUTF8String: videoCodecIDString.c_str()];  
		NSString * NSaudioCodec = [NSString stringWithUTF8String: audioCodecIDString.c_str()];  
  
		[grabber initRecording:NSvideoCodec audioCodec:NSaudioCodec];  
		[pool release];	  
	}  
}  

AND initGrabber for comparison

  
bool ofxQTKitVideoGrabber::initGrabber(int w, int h){  
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
	grabber = [[QTKitVideoGrabber alloc] initWithWidth:w height:h videodevice:videoDeviceID audiodevice:audioDeviceID usingTexture:bUseTexture usingAudio:bUseAudio];  
	isInited = (grabber != nil);  
	[pool release];  
}  

  
- (id) initWithWidth:(NSInteger)_width height:(NSInteger)_height videodevice:(NSInteger)_videoDeviceID audiodevice:(NSInteger)_audioDeviceID usingTexture:(BOOL)_useTexture usingAudio:(BOOL)_useAudio  
{  
	if((self = [super init])){  
		//configure self  
		width = _width;  
		height = _height;  
		  
		//instance variables  
		cvFrame = NULL;  
		hasNewFrame = NO;  
		texture = NULL;  
		self.useTexture = _useTexture;  
		self.useAudio = _useAudio;  
		isRecordReady = NO;  
		isRecording = NO;  
		  
		[self setPixelBufferAttributes: [NSDictionary dictionaryWithObjectsAndKeys:   
										 [NSNumber numberWithInt: kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey,  
										 [NSNumber numberWithInt:width], kCVPixelBufferWidthKey,   
										 [NSNumber numberWithInt:height], kCVPixelBufferHeightKey,   
										 [NSNumber numberWithBool:YES], kCVPixelBufferOpenGLCompatibilityKey,  
										 nil]];	  
          
		//pixels = (unsigned char*)calloc(sizeof(char), _width*_height*3);  
        pixels = new ofPixels();  
        pixels->allocate(_width, _height, OF_IMAGE_COLOR);  
		  
		//init the session  
		self.session = [[[QTCaptureSession alloc] init] autorelease];  
		  
		NSError* error;  
		bool success = [self.session addOutput:self error:&error];  
		if( !success ){  
			ofLog(OF_LOG_ERROR, "ofxQTKitVideoGrabber - ERROR - Error creating capture session");  
			return nil;  
		}  
		  
		videoDeviceID = -1;		  
		[self setVideoDeviceID:_videoDeviceID];  
		  
		// if we're using audio add an audio device  
		if (self.useAudio) {  
			audioDeviceID = -1;  
			[self setAudioDeviceID:_audioDeviceID];  
		}  
          
		// give us some info about the 'native format' of our device/s  
		NSEnumerator *videoConnectionEnumerator = [[videoDeviceInput connections] objectEnumerator];  
		QTCaptureConnection *videoConnection;  
		  
		while ((videoConnection = [videoConnectionEnumerator nextObject])) {  
			NSLog(@"Video Input Format: %@\n", [[videoConnection formatDescription] localizedFormatSummary]);  
		}  
          
		NSEnumerator *audioConnectionEnumerator = [[audioDeviceInput connections] objectEnumerator];  
		QTCaptureConnection *audioConnection;  
		while ((audioConnection = [audioConnectionEnumerator nextObject])) {  
			NSLog(@"Audio Input Format: %@\n", [[audioConnection formatDescription] localizedFormatSummary]);  
		}     
		  
		[self startSession];  
	}  
	return self;  
}  

As usual when I post on a forum an answer comes to me soonafter…but I’m not all the way there

  
void ofxQTKitVideoGrabber::initRecording(int w, int h){  
	if(confirmInit()){  
		NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];  
          
       grabber =  [[QTKitVideoGrabber alloc] initWithWidth:w height:h videodevice:videoDeviceID audiodevice:audioDeviceID usingTexture:bUseTexture usingAudio:bUseAudio]; //Added this line to re-init the grabber right before recording is initialized  
  
		NSString * NSvideoCodec = [NSString stringWithUTF8String: videoCodecIDString.c_str()];  
		NSString * NSaudioCodec = [NSString stringWithUTF8String: audioCodecIDString.c_str()];  
  
		[grabber initRecording:NSvideoCodec audioCodec:NSaudioCodec];  
		[pool release];	  
	}  
}  

This works much better in most cases, but of course there are huge memory leaks and the program crashes after it records around 4 videos. I’ve tried different methods of releasing but I don’t seem to be releasing the right thing. Does anyone have any ideas? Maybe I should just be calling that initwithWidth method with the initgrabber obj-c portion?

So it looks like what I thought was broken a couple months ago ended up being fixed in the newer version of the addon but I failed to check if it was fixed in the newer version, so I was trying to fix something that wasn’t actually broken in the end, hah.

The videos that it records come out at 10fps (640x480 h264 codec) which is a little strange, but they seem to be constant at least. I’m still losing/leaking almost 20mb of memory for every iteration of my program which I’m tempted to point at qtkit for, but I haven’t done enough debugging yet