IplImage *image_input::capture_uvc_camera() { #ifdef ENABLE_CAMERA struct vdIn *videoIn; char *videodevice = (char*)"/dev/video0"; int format = V4L2_PIX_FMT_YUYV; int grabmethod = 1; IplImage* frame; videoIn = (struct vdIn *) calloc (1, sizeof (struct vdIn)); if (init_videoIn(videoIn, videodevice, camera.width, camera.height, format, grabmethod) < 0) { puts("init failed"); exit (1); } //Reset all camera controls v4l2ResetControl (videoIn, V4L2_CID_BRIGHTNESS); v4l2ResetControl (videoIn, V4L2_CID_CONTRAST); v4l2ResetControl (videoIn, V4L2_CID_SATURATION); v4l2ResetControl (videoIn, V4L2_CID_GAIN); //Setup Camera Parameters v4l2SetControl (videoIn, V4L2_CID_BRIGHTNESS, camera.brightness); v4l2SetControl (videoIn, V4L2_CID_CONTRAST, camera.contrast); v4l2SetControl (videoIn, V4L2_CID_SATURATION, camera.saturation); v4l2SetControl (videoIn, V4L2_CID_GAIN, camera.gain); if (uvcGrab (videoIn) < 0) { fprintf(stderr, "Error grabbing\n"); close_v4l2(videoIn); free(videoIn); exit(1); } // IplImage frame = cvCreateImage(cvSize(videoIn->width, videoIn->height), IPL_DEPTH_8U, 3); // convert image format convert_yuyv_to_rgb(videoIn->framebuffer, (unsigned char*)frame->imageData, videoIn->width, videoIn->height); close_v4l2 (videoIn); free (videoIn); return frame; #else // ENABLE_CAMERA return NULL; #endif // ENABLE_CAMERA }
/****************************************************************************** Description.: process commands, allows to set v4l2 controls Input Value.: * control specifies the selected v4l2 control's id see struct v4l2_queryctr in the videodev2.h * value is used for control that make use of a parameter. Return Value: depends in the command, for most cases 0 means no errors and -1 signals an error. This is just rule of thumb, not more! ******************************************************************************/ int input_cmd(int plugin_number, unsigned int control_id, unsigned int group, int value) { int ret = -1; int i = 0; DBG("Requested cmd (id: %d) for the %d plugin. Group: %d value: %d\n", control_id, plugin_number, group, value); switch(group) { case IN_CMD_GENERIC: { int i; for (i = 0; i<pglobal->in[plugin_number].parametercount; i++) { if ((pglobal->in[plugin_number].in_parameters[i].ctrl.id == control_id) && (pglobal->in[plugin_number].in_parameters[i].group == IN_CMD_GENERIC)){ DBG("Generic control found (id: %d): %s\n", control_id, pglobal->in[plugin_number].in_parameters[i].ctrl.name); DBG("New %s value: %d\n", pglobal->in[plugin_number].in_parameters[i].ctrl.name, value); return 0; } } DBG("Requested generic control (%d) did not found\n", control_id); return -1; } break; case IN_CMD_V4L2: { ret = v4l2SetControl(cams[plugin_number].videoIn, control_id, value, plugin_number, pglobal); if(ret == 0) { pglobal->in[plugin_number].in_parameters[i].value = value; } else { DBG("v4l2SetControl failed: %d\n", ret); } return ret; } break; case IN_CMD_RESOLUTION: { // the value points to the current formats nth resolution if(value > (pglobal->in[plugin_number].in_formats[pglobal->in[plugin_number].currentFormat].resolutionCount - 1)) { DBG("The value is out of range"); return -1; } int height = pglobal->in[plugin_number].in_formats[pglobal->in[plugin_number].currentFormat].supportedResolutions[value].height; int width = pglobal->in[plugin_number].in_formats[pglobal->in[plugin_number].currentFormat].supportedResolutions[value].width; ret = setResolution(cams[plugin_number].videoIn, width, height); if(ret == 0) { pglobal->in[plugin_number].in_formats[pglobal->in[plugin_number].currentFormat].currentResolution = value; } return ret; } break; case IN_CMD_JPEG_QUALITY: if((value >= 0) && (value < 101)) { pglobal->in[plugin_number].jpegcomp.quality = value; if(IOCTL_VIDEO(cams[plugin_number].videoIn->fd, VIDIOC_S_JPEGCOMP, &pglobal->in[plugin_number].jpegcomp) != EINVAL) { DBG("JPEG quality is set to %d\n", value); ret = 0; } else { DBG("Setting the JPEG quality is not supported\n"); } } else { DBG("Quality is out of range\n"); } break; } return ret; }
int main (int argc, char *argv[]) { char *videodevice = "/dev/video0"; char *outputfile = "snap.jpg"; char *post_capture_command[3]; int format = V4L2_PIX_FMT_MJPEG; int grabmethod = 1; int width = 320; int height = 240; int brightness = 0, contrast = 0, saturation = 0, gain = 0; int verbose = 0; int delay = 0; int quality = 95; int post_capture_command_wait = 0; time_t ref_time; struct vdIn *videoIn; FILE *file; (void) signal (SIGINT, sigcatch); (void) signal (SIGQUIT, sigcatch); (void) signal (SIGKILL, sigcatch); (void) signal (SIGTERM, sigcatch); (void) signal (SIGABRT, sigcatch); (void) signal (SIGTRAP, sigcatch); // set post_capture_command to default values post_capture_command[0] = NULL; post_capture_command[1] = NULL; post_capture_command[2] = NULL; //Options Parsing (FIXME) while ((argc > 1) && (argv[1][0] == '-')) { switch (argv[1][1]) { case 'v': verbose++; break; case 'o': outputfile = &argv[1][2]; break; case 'd': videodevice = &argv[1][2]; break; case 'x': width = atoi (&argv[1][2]); break; case 'y': height = atoi (&argv[1][2]); break; case 'r': grabmethod = 0; break; case 'm': format = V4L2_PIX_FMT_YUYV; break; case 't': delay = atoi (&argv[1][2]); break; case 'c': post_capture_command[0] = &argv[1][2]; break; case 'w': post_capture_command_wait = 1; break; case 'B': brightness = atoi (&argv[1][2]); break; case 'C': contrast = atoi (&argv[1][2]); break; case 'S': saturation = atoi (&argv[1][2]); break; case 'G': gain = atoi (&argv[1][2]); break; case 'q': quality = atoi (&argv[1][2]); break; case 'h': usage (); break; default: fprintf (stderr, "Unknown option %s \n", argv[1]); usage (); } ++argv; --argc; } if ((width > 960) || (height > 720) || (quality != 95)) format = V4L2_PIX_FMT_YUYV; if (post_capture_command[0]) post_capture_command[1] = outputfile; if (verbose >= 1) { fprintf (stderr, "Using videodevice: %s\n", videodevice); fprintf (stderr, "Saving images to: %s\n", outputfile); fprintf (stderr, "Image size: %dx%d\n", width, height); fprintf (stderr, "Taking snapshot every %d seconds\n", delay); if (grabmethod == 1) fprintf (stderr, "Taking images using mmap\n"); else fprintf (stderr, "Taking images using read\n"); if (post_capture_command[0]) fprintf (stderr, "Executing '%s' after each image capture\n", post_capture_command[0]); } videoIn = (struct vdIn *) calloc (1, sizeof (struct vdIn)); if (init_videoIn (videoIn, (char *) videodevice, width, height, format, grabmethod) < 0) exit (1); //Reset all camera controls if (verbose >= 1) fprintf (stderr, "Resetting camera settings\n"); v4l2ResetControl (videoIn, V4L2_CID_BRIGHTNESS); v4l2ResetControl (videoIn, V4L2_CID_CONTRAST); v4l2ResetControl (videoIn, V4L2_CID_SATURATION); v4l2ResetControl (videoIn, V4L2_CID_GAIN); //Setup Camera Parameters if (brightness != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera brightness to %d\n", brightness); v4l2SetControl (videoIn, V4L2_CID_BRIGHTNESS, brightness); } else if (verbose >= 1) { fprintf (stderr, "Camera brightness level is %d\n", v4l2GetControl (videoIn, V4L2_CID_BRIGHTNESS)); } if (contrast != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera contrast to %d\n", contrast); v4l2SetControl (videoIn, V4L2_CID_CONTRAST, contrast); } else if (verbose >= 1) { fprintf (stderr, "Camera contrast level is %d\n", v4l2GetControl (videoIn, V4L2_CID_CONTRAST)); } if (saturation != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera saturation to %d\n", saturation); v4l2SetControl (videoIn, V4L2_CID_SATURATION, saturation); } else if (verbose >= 1) { fprintf (stderr, "Camera saturation level is %d\n", v4l2GetControl (videoIn, V4L2_CID_SATURATION)); } if (gain != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera gain to %d\n", gain); v4l2SetControl (videoIn, V4L2_CID_GAIN, gain); } else if (verbose >= 1) { fprintf (stderr, "Camera gain level is %d\n", v4l2GetControl (videoIn, V4L2_CID_GAIN)); } ref_time = time (NULL); while (run) { if (verbose >= 2) fprintf (stderr, "Grabbing frame\n"); if (uvcGrab (videoIn) < 0) { fprintf (stderr, "Error grabbing\n"); close_v4l2 (videoIn); free (videoIn); exit (1); } if ((difftime (time (NULL), ref_time) > delay) || delay == 0) { if (verbose >= 1) fprintf (stderr, "Saving image to: %s\n", outputfile); file = fopen (outputfile, "wb"); if (file != NULL) { switch (videoIn->formatIn) { case V4L2_PIX_FMT_YUYV: compress_yuyv_to_jpeg (videoIn, file, quality); break; default: fwrite (videoIn->tmpbuffer, videoIn->buf.bytesused + DHT_SIZE, 1, file); break; } fclose (file); videoIn->getPict = 0; } if (post_capture_command[0]) { if (verbose >= 1) fprintf (stderr, "Executing '%s %s'\n", post_capture_command[0], post_capture_command[1]); if (spawn (post_capture_command, post_capture_command_wait, verbose)) { fprintf (stderr, "Command exited with error\n"); close_v4l2 (videoIn); free (videoIn); exit (1); } } ref_time = time (NULL); } if (delay == 0) break; } close_v4l2 (videoIn); free (videoIn); return 0; }
void startVideoSrvr() { pthread_t videoSocketThread; /* alloc mameory for the videoIn struct & initialize */ videoIn = (struct vdIn *) calloc (1, sizeof (struct vdIn)); if (init_videoIn (videoIn, (char *) videodevice, width, height, format, grabmethod) < 0) exit (1); /* alloc memory for the control struct & video out array & initialize */ ctrlStruct ctrl, *pc; if ((ctrl.imgArray = malloc(3 * width * height)) < 0) // enough space for rgb exit(-1); ctrl.doCapture = 0; //Reset all camera controls if (verbose >= 1) fprintf (stderr, "Resetting camera settings\n"); v4l2ResetControl (videoIn, V4L2_CID_BRIGHTNESS); v4l2ResetControl (videoIn, V4L2_CID_CONTRAST); v4l2ResetControl (videoIn, V4L2_CID_SATURATION); v4l2ResetControl (videoIn, V4L2_CID_GAIN); //Setup Camera Parameters if (brightness != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera brightness to %d\n", brightness); v4l2SetControl (videoIn, V4L2_CID_BRIGHTNESS, brightness); } else if (verbose >= 1) { fprintf (stderr, "Camera brightness level is %d\n", v4l2GetControl (videoIn, V4L2_CID_BRIGHTNESS)); } if (contrast != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera contrast to %d\n", contrast); v4l2SetControl (videoIn, V4L2_CID_CONTRAST, contrast); } else if (verbose >= 1) { fprintf (stderr, "Camera contrast level is %d\n", v4l2GetControl (videoIn, V4L2_CID_CONTRAST)); } if (saturation != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera saturation to %d\n", saturation); v4l2SetControl (videoIn, V4L2_CID_SATURATION, saturation); } else if (verbose >= 1) { fprintf (stderr, "Camera saturation level is %d\n", v4l2GetControl (videoIn, V4L2_CID_SATURATION)); } if (gain != 0) { if (verbose >= 1) fprintf (stderr, "Setting camera gain to %d\n", gain); v4l2SetControl (videoIn, V4L2_CID_GAIN, gain); } else if (verbose >= 1) { fprintf (stderr, "Camera gain level is %d\n", v4l2GetControl (videoIn, V4L2_CID_GAIN)); } // wait for a video client to connect before proceeding fprintf (stderr, "waiting for video client connection on port %d\n", port); if ((ctrl.videoSocket = wait4client(port)) <= 0) { fprintf (stderr, "error connecting to client: %d\n", ctrl.videoSocket); exit(-1); } // start the thread that handles the video client requests pthread_create(&videoSocketThread, NULL, (void *)cmdHandler, (void *)&ctrl); while (run) { if (verbose >= 2) fprintf (stderr, "."); if (uvcGrab (videoIn) < 0) { fprintf (stderr, "Error grabbing\n"); close_v4l2 (videoIn); free (videoIn); exit (1); } if (ctrl.doCapture == 1) { if (verbose >= 1) { fprintf (stderr, "captured %d byte image at 0x%x %dx%d\n", videoIn->framesizeIn, videoIn->framebuffer, videoIn->width, videoIn->height); } else { fprintf (stderr, "."); } if (outputType == 0) yuyv2Y(videoIn, &ctrl); else yuyv2rgb(videoIn, &ctrl); if (verbose >=1) fprintf (stderr, "converted image to luminance in buffer at 0x%x\n", ctrl.imgArray); videoIn->getPict = 0; ctrl.doCapture = 0; } } close_v4l2 (videoIn); free (videoIn); return; }
/****************************************************************************** Description.: process commands, allows to set certain runtime configurations and settings like pan/tilt, colors, saturation etc. Input Value.: * cmd specifies the command, a complete list is maintained in the file "input.h" * value is used for commands that make use of a parameter. Return Value: depends in the command, for most cases 0 means no errors and -1 signals an error. This is just rule of thumb, not more! ******************************************************************************/ int input_cmd(in_cmd_type cmd, int value) { int res=0; static int pan=0, tilt=0, pan_tilt_valid=-1; static int focus=-1; const int one_degree = ONE_DEGREE; /* certain commands do not need the mutex */ if ( cmd != IN_CMD_RESET_PAN_TILT_NO_MUTEX ) pthread_mutex_lock( &controls_mutex ); switch (cmd) { case IN_CMD_HELLO: fprintf(stderr, "Hello from input plugin\n"); break; case IN_CMD_RESET: DBG("about to reset all image controls to defaults\n"); res = v4l2ResetControl(videoIn, V4L2_CID_BRIGHTNESS); res |= v4l2ResetControl(videoIn, V4L2_CID_CONTRAST); res |= v4l2ResetControl(videoIn, V4L2_CID_SATURATION); res |= v4l2ResetControl(videoIn, V4L2_CID_GAIN); if ( res != 0 ) res = -1; break; case IN_CMD_RESET_PAN_TILT: case IN_CMD_RESET_PAN_TILT_NO_MUTEX: DBG("about to set pan/tilt to default position\n"); if ( uvcPanTilt(videoIn->fd, 0, 0, 3) != 0 ) { res = -1; break; } pan_tilt_valid = 1; pan = tilt = 0; sleep(4); break; case IN_CMD_PAN_SET: DBG("set pan to %d degrees\n", value); /* in order to calculate absolute positions we must check for initialized values */ if ( pan_tilt_valid != 1 ) { if ( input_cmd(IN_CMD_RESET_PAN_TILT_NO_MUTEX, 0) == -1 ) { res = -1; break; } } /* limit pan-value to min and max, multiply it with constant "one_degree" */ value = MIN(MAX(value*one_degree, MIN_PAN), MAX_PAN); /* calculate the relative degrees to move to the desired absolute pan-value */ if( (res = value - pan) == 0 ) { /* do not move if this would mean to move by 0 degrees */ res = pan/one_degree; break; } /* move it */ pan = value; uvcPanTilt(videoIn->fd, res, 0, 0); res = pan/one_degree; DBG("pan: %d\n", pan); break; case IN_CMD_PAN_PLUS: DBG("pan +\n"); if ( pan_tilt_valid != 1 ) { if ( input_cmd(IN_CMD_RESET_PAN_TILT_NO_MUTEX, 0) == -1 ) { res = -1; break; } } if ( (MAX_PAN) >= (pan+MIN_RES) ) { pan += MIN_RES; uvcPanTilt(videoIn->fd, MIN_RES, 0, 0); } res = pan/one_degree; DBG("pan: %d\n", pan); break; case IN_CMD_PAN_MINUS: DBG("pan -\n"); if ( pan_tilt_valid != 1 ) { if ( input_cmd(IN_CMD_RESET_PAN_TILT_NO_MUTEX, 0) == -1 ) { res = -1; break; } } if ( (MIN_PAN) <= (pan-MIN_RES) ) { pan -= MIN_RES; uvcPanTilt(videoIn->fd, -MIN_RES, 0, 0); } res = pan/one_degree; DBG("pan: %d\n", pan); break; case IN_CMD_TILT_SET: DBG("set tilt to %d degrees\n", value); if ( pan_tilt_valid != 1 ) { if ( input_cmd(IN_CMD_RESET_PAN_TILT_NO_MUTEX, 0) == -1 ) { res = -1; break; } } /* limit pan-value to min and max, multiply it with constant "one_degree" */ value = MIN(MAX(value*one_degree, MIN_TILT), MAX_TILT); /* calculate the relative degrees to move to the desired absolute pan-value */ if( (res = value - tilt) == 0 ) { /* do not move if this would mean to move by 0 degrees */ res = tilt/one_degree; break; } /* move it */ tilt = value; uvcPanTilt(videoIn->fd, 0, res, 0); res = tilt/one_degree; DBG("tilt: %d\n", tilt); break; case IN_CMD_TILT_PLUS: DBG("tilt +\n"); if ( pan_tilt_valid != 1 ) { if ( input_cmd(IN_CMD_RESET_PAN_TILT_NO_MUTEX, 0) == -1 ) { res = -1; break; } } if ( (MAX_TILT) >= (tilt+MIN_RES) ) { tilt += MIN_RES; uvcPanTilt(videoIn->fd, 0, MIN_RES, 0); } res = tilt/one_degree; DBG("tilt: %d\n", tilt); break; case IN_CMD_TILT_MINUS: DBG("tilt -\n"); if ( pan_tilt_valid != 1 ) { if ( input_cmd(IN_CMD_RESET_PAN_TILT_NO_MUTEX, 0) == -1 ) { res = -1; break; } } if ( (MIN_TILT) <= (tilt-MIN_RES) ) { tilt -= MIN_RES; uvcPanTilt(videoIn->fd, 0, -MIN_RES, 0); } res = tilt/one_degree; DBG("tilt: %d\n", tilt); break; case IN_CMD_SATURATION_PLUS: DBG("saturation + (%d)\n", v4l2GetControl (videoIn, V4L2_CID_SATURATION)); res = v4l2UpControl(videoIn, V4L2_CID_SATURATION); break; case IN_CMD_SATURATION_MINUS: DBG("saturation - (%d)\n", v4l2GetControl (videoIn, V4L2_CID_SATURATION)); res = v4l2DownControl(videoIn, V4L2_CID_SATURATION); break; case IN_CMD_CONTRAST_PLUS: DBG("contrast + (%d)\n", v4l2GetControl (videoIn, V4L2_CID_CONTRAST)); res = v4l2UpControl(videoIn, V4L2_CID_CONTRAST); break; case IN_CMD_CONTRAST_MINUS: DBG("contrast - (%d)\n", v4l2GetControl (videoIn, V4L2_CID_CONTRAST)); res = v4l2DownControl(videoIn, V4L2_CID_CONTRAST); break; case IN_CMD_BRIGHTNESS_PLUS: DBG("brightness + (%d)\n", v4l2GetControl (videoIn, V4L2_CID_BRIGHTNESS)); res = v4l2UpControl(videoIn, V4L2_CID_BRIGHTNESS); break; case IN_CMD_BRIGHTNESS_MINUS: DBG("brightness - (%d)\n", v4l2GetControl (videoIn, V4L2_CID_BRIGHTNESS)); res = v4l2DownControl(videoIn, V4L2_CID_BRIGHTNESS); break; case IN_CMD_GAIN_PLUS: DBG("gain + (%d)\n", v4l2GetControl (videoIn, V4L2_CID_GAIN)); res = v4l2UpControl(videoIn, V4L2_CID_GAIN); break; case IN_CMD_GAIN_MINUS: DBG("gain - (%d)\n", v4l2GetControl (videoIn, V4L2_CID_GAIN)); res = v4l2DownControl(videoIn, V4L2_CID_GAIN); break; case IN_CMD_FOCUS_PLUS: DBG("focus + (%d)\n", focus); value=MIN(MAX(focus+10,0),255); if ( (res = v4l2SetControl(videoIn, V4L2_CID_FOCUS_LOGITECH, value)) == 0) { focus = value; } res = focus; break; case IN_CMD_FOCUS_MINUS: DBG("focus - (%d)\n", focus); value=MIN(MAX(focus-10,0),255); if ( (res = v4l2SetControl(videoIn, V4L2_CID_FOCUS_LOGITECH, value)) == 0) { focus = value; } res = focus; break; case IN_CMD_FOCUS_SET: value=MIN(MAX(value,0),255); DBG("set focus to %d\n", value); if ( (res = v4l2SetControl(videoIn, V4L2_CID_FOCUS_LOGITECH, value)) == 0) { focus = value; } res = focus; break; /* switch the webcam LED permanently on */ case IN_CMD_LED_ON: res = v4l2SetControl(videoIn, V4L2_CID_LED1_MODE_LOGITECH, 1); break; /* switch the webcam LED permanently off */ case IN_CMD_LED_OFF: res = v4l2SetControl(videoIn, V4L2_CID_LED1_MODE_LOGITECH, 0); break; /* switch the webcam LED on if streaming, off if not streaming */ case IN_CMD_LED_AUTO: res = v4l2SetControl(videoIn, V4L2_CID_LED1_MODE_LOGITECH, 3); break; /* let the webcam LED blink at a given hardcoded intervall */ case IN_CMD_LED_BLINK: res = v4l2SetControl(videoIn, V4L2_CID_LED1_MODE_LOGITECH, 2); res = v4l2SetControl(videoIn, V4L2_CID_LED1_FREQUENCY_LOGITECH, 255); break; default: DBG("nothing matched\n"); res = -1; } if ( cmd != IN_CMD_RESET_PAN_TILT_NO_MUTEX ) pthread_mutex_unlock( &controls_mutex ); return res; }