vidGrabber.close() crashes application in linux

I’m using the video grabber close() function in my application. It works fine on windows, but it seems to crash on linux.

I also loaded up the openCV example in linux and added a vidGrabber.close() function on mouseReleased() to test whether it was only my application that was crashing. The openCv example also crashed using the close().

I’ve narrowed it down to the ucGrabber.close_unicap(); in the ofVideoGrabber.cpp file which points to the close_unicap() function in ofUCUtils. I’ not sure what the problem is or how to fix it since I haven’t found how to properly debug in linux/codeblocks.

Sorry to bump this, but can anyone quickly check this out? Simple load the video example and add a vidGrabber.close() on mouse pressed to see if it crashes.

I can’t seem to get past this bug. Feel free to move this to the bugs thread.

Hi cerupcat

when you close the videograbber, all the memory it’s using is released, so if you try to grab a new frame it will crash.

never supposed that will be a problem or in other platforms it will work, but indeed it really makes sense that the application doesn’t crash.

I’ll take a look into this and make sure that if the videograbber is not inited, it doesn’t try to access the memory structures in it.

Sounds good. Please test.

Basically in my real code, I have a next/previous button that will switch to various cameras that are detected by OF. So what I do is, when the button is pressed, it stops the camera from grabbing frames, closes the current camera, and then sets the next device ID, and inits the new camera. The problem is, it crashes when closing every time and is related to how it’s clearing the memory, but I can’t narrow it down. I have this working on both mac and windows just great.

mmmh…

I thought you were trying to grab new frames even when the device is closed, but then it should be a problem with the close method. Indeed i’m realizing that sometimes when closing applications that use the videograbber it returns a memory dump.

i’ll take a look…

Correct, it’s the actual close function that crashes it.

Hi cerupcat

I’m working with the new version that will be in 0.06, so cannot post the changes because some parts depend on a new version of ffmpeg, but try substituting this lines in the close_unicap method in ofUCUtils.cpp:

  
if ( pixels != NULL ) {  
	delete pixels;  
}  
	  
if ( src != NULL ){  
	avpicture_free(src);  
	delete src;  
}  

with:

  
if ( pixels != NULL ) {  
	delete[] pixels;  
}  
	  
if ( src != NULL ){  
	delete src;  
}  

and in ofVideoGrabber.cpp at the end of the close method these:

  
if (pixels != NULL){  
	delete pixels;  
	pixels = NULL;  
}  

with:

  
if (pixels != NULL){  
	delete[] pixels;  
	pixels = NULL;  
}  

Thanks arturo, but I dont have any

if ( pixels != NULL ) {
delete[] pixels;
}

in the ofUCUtils.cpp I’m using. There’s no pixel array in that class.

I tried using your OF 0.6 download you posted in another thread but couldn’t get everything compiled.

sorry I missed this…

try changing:

  
void ofUCUtils::close_unicap() {  
  
	unicap_stop_capture(handle);  
	if (buffer.data != NULL) {  
		free(buffer.data);  
	}  
  
	if (src != NULL){  
		avpicture_free(src);  
		delete src;  
	}  
	if (dst != NULL){  
		avpicture_free(dst);  
		delete dst;  
	}  
}  

with:

  
  
void ofUCUtils::close_unicap() {  
	unicap_stop_capture(handle);  
	  
	if (src != NULL){  
		delete src;  
	}  
	if (dst != NULL){  
		avpicture_free(dst);  
		delete dst;  
	}  
}  

cannot test it now, so perhaps there’s a memory leak.

Also this version of 0.06 I uploaded later should work:
http://65.111.166.199/openframeworks/of-preRelease-v0.059-linux-cb-FAT.tar.gz

Thanks. I tried the new code. It works to some extent, but if you switch back and forth between cameras eventually you get a buffer error (Unicap : Failed to wait for buffer) and it crashes.

Also, I think we need to add error catching to the videoGrabber so that when a device number is chosen or a camera is not found, the application doesn’t crash.

I’ll see if I can port my stuff to the new OF version and see if it’s fixed, but for now the above still has the problem.

update:

With OF .06 closing doesn’t work at all and crashes with a seg fault.

What I’m trying to do is switch between webcams that are loaded on a computer. So if someone has 3 webcams hooked up, then it should load the first one, then if a button is pressed the current one should close and the next one should open, etc.

Here’s the current code I’m using. It crashes on the vidGrabber.close() part on the .06 version and on .05 with the fix above it crashes after switching a few times.

  
  
activeInput = false; //this stops the app from doing anything when changing source  
  
deviceID += 1;  
if(deviceID >= vidGrabber.getDeviceCount() - 1) {deviceID = vidGrabber.getDeviceCount() - 1;}                   
else{  
vidGrabber.close();  
vidGrabber.setDeviceID(deviceID);  
vidGrabber.setVerbose(true);                                                               vidGrabber.initGrabber(camWidth,camHeight);  
bLearnBakground = true;  
}                                         
  
activeInput = true;  
  

The code works fine on mac and windows. So I’m still assuming that the code for closing devices on linux isn’t right. Sorry, I can’t be more help, I’m not sure how to debug on linux since I can’t get codeblocks debugger to work and I’m not sure how seg faults can be debugged.

ok, it should be corrected now in 0.06.

About your example, setting the activeInput flag is not thread safe, as the app can look if activeInput is true, try to grab the frame an meanwhile you press the mouse and close the device.

I’ve tried anyway to grab with a closed device and it doesn’t crash. Perhaps is a problem with unicap when you open and close several times. try also with 0.06, as it has the last unicap library, and perhpas some of that errors has been corrected.

Also another posibility is to have every device opened in a diferent videoGrabber variable and switch between them without closing. This also should be faster as you don’t need to open and close the devices once and again.