static int eventThread(void *data) { struct pt_data *gdata = (struct pt_data *) data; struct v4l2_control control; SDL_Surface *pscreen = *gdata->ptscreen; struct vdIn *videoIn = gdata->ptvideoIn; SDL_Event *sdlevent = gdata->ptsdlevent; SDL_Rect *drect = gdata->drect; SDL_mutex *affmutex = gdata->affmutex; unsigned char frmrate; int x, y; int mouseon = 0; int value = 0; int len = 0; short incpantilt = INCPANTILT; int boucle = 0; action_gui curr_action = A_VIDEO; while (videoIn->signalquit) { SDL_LockMutex(affmutex); frmrate = gdata->frmrate; while (SDL_PollEvent(sdlevent)) { //scan the event queue switch (sdlevent->type) { case SDL_KEYUP: case SDL_MOUSEBUTTONUP: mouseon = 0; incpantilt = INCPANTILT; boucle = 0; break; case SDL_MOUSEBUTTONDOWN: mouseon = 1; case SDL_MOUSEMOTION: SDL_GetMouseState(&x, &y); curr_action = GUI_whichbutton(x, y, pscreen, videoIn); break; case SDL_VIDEORESIZE: pscreen = SDL_SetVideoMode(sdlevent->resize.w, sdlevent->resize.h, 0, SDL_VIDEO_Flags); drect->w = sdlevent->resize.w; drect->h = sdlevent->resize.h; break; case SDL_KEYDOWN: curr_action = GUI_keytoaction(sdlevent->key.keysym.sym); if (curr_action != A_VIDEO) mouseon = 1; break; case SDL_QUIT: printf("\nStop asked\n"); videoIn->signalquit = 0; break; } } //end if poll SDL_UnlockMutex(affmutex); /* traiter les actions */ value = 0; if (mouseon){ boucle++; switch (curr_action) { case A_BRIGHTNESS_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_BRIGHTNESS)) < 0) printf("Set Brightness up error\n"); break; case A_CONTRAST_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_CONTRAST)) < 0) printf("Set Contrast up error \n"); break; case A_SATURATION_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_SATURATION)) < 0) printf("Set Saturation up error\n"); break; case A_GAIN_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_GAIN)) < 0) printf("Set Gain up error\n"); break; case A_SHARPNESS_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_SHARPNESS)) < 0) printf("Set Sharpness up error\n"); break; case A_GAMMA_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_GAMMA)) < 0) printf("Set Gamma up error\n"); break; case A_PAN_UP: if ((value =v4L2UpDownPan(videoIn, -incpantilt)) < 0) printf("Set Pan up error\n"); break; case A_TILT_UP: if ((value =v4L2UpDownTilt(videoIn, -incpantilt)) < 0) printf("Set Tilt up error\n"); break; case A_PAN_RESET: if (v4l2ResetPanTilt(videoIn,1) < 0) printf("reset pantilt error\n"); break; case A_SCREENSHOT: SDL_Delay(200); videoIn->getPict = 1; value = 1; break; case A_RESET: if (v4l2ResetControl(videoIn, V4L2_CID_BRIGHTNESS) < 0) printf("reset Brightness error\n"); if (v4l2ResetControl(videoIn, V4L2_CID_SATURATION) < 0) printf("reset Saturation error\n"); if (v4l2ResetControl(videoIn, V4L2_CID_CONTRAST) < 0) printf("reset Contrast error\n"); if (v4l2ResetControl(videoIn, V4L2_CID_HUE) < 0) printf("reset Hue error\n"); if (v4l2ResetControl(videoIn, V4L2_CID_SHARPNESS) < 0) printf("reset Sharpness error\n"); if (v4l2ResetControl(videoIn, V4L2_CID_GAMMA) < 0) printf("reset Gamma error\n"); if (v4l2ResetControl(videoIn, V4L2_CID_GAIN) < 0) printf("reset Gain error\n"); if (v4l2ResetPanTilt(videoIn,3) < 0) printf("reset pantilt error\n"); break; case A_BRIGHTNESS_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_BRIGHTNESS)) < 0) printf("Set Brightness down error\n"); break; case A_CONTRAST_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_CONTRAST)) < 0) printf("Set Contrast down error\n"); break; case A_SATURATION_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_SATURATION)) < 0) printf("Set Saturation down error\n"); break; case A_GAIN_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_GAIN)) < 0) printf("Set Gain down error\n"); break; case A_SHARPNESS_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_SHARPNESS)) < 0) printf("Set Sharpness down error\n"); break; case A_GAMMA_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_GAMMA)) < 0) printf("Set Gamma down error\n"); break; case A_PAN_DOWN: if ((value =v4L2UpDownPan(videoIn, incpantilt)) < 0) printf("Set Pan down error\n"); break; case A_TILT_DOWN: if ((value =v4L2UpDownTilt(videoIn,incpantilt)) < 0) printf("Set Tilt down error\n"); break; case A_TILT_RESET: if (v4l2ResetPanTilt(videoIn,2) < 0) printf("reset pantilt error\n"); break; case A_RECORD_TOGGLE: SDL_Delay(200); videoIn->toggleAvi = !videoIn->toggleAvi; value = videoIn->toggleAvi; if ( value == 1 ) { printf("avi recording started\n"); videoIn->recordstart=SDL_GetTicks(); } else { int dur=SDL_GetTicks()-videoIn->recordstart; printf("\navi recording stopped (%ds)\n",dur/1000); videoIn->recordtime+=dur; } break; case A_SWITCH_LIGHTFREQFILT: if ((value =v4l2GetControl(videoIn,V4L2_CID_POWER_LINE_FREQUENCY)) < 0) printf("Get value of light frequency filter error\n"); if(value < 2) // round switch 50->60->NoFliker->. value++; // \_______________; else value=0; if(value == 0) printf("Current light frequency filter: 50Hz\n"); else if(value == 1) printf("Current light frequency filter: 60Hz\n"); else if(value == 2) printf("Current light frequency filter: NoFliker\n"); if ((value =v4l2SetLightFrequencyFilter(videoIn,value)) < 0) printf("Switch light frequency filter error\n"); break; case A_QUIT: videoIn->signalquit = 0; break; case A_VIDEO: break; case A_CAPTURE_FRAME: value = 1; videoIn->rawFrameCapture = 1; break; case A_CAPTURE_FRAMESTREAM: value = 1; if (!videoIn->rawFrameCapture) { videoIn->rawFrameCapture = 2; videoIn->rfsBytesWritten = 0; videoIn->rfsFramesWritten = 0; printf("Starting raw frame stream capturing ...\n"); } else if(videoIn->framesWritten >= 5) { videoIn->rawFrameCapture = 0; printf("Stopped raw frame stream capturing. %u bytes written for %u frames.\n", videoIn->rfsBytesWritten, videoIn->rfsFramesWritten); } break; case A_CAPTURE_STREAM: value = 1; if (videoIn->captureFile == NULL) { videoIn->captureFile = fopen("stream.raw", "wb"); if(videoIn->captureFile == NULL) { perror("Unable to open file for raw stream capturing"); } else { printf("Starting raw stream capturing to stream.raw ...\n"); } videoIn->bytesWritten = 0; videoIn->framesWritten = 0; } else if(videoIn->framesWritten >= 5) { fclose(videoIn->captureFile); printf("Stopped raw stream capturing to stream.raw. %u bytes written for %u frames.\n", videoIn->bytesWritten, videoIn->framesWritten); videoIn->captureFile = NULL; } break; case A_EXPOSURE_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_EXPOSURE_ABSOLUTE)) < 0) printf("Set Absolute Exposure up error\n"); break; case A_EXPOSURE_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_EXPOSURE_ABSOLUTE)) < 0) printf("Set Absolute Exposure down error\n"); break; case A_EXPOSURE_ON: control.id =V4L2_CID_EXPOSURE_AUTO; control.value =1; if ((value = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0) printf("Set Auto Exposure on error\n"); else printf("Auto Exposure set to %d \n", control.value); break; case A_EXPOSURE_OFF: control.id =V4L2_CID_EXPOSURE_AUTO; control.value =8; if ((value = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0) printf("Set Auto Exposure off error\n"); else printf("Auto Exposure set to %d \n", control.value); break; case A_BALANCE_UP: if ((value = v4l2UpControl(videoIn, V4L2_CID_WHITE_BALANCE_TEMPERATURE)) < 0) printf("Set Balance Temperature up error\n"); break; case A_BALANCE_DOWN: if ((value = v4l2DownControl(videoIn, V4L2_CID_WHITE_BALANCE_TEMPERATURE)) < 0) printf("Set Balance Temperature down error\n"); break; case A_BALANCE_ON: control.id =V4L2_CID_WHITE_BALANCE_TEMPERATURE_AUTO; control.value =1; if ((value = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0) printf("Set Auto Balance on error\n"); else printf("Auto Balance set to %d \n", control.value); break; case A_BALANCE_OFF: control.id =V4L2_CID_WHITE_BALANCE_TEMPERATURE_AUTO; control.value =0; if ((value = ioctl(videoIn->fd, VIDIOC_S_CTRL, &control)) < 0) printf("Set Auto Balance off error\n"); else printf("Auto Balance set to %d \n", control.value); break; case A_SAVE: printf("Save controls \n"); save_controls(videoIn->fd); break; case A_LOAD: printf("load controls \n"); load_controls(videoIn->fd); break; default: break; } if(!(boucle%10)) // smooth pan tilt method if(incpantilt < (10*INCPANTILT)) incpantilt += (INCPANTILT/4); if(value){ len = strlen(title_act[curr_action].title)+8; snprintf(videoIn->status, len,"%s %06d",title_act[curr_action].title,value); } } else { // mouseon len = strlen(title_act[curr_action].title)+9; snprintf(videoIn->status, len,"%s, %02d Fps",title_act[curr_action].title, frmrate); } SDL_Delay(50); //printf("fp/s %d \n",frmrate); } //end main loop /* Close the stream capture file */ if (videoIn->captureFile) { fclose(videoIn->captureFile); printf("Stopped raw stream capturing to stream.raw. %u bytes written for %u frames.\n", videoIn->bytesWritten, videoIn->framesWritten); } /* Display stats for raw frame stream capturing */ if (videoIn->rawFrameCapture == 2) { printf("Stopped raw frame stream capturing. %u bytes written for %u frames.\n", videoIn->rfsBytesWritten, videoIn->rfsFramesWritten); } }
/****************************************************************************** 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; }