dynctrl.c
Go to the documentation of this file.
00001 /*******************************************************************************#
00002 #           guvcview              http://guvcview.berlios.de                    #
00003 #                                                                               #
00004 #           Paulo Assis <pj.assis@gmail.com>                                    #
00005 #                                                                               #
00006 # This program is free software; you can redistribute it and/or modify          #
00007 # it under the terms of the GNU General Public License as published by          #
00008 # the Free Software Foundation; either version 2 of the License, or             #
00009 # (at your option) any later version.                                           #
00010 #                                                                               #
00011 # This program is distributed in the hope that it will be useful,               #
00012 # but WITHOUT ANY WARRANTY; without even the implied warranty of                #
00013 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                 #
00014 # GNU General Public License for more details.                                  #
00015 #                                                                               #
00016 # You should have received a copy of the GNU General Public License             #
00017 # along with this program; if not, write to the Free Software                   #
00018 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA     #
00019 #                                                                               #
00020 ********************************************************************************/
00021 
00022 
00023 #include <sys/ioctl.h>
00024 #include <sys/time.h>
00025 #include <getopt.h>
00026 #include <errno.h>
00027 #include <pthread.h>
00028 #include <stdio.h>
00029 
00030 #include <linux/videodev2.h>
00031 
00032 #include "utils.h"
00033 #include "dynctrl.h"
00034 
00035 /* some Logitech webcams have pan/tilt/focus controls */
00036 #define LENGTH_OF_XU_CTR (6)
00037 #define LENGTH_OF_XU_MAP (10)
00038 
00039 static struct uvc_xu_control_info xu_ctrls[] = {
00040     {
00041         .entity   = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00042         .selector = XU_MOTORCONTROL_PANTILT_RELATIVE,
00043         .index    = 0,
00044         .size     = 4,
00045         .flags    = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE
00046     },
00047     {
00048         .entity   = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00049         .selector = XU_MOTORCONTROL_PANTILT_RESET,
00050         .index    = 1,
00051         .size     = 1,
00052         .flags    = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE
00053     },
00054     {
00055         .entity   = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00056         .selector = XU_MOTORCONTROL_FOCUS,
00057         .index    = 2,
00058         .size     = 6,
00059         .flags    = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE
00060     },
00061     {
00062         .entity   = UVC_GUID_LOGITECH_VIDEO_PIPE,
00063         .selector = XU_COLOR_PROCESSING_DISABLE,
00064         .index    = 4,
00065         .size     = 1,
00066         .flags    = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE
00067     },
00068     {
00069         .entity   = UVC_GUID_LOGITECH_VIDEO_PIPE,
00070         .selector = XU_RAW_DATA_BITS_PER_PIXEL,
00071         .index    = 7,
00072         .size     = 1,
00073         .flags    = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE
00074     },
00075     {
00076         .entity   = UVC_GUID_LOGITECH_USER_HW_CONTROL,
00077         .selector = XU_HW_CONTROL_LED1,
00078         .index    = 0,
00079         .size     = 3,
00080         .flags    = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE
00081     },
00082 
00083 };
00084 
00085 /* mapping for Pan/Tilt/Focus */
00086 static struct uvc_xu_control_mapping xu_mappings[] = {
00087     {
00088         .id        = V4L2_CID_PAN_RELATIVE,
00089         .name      = "Pan (relative)",
00090         .entity    = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00091         .selector  = XU_MOTORCONTROL_PANTILT_RELATIVE,
00092         .size      = 16,
00093         .offset    = 0,
00094         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00095         .data_type = UVC_CTRL_DATA_TYPE_SIGNED
00096     },
00097     {
00098         .id        = V4L2_CID_TILT_RELATIVE,
00099         .name      = "Tilt (relative)",
00100         .entity    = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00101         .selector  = XU_MOTORCONTROL_PANTILT_RELATIVE,
00102         .size      = 16,
00103         .offset    = 16,
00104         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00105         .data_type = UVC_CTRL_DATA_TYPE_SIGNED
00106     },
00107     {
00108         .id        = V4L2_CID_PAN_RESET,
00109         .name      = "Pan Reset",
00110         .entity    = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00111         .selector  = XU_MOTORCONTROL_PANTILT_RESET,
00112         .size      = 1,
00113         .offset    = 0,
00114         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00115         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00116     },
00117     {
00118         .id        = V4L2_CID_TILT_RESET,
00119         .name      = "Tilt Reset",
00120         .entity    = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00121         .selector  = XU_MOTORCONTROL_PANTILT_RESET,
00122         .size      = 1,
00123         .offset    = 1,
00124         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00125         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00126     },
00127     {
00128         .id        = V4L2_CID_PANTILT_RESET_LOGITECH,
00129         .name      = "Pan/tilt Reset",
00130         .entity    = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00131         .selector  = XU_MOTORCONTROL_PANTILT_RESET,
00132         .size      = 8,
00133         .offset    = 0,
00134         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00135         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00136     },
00137     {
00138         .id        = V4L2_CID_FOCUS_LOGITECH,
00139         .name      = "Focus (absolute)",
00140         .entity    = UVC_GUID_LOGITECH_MOTOR_CONTROL,
00141         .selector  = XU_MOTORCONTROL_FOCUS,
00142         .size      = 8,
00143         .offset    = 0,
00144         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00145         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00146     },
00147     {
00148         .id        = V4L2_CID_LED1_MODE_LOGITECH,
00149         .name      = "LED1 Mode",
00150         .entity    = UVC_GUID_LOGITECH_USER_HW_CONTROL,
00151         .selector  = XU_HW_CONTROL_LED1,
00152         .size      = 8,
00153         .offset    = 0,
00154         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00155         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00156     },
00157     {
00158         .id        = V4L2_CID_LED1_FREQUENCY_LOGITECH,
00159         .name      = "LED1 Frequency",
00160         .entity    = UVC_GUID_LOGITECH_USER_HW_CONTROL,
00161         .selector  = XU_HW_CONTROL_LED1,
00162         .size      = 8,
00163         .offset    = 16,
00164         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00165         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00166     },
00167     {
00168         .id        = V4L2_CID_DISABLE_PROCESSING_LOGITECH,
00169         .name      = "Disable video processing",
00170         .entity    = UVC_GUID_LOGITECH_VIDEO_PIPE,
00171         .selector  = XU_COLOR_PROCESSING_DISABLE,
00172         .size      = 8,
00173         .offset    = 0,
00174         .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN,
00175         .data_type = UVC_CTRL_DATA_TYPE_BOOLEAN
00176     },
00177     {
00178         .id        = V4L2_CID_RAW_BITS_PER_PIXEL_LOGITECH,
00179         .name      = "Raw bits per pixel",
00180         .entity    = UVC_GUID_LOGITECH_VIDEO_PIPE,
00181         .selector  = XU_RAW_DATA_BITS_PER_PIXEL,
00182         .size      = 8,
00183         .offset    = 0,
00184         .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
00185         .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED
00186     },
00187 
00188 };
00189 
00190 int initDynCtrls(int fd)
00191 {
00192     int i = 0;
00193     int err = 0;
00194     /* try to add all controls listed above */
00195     for(i = 0; i < LENGTH_OF_XU_CTR; i++) {
00196         fprintf(stderr, "Adding control for %s\n", xu_mappings[i].name);
00197         if((err = xioctl(fd, UVCIOC_CTRL_ADD, &xu_ctrls[i])) < 0) {
00198             if(errno != EEXIST)
00199                 perror("UVCIOC_CTRL_ADD - Error");
00200             else
00201                 perror("Control exists");
00202         }
00203     }
00204     /* after adding the controls, add the mapping now */
00205     for(i = 0; i < LENGTH_OF_XU_MAP; i++) {
00206         fprintf(stderr, "mapping control for %s\n", xu_mappings[i].name);
00207         if((err = xioctl(fd, UVCIOC_CTRL_MAP, &xu_mappings[i])) < 0) {
00208             if(errno != EEXIST)
00209                 perror("UVCIOC_CTRL_MAP - Error");
00210             else
00211                 perror("Mapping exists");
00212         }
00213     }
00214     return 0;
00215 }
00216 
00217 /*
00218 SRC: https://lists.berlios.de/pipermail/linux-uvc-devel/2007-July/001888.html
00219 
00220 - dev: the device file descriptor
00221 - pan: pan angle in 1/64th of degree
00222 - tilt: tilt angle in 1/64th of degree
00223 - reset: set to 1 to reset pan/tilt to the device origin, set to 0 otherwise
00224 */
00225 int uvcPanTilt(int dev, int pan, int tilt, int reset) {
00226   struct v4l2_ext_control xctrls[2];
00227   struct v4l2_ext_controls ctrls;
00228 
00229   if (reset) {
00230     xctrls[0].id = V4L2_CID_PANTILT_RESET_LOGITECH;
00231     xctrls[0].value = 3;
00232 
00233     ctrls.count = 1;
00234     ctrls.controls = xctrls;
00235   } else {
00236     xctrls[0].id = V4L2_CID_PAN_RELATIVE;
00237     xctrls[0].value = pan;
00238     xctrls[1].id = V4L2_CID_TILT_RELATIVE;
00239     xctrls[1].value = -tilt;
00240 
00241     ctrls.count = 2;
00242     ctrls.controls = xctrls;
00243   }
00244 
00245   if ( ioctl(dev, VIDIOC_S_EXT_CTRLS, &ctrls) < 0 ) {
00246     // DBG("Error in uvcPanTilt");
00247     return -1;
00248   }
00249 
00250   return 0;
00251 }


corobot_pantilt
Author(s): Morgan Cormier/mcormier@coroware.com
autogenerated on Tue Jan 7 2014 11:39:02