VC++ GetFrame returns NULL

Post Reply
lawson
Posts: 1
Joined: Tue Feb 26, 2008 8:14 am

VC++ GetFrame returns NULL

Post by lawson »

Hi,

I'm having troubles using the GetFrame(Long*,INPCameraFrame**) function.

I've checked the previous posts about this problem but haven't found a clear answer. I also went through the "OptiTrack API, Version: 1.81 For SDK Version 1.1.034 Date: 02/21/2008" but I haven't found anything.

Here is a description of my problem:

Device: TrackIR pro 73010
Software: Windows XP SP2, OptiTrack SDK version 1.1.034

Hereafter is a simplified version of the failing code (base on the code found here http://forum.naturalpoint.com/forum/ubb ... mber=17794 ). I'm compiling with VC++ 2005 Express. The GetFrame function sets the pFrame pointer to NULL, while from what I'm understood it shouldn't... and I've also set the option to *not* send empty frames. So the following line

Code: Select all

 hr=pFrame->get_Count(&vCount);
generates a segmentation fault. Any idea of what's going wrong?

All samples downloaded from the OptiTrack SDK download page also failed to run(same error). However this code (and examples) works fine with SDK 1.1.031 or 1.1.030.

I'd rather not use

Code: Select all

if(pFrame==NULL){continue;}
as it eats up lot of CPU.

Many Thanks.

======================CODE================================
#include "stdafx.h"
#include
#include
#include "optitrack.h"

INPCameraCollection *pCameraCollection=NULL;
INPCamera *pCamera=NULL;
INPCameraFrame *pFrame=NULL;
#define HRCHECK(message) if (hr!=S_OK) { fprintf(stderr, "%s\n", message); return 0; }

int main(int argc, char* argv[])
{
HRESULT hr;
LONG count;
LONG vCount;
VARIANT voption;
int running = 1;

CoInitialize(NULL);

// create CameraCollection and Vector objects:

hr = CoCreateInstance(__uuidof(NPCameraCollection), NULL, CLSCTX_ALL,
__uuidof(INPCameraCollection), (void **) &pCameraCollection);
HRCHECK("CoCreateInstance for CameraCollection");

// find all the cameras:
hr = pCameraCollection->Enum();
HRCHECK("CameraCollection->Enum");

hr = pCameraCollection->get_Count(&count);
HRCHECK("CameraCollection->get_Count");

if (count Item(0, &pCamera);
HRCHECK("CameraCollection->Item");

hr = pCamera->Open();
HRCHECK("Camera->Open");

// turn on illumination LEDs
hr = pCamera->SetLED(NP_LED_ONE, VARIANT_TRUE);
HRCHECK("Camera->SetLED");

voption.vt = VT_BOOL;
voption.boolVal = VARIANT_FALSE;
hr = pCamera->SetOption(NP_OPTION_SEND_EMPTY_FRAMES, voption);
HRCHECK("Camera->SetOption");

hr = pCamera->Start();
HRCHECK("Camera->Start");

while(running) {
hr = pCamera->GetFrame(INFINITE, &pFrame);
HRCHECK("pCamera->GetFrame");
//if(pFrame==NULL){
// continue;
//}

hr=pFrame->get_Count(&vCount);
HRCHECK("pFrame->get_Count");
printf("objects count: %d\n",vCount);

hr = pFrame->Free();
//pFrame=NULL;
}


// shutdown
pCamera->SetLED(NP_LED_ONE, VARIANT_FALSE);
pCamera->Stop();
pCamera->Close();

CoUninitialize();

return 0;
}
beckdo
Posts: 520
Joined: Tue Jan 02, 2007 2:02 pm

Re: VC++ GetFrame returns NULL

Post by beckdo »

Ok, good question. Now here's your answer: GetFrame() returns NULL if there are no new frames available. In your particular case where you are directing OptiTrack to not send empty frames if there are no markers in the camera view, the library could return NULL indefinitely (or at least until a marker comes into view). Since the Tracker runs at 120 frames per second, you can expect to receive valid frames every 120th of a second when you call GetFrame() and you'll receive NULL every additional time you call GetFrame() as the camera hasn't had the chance to output another frame.

How to solve your problem: You need to check to make sure you have a valid frame before you try to process it. Your initial approach of "if(pFrame==NULL){continue;}" is partially correct. The problem though is that your loop will spin many many times trying to get a valid frame through GetFrame(). This wastes CPU cycles. A more appropriate solution is "if(pFrame==NULL){continue;Sleep(1);}". This will solve your problem with the CPU being buried by your initial continue; approach. You can also put say 10 as the first parameter in the GetFrame() call. This way execution will stall till another frame is delivered or times out after 10ms.
hpcv
Posts: 58
Joined: Tue Oct 23, 2007 2:09 pm

Re: VC++ GetFrame returns NULL

Post by hpcv »

Just for the record: what you mean is of course "if(pFrame==NULL){Sleep(1);continue;}" or the Sleep will still not get executed.
Post Reply