int CWebCam::SetupWebCam(const char *cparam_names, char *vconfs) { int xsize, ysize; ARParam wparam; if((ARTVideo = ar2VideoOpen(vconfs)) == 0) return(0); if(ar2VideoInqSize(ARTVideo, &xsize, &ysize) < 0) return(0); if(arParamLoad(cparam_names, 1, &wparam) < 0) return(0); arParamChangeSize(&wparam, xsize, ysize, &ARTCparam); arInitCparam(&ARTCparam); arParamDisp(&ARTCparam); ARTThreshhold = 100; arglCameraFrustumRH(&ARTCparam, VIEW_DISTANCE_MIN, VIEW_DISTANCE_MAX, projectionMat); if(ar2VideoCapStart(ARTVideo) != 0) return(0); ar2VideoCapNext(ARTVideo); return(1); }
int arVideoInqSize( int *x, int *y ) { if( vid == NULL ) return -1; return ar2VideoInqSize( vid, x, y ); }
/* CHECKED TODO * PsychAROpenVideoCaptureDevice() -- Create a video capture object. * * This function tries to open and initialize a connection to a camera * and returns the associated captureHandle for it. * * slotid = Number of slot in vidcapRecordBANK[] array to use for this camera. * win = Pointer to window record of associated onscreen window. * deviceIndex = Index of the grabber device. (Currently ignored) * capturehandle = handle to the new capture object. * capturerectangle = If non-NULL a ptr to a PsychRectangle which contains the ROI for capture. * reqdepth = Number of layers for captured output textures. (0=Don't care, 1=LUMINANCE8, 2=LUMINANCE8_ALPHA8, 3=RGB8, 4=RGBA8) * num_dmabuffers = Number of buffers in the ringbuffer queue (e.g., DMA buffers) - This is OS specific. Zero = Don't care. * allow_lowperf_fallback = If set to 1 then PTB can use a slower, low-performance fallback path to get nasty devices working. * targetmoviefilename and recordingflags are currently ignored, they would refer to video harddics recording capabilities. */ psych_bool PsychAROpenVideoCaptureDevice(int slotid, PsychWindowRecordType *win, int deviceIndex, int* capturehandle, double* capturerectangle, int reqdepth, int num_dmabuffers, int allow_lowperf_fallback, char* targetmoviefilename, unsigned int recordingflags) { PsychVidcapRecordType *capdev = NULL; int w, h; char msgerr[10000]; char config[1000]; char tmpstr[1000]; config[0] = 0; tmpstr[0] = 0; // Default camera config: #if PSYCH_SYSTEM == PSYCH_WINDOWS //strcat(config, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dsvl_input><camera show_format_dialog=\"false\" friendly_name=\"\"><pixel_format><RGB32 flip_h=\"false\" flip_v=\"true\"/></pixel_format></camera></dsvl_input>"); // Prefix: strcat(config, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dsvl_input><camera show_format_dialog=\"false\" "); // Specific deviceIndex requested, instead of auto-select? if (deviceIndex >= 1 && deviceIndex <= 3) { // Fetch optional moviename parameter as name spec string: if (targetmoviefilename == NULL) PsychErrorExitMsg(PsychError_user, "You set 'deviceIndex' to a value of 1, 2 or 3, but didn't provide the required device name string in the 'moviename' argument! Aborted."); switch(deviceIndex) { case 1: sprintf(tmpstr, "friendly_name=\"%s\" ", targetmoviefilename); break; case 2: sprintf(tmpstr, "device_name=\"%s\" ", targetmoviefilename); break; case 3: sprintf(tmpstr, "ieee1394id=\"%s\" ", targetmoviefilename); break; } strcat(config, tmpstr); } else { // Default device index: Just pass through as default device: strcat(config, "friendly_name=\"\" "); } #endif #if PSYCH_SYSTEM == PSYCH_OSX char *defaultcamconfig = ""; #endif #if PSYCH_SYSTEM == PSYCH_LINUX char *defaultcamconfig = "-dev=/dev/video0 -channel=0 -palette=YUV420P -width=320 -height=240"; #endif // Init capturehandle to none: *capturehandle = -1; if (firsttime) { // First time invocation: #if PSYCH_SYSTEM == PSYCH_WINDOWS // On Windows, we need to delay-load the libARvideo.dll DLL. This loading // and linking will automatically happen downstream. However, if delay loading // would fail, we would end up with a crash! For that reason, we try here to // load the DLL, just to probe if the real load/link/bind op later on will // likely succeed. If the following LoadLibrary() call fails and returns NULL, // then we know we would end up crashing. Therefore we'll output some helpful // error-message instead: if (NULL == LoadLibrary("libARvideo.dll")) { // Failed: printf("\n\nPTB-ERROR: Tried to startup video capture engine type 2 (ARVideo). This didn't work,\n"); printf("PTB-ERROR: because one of the required helper DLL libraries failed to load. Probably because they\n"); printf("PTB-ERROR: could not be found or could not be accessed (e.g., due to permission problems).\n\n"); printf("PTB-ERROR: Please read the online help by typing 'help ARVideoCapture' for troubleshooting instructions.\n\n"); PsychErrorExitMsg(PsychError_user, "Unable to start Videocapture engine ARVideo due to DLL loading problems. Aborted."); } #endif firsttime = FALSE; } // Slot 'slotid' will contain the record for our new capture object: // Initialize new record: vidcapRecordBANK[slotid].valid = 1; // Retrieve device record for slotid: capdev = PsychGetARVidcapRecord(slotid); capdev->camera = NULL; capdev->grabber_active = 0; capdev->scratchbuffer = NULL; // ROI rectangle specified? if (capturerectangle) { // Extract wanted width and height: w = (int) PsychGetWidthFromRect(capturerectangle); h = (int) PsychGetHeightFromRect(capturerectangle); #if PSYCH_SYSTEM == PSYCH_OSX sprintf(tmpstr, " -width=%i -height=%i", w, h); #endif #if PSYCH_SYSTEM == PSYCH_WINDOWS sprintf(tmpstr, " frame_width=\"%i\" frame_height=\"%i\" ", w, h); #endif #if PSYCH_SYSTEM == PSYCH_LINUX // TODO #endif strcat(config, tmpstr); } if (num_dmabuffers > 0) { #if PSYCH_SYSTEM == PSYCH_WINDOWS // Get framerate from num_dmabuffers argument: sprintf(tmpstr, " frame_rate=\"%i\" ", num_dmabuffers); strcat(config, tmpstr); #endif } #if PSYCH_SYSTEM == PSYCH_OSX // Disable setup dialog: strcat(config, " -nodialog"); // Specific deviceIndex requested, instead of auto-select? if (deviceIndex > 0) { sprintf(tmpstr, " -grabber=%i", deviceIndex + 1); strcat(config, tmpstr); } else { deviceIndex = 0; } switch (reqdepth) { case 2: // A no-go: Instead we use 1 channel luminance8: if (PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Video capture engine doesn't support requested Luminance+Alpha format. Will revert to pure Luminance instead...\n"); case 1: reqdepth = 1; sprintf(tmpstr, " -pixelformat=40"); break; case 3: reqdepth = 3; sprintf(tmpstr, " -pixelformat=24"); break; case 5: reqdepth = 4; sprintf(tmpstr, ""); break; case 4: case 0: reqdepth = 4; sprintf(tmpstr, " -pixelformat=ARGB"); break; default: // Unknown format: PsychErrorExitMsg(PsychError_user, "You requested an invalid image depths (not one of 0, 1, 2, 3 or 4). Aborted."); } strcat(config, tmpstr); #endif #if PSYCH_SYSTEM == PSYCH_WINDOWS if (reqdepth == 4 || reqdepth == 0) { // Default is RGB32 bit: reqdepth = 4; sprintf(tmpstr, "><pixel_format><RGB32 flip_h=\"false\" flip_v=\"true\"/></pixel_format></camera></dsvl_input>"); } else { // Only other supported format is RGB24 bit: switch (reqdepth) { case 1: if (PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Video capture engine doesn't support requested Luminance format. Will revert to RGB color instead...\n"); break; case 2: // A no-go: Instead we use 1 channel luminance8: if (PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Video capture engine doesn't support requested Luminance+Alpha format. Will revert to RGB color instead...\n"); break; case 3: break; default: // Unknown format: PsychErrorExitMsg(PsychError_user, "You requested an invalid image depths (not one of 0, 1, 2, 3 or 4). Aborted."); } reqdepth = 3; sprintf(tmpstr, "><pixel_format><RGB24 flip_h=\"false\" flip_v=\"true\"/></pixel_format></camera></dsvl_input>"); } strcat(config, tmpstr); if (deviceIndex == 4) { // Fetch optional moviename parameter as override configuration string: if (targetmoviefilename == NULL) PsychErrorExitMsg(PsychError_user, "You set 'deviceIndex' to a value of 4, but didn't provide the required override configuration string in the 'moviename' argument! Aborted."); // Reset config string: config[0] = 0; // And load the moviename argument as override string: strcat(config, targetmoviefilename); } // End of MS-Windows specific setup. #endif #if PSYCH_SYSTEM == PSYCH_LINUX // Specific deviceIndex requested, instead of auto-select? if (deviceIndex!=-1) { sprintf(tmpstr, " -dev=/dev/video%i", deviceIndex); strcat(config, tmpstr); } else { deviceIndex = 0; } reqdepth = 3; #endif // Requested output texture pixel depth in layers: capdev->reqpixeldepth = reqdepth; capdev->pixeldepth = reqdepth * 8; // Number of DMA ringbuffers to use in DMA capture mode: If no number provided (==0), set it to 8 buffers... #if PSYCH_SYSTEM == PSYCH_OSX if (num_dmabuffers == 1) { // Use single-buffering instead of triple buffering: strcat(config, " -singlebuffer"); } else { num_dmabuffers = 3; } capdev->num_dmabuffers = num_dmabuffers; #else capdev->num_dmabuffers = num_dmabuffers; #endif if (PsychPrefStateGet_Verbosity()>4) printf("PTB-INFO: Final configuration string passed to ARVideo library is:\n%s\n", config); // Prepare error message in case its needed below: sprintf(msgerr, "PTB-ERROR: Opening the %i. camera (deviceIndex=%i) failed!\n", deviceIndex + 1, deviceIndex); // Try to open and initialize camera according to given settings: capdev->camera = ar2VideoOpen(config); // Error abort if camera init failed: if(capdev->camera == NULL) { // Error abort here: capdev->valid = 0; PsychErrorExitMsg(PsychError_user, msgerr); } // Our camera should be ready: Assign final handle. *capturehandle = slotid; // Increase counter of open capture devices: numCaptureRecords++; // Set zero framerate: capdev->fps = 0; // Set image size: ar2VideoInqSize(capdev->camera, &(capdev->width), &(capdev->height)); // Create capture ROI corresponding to width and height of video image: PsychMakeRect(capdev->roirect, 0, 0, capdev->width, capdev->height); // Reset framecounter: capdev->nrframes = 0; capdev->grabber_active = 0; printf("PTB-INFO: Camera successfully opened...\n"); return(TRUE); }