| 1 | /*
 | 
|---|
| 2 |     Phlips webcam driver for V4L 1
 | 
|---|
| 3 |     Copyright (C) 2005 by Jasem Mutlaq <mutlaqja@ikarustech.com>
 | 
|---|
| 4 | 
 | 
|---|
| 5 |     This library is free software; you can redistribute it and/or
 | 
|---|
| 6 |     modify it under the terms of the GNU Lesser General Public
 | 
|---|
| 7 |     License as published by the Free Software Foundation; either
 | 
|---|
| 8 |     version 2.1 of the License, or (at your option) any later version.
 | 
|---|
| 9 | 
 | 
|---|
| 10 |     This library is distributed in the hope that it will be useful,
 | 
|---|
| 11 |     but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 12 |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
|---|
| 13 |     Lesser General Public License for more details.
 | 
|---|
| 14 | 
 | 
|---|
| 15 |     You should have received a copy of the GNU Lesser General Public
 | 
|---|
| 16 |     License along with this library; if not, write to the Free Software
 | 
|---|
| 17 |     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 | 
|---|
| 18 | 
 | 
|---|
| 19 | */
 | 
|---|
| 20 | 
 | 
|---|
| 21 | #include <iostream>
 | 
|---|
| 22 | 
 | 
|---|
| 23 | #include <sys/ioctl.h>
 | 
|---|
| 24 | #include <sys/types.h>
 | 
|---|
| 25 | #include <sys/stat.h>
 | 
|---|
| 26 | #include <fcntl.h>
 | 
|---|
| 27 | #include <unistd.h>
 | 
|---|
| 28 | #include <stdio.h>
 | 
|---|
| 29 | #include <errno.h>
 | 
|---|
| 30 | #include <sys/mman.h>
 | 
|---|
| 31 | #include <string.h>
 | 
|---|
| 32 | 
 | 
|---|
| 33 | #include "ccvt.h"
 | 
|---|
| 34 | #include "pwc-ioctl.h"
 | 
|---|
| 35 | #include "v4l1_pwc.h"
 | 
|---|
| 36 | #include "../eventloop.h"
 | 
|---|
| 37 | 
 | 
|---|
| 38 | #define ERRMSG_SIZ      1024
 | 
|---|
| 39 | 
 | 
|---|
| 40 | extern int errno;
 | 
|---|
| 41 | using namespace std;
 | 
|---|
| 42 | 
 | 
|---|
| 43 | V4L1_PWC::V4L1_PWC()
 | 
|---|
| 44 | {
 | 
|---|
| 45 |    frameRate=15;
 | 
|---|
| 46 |    fd=-1;
 | 
|---|
| 47 |    streamActive = true;
 | 
|---|
| 48 | 
 | 
|---|
| 49 |    YBuf       = NULL;
 | 
|---|
| 50 |    UBuf       = NULL;
 | 
|---|
| 51 |    VBuf       = NULL;
 | 
|---|
| 52 |    colorBuffer= NULL;
 | 
|---|
| 53 |    buffer_start=NULL;
 | 
|---|
| 54 | }
 | 
|---|
| 55 | 
 | 
|---|
| 56 | V4L1_PWC::~V4L1_PWC()
 | 
|---|
| 57 | {
 | 
|---|
| 58 | 
 | 
|---|
| 59 | } 
 | 
|---|
| 60 | 
 | 
|---|
| 61 | int V4L1_PWC::connectCam(const char * devpath, char *errmsg)
 | 
|---|
| 62 | {
 | 
|---|
| 63 |    options= (ioNoBlock|ioUseSelect|haveBrightness|haveContrast|haveColor);
 | 
|---|
| 64 |    struct pwc_probe probe;
 | 
|---|
| 65 |    bool IsPhilips = false;
 | 
|---|
| 66 |    frameRate=15;
 | 
|---|
| 67 |    fd=-1;
 | 
|---|
| 68 |    streamActive = true;
 | 
|---|
| 69 |    buffer_start=NULL;
 | 
|---|
| 70 |    
 | 
|---|
| 71 |    if (-1 == (fd=open(devpath,
 | 
|---|
| 72 |                            O_RDONLY | ((options & ioNoBlock) ? O_NONBLOCK : 0)))) {
 | 
|---|
| 73 |       
 | 
|---|
| 74 |       strncpy(errmsg, strerror(errno), 1024);
 | 
|---|
| 75 |       cerr << strerror(errno);
 | 
|---|
| 76 |       return -1;
 | 
|---|
| 77 |    } 
 | 
|---|
| 78 |   
 | 
|---|
| 79 |    cerr << "Device opened" << endl;
 | 
|---|
| 80 |    
 | 
|---|
| 81 |    if (fd != -1) {
 | 
|---|
| 82 |       if (-1 == ioctl(fd,VIDIOCGCAP,&capability)) {
 | 
|---|
| 83 |          cerr << "Error: ioctl (VIDIOCGCAP)" << endl;
 | 
|---|
| 84 |          strncpy(errmsg, "ioctl (VIDIOCGCAP)", 1024);
 | 
|---|
| 85 |          return -1;
 | 
|---|
| 86 |       }
 | 
|---|
| 87 |       if (-1 == ioctl (fd, VIDIOCGWIN, &window)) {
 | 
|---|
| 88 |          cerr << "Error: ioctl (VIDIOCGWIN)" << endl;
 | 
|---|
| 89 |          strncpy(errmsg, "ioctl (VIDIOCGWIN)", 1024);
 | 
|---|
| 90 |          return -1;
 | 
|---|
| 91 |       }
 | 
|---|
| 92 |       if (-1 == ioctl (fd, VIDIOCGPICT, &picture_format)) {
 | 
|---|
| 93 |          cerr << "Error: ioctl (VIDIOCGPICT)" << endl;
 | 
|---|
| 94 |          strncpy(errmsg, "ioctl (VIDIOCGPICT)", 1024);
 | 
|---|
| 95 |          return -1;
 | 
|---|
| 96 |       }
 | 
|---|
| 97 |       init(0);
 | 
|---|
| 98 |    }
 | 
|---|
| 99 |    
 | 
|---|
| 100 |   // Check to see if it's really a philips webcam       
 | 
|---|
| 101 |   if (ioctl(fd, VIDIOCPWCPROBE, &probe) == 0) 
 | 
|---|
| 102 |   {
 | 
|---|
| 103 |             if (!strcmp(capability.name,probe.name))
 | 
|---|
| 104 |             {
 | 
|---|
| 105 |                IsPhilips = true;
 | 
|---|
| 106 |                type_=probe.type;
 | 
|---|
| 107 |             }
 | 
|---|
| 108 |  }
 | 
|---|
| 109 |          
 | 
|---|
| 110 |   if (IsPhilips)
 | 
|---|
| 111 |       cerr << "Philips webcam type " << type_ << " detected" << endl;
 | 
|---|
| 112 |   else
 | 
|---|
| 113 |   {
 | 
|---|
| 114 |    strncpy(errmsg, "No Philips webcam detected.", 1024);
 | 
|---|
| 115 |    return -1;
 | 
|---|
| 116 |   }
 | 
|---|
| 117 |     
 | 
|---|
| 118 |    cerr << "initial size w:" << window.width << " -- h: " << window.height << endl;
 | 
|---|
| 119 |    
 | 
|---|
| 120 |    
 | 
|---|
| 121 |    mmapInit();
 | 
|---|
| 122 |    
 | 
|---|
| 123 |    setWhiteBalanceMode(PWC_WB_AUTO, errmsg);
 | 
|---|
| 124 |    multiplicateur_=1;
 | 
|---|
| 125 |    skippedFrame_=0;
 | 
|---|
| 126 |    lastGain_=getGain();
 | 
|---|
| 127 | 
 | 
|---|
| 128 |    cerr << "All successful, returning\n";
 | 
|---|
| 129 |    return fd;
 | 
|---|
| 130 | }
 | 
|---|
| 131 | 
 | 
|---|
| 132 | void V4L1_PWC::checkSize(int & x, int & y) 
 | 
|---|
| 133 | {
 | 
|---|
| 134 |  if (x>=capability.maxwidth && y >= capability.maxheight)
 | 
|---|
| 135 |    {
 | 
|---|
| 136 |       x=capability.maxwidth;
 | 
|---|
| 137 |       y=capability.maxheight;
 | 
|---|
| 138 |    } else if (x>=352 && y >=288 && type_<700) {
 | 
|---|
| 139 |       x=352;y=288;
 | 
|---|
| 140 |    } else if (x>=320 && y >= 240) {
 | 
|---|
| 141 |       x=320;y=240;
 | 
|---|
| 142 |    } else if (x>=176 && y >=144 && type_<700 ) {
 | 
|---|
| 143 |       x=176;y=144;
 | 
|---|
| 144 |    } else if (x>=160 && y >=120 ) {
 | 
|---|
| 145 |       x=160;y=120;
 | 
|---|
| 146 |    } else {
 | 
|---|
| 147 |       x=capability.minwidth;
 | 
|---|
| 148 |       y=capability.minheight;
 | 
|---|
| 149 |    }
 | 
|---|
| 150 | }
 | 
|---|
| 151 | 
 | 
|---|
| 152 | bool V4L1_PWC::setSize(int x, int y) 
 | 
|---|
| 153 | {
 | 
|---|
| 154 | 
 | 
|---|
| 155 |    int oldX, oldY;
 | 
|---|
| 156 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 157 |    checkSize(x,y);
 | 
|---|
| 158 |    
 | 
|---|
| 159 |    oldX = window.width;
 | 
|---|
| 160 |    oldY = window.height;
 | 
|---|
| 161 |    
 | 
|---|
| 162 |    window.width=x;
 | 
|---|
| 163 |    window.height=y;
 | 
|---|
| 164 |    
 | 
|---|
| 165 |    if (ioctl (fd, VIDIOCSWIN, &window))
 | 
|---|
| 166 |    {
 | 
|---|
| 167 |        snprintf(msg, ERRMSG_SIZ, "ioctl(VIDIOCSWIN) %s", strerror(errno));
 | 
|---|
| 168 |        cerr << msg << endl;
 | 
|---|
| 169 |        window.width=oldX;
 | 
|---|
| 170 |        window.height=oldY;
 | 
|---|
| 171 |        return false;
 | 
|---|
| 172 |    }
 | 
|---|
| 173 |    ioctl (fd, VIDIOCGWIN, &window);
 | 
|---|
| 174 | 
 | 
|---|
| 175 |    cerr << "New size is x=" << window.width << " " << "y=" << window.height <<endl;
 | 
|---|
| 176 |    
 | 
|---|
| 177 |    allocBuffers();
 | 
|---|
| 178 |    
 | 
|---|
| 179 |    return true;
 | 
|---|
| 180 | }
 | 
|---|
| 181 | 
 | 
|---|
| 182 | int V4L1_PWC::saveSettings(char *errmsg)
 | 
|---|
| 183 | {
 | 
|---|
| 184 |    if (ioctl(fd, VIDIOCPWCSUSER)==-1)
 | 
|---|
| 185 |     {
 | 
|---|
| 186 |       snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSUSER %s", strerror(errno));
 | 
|---|
| 187 |       return -1;
 | 
|---|
| 188 |    }
 | 
|---|
| 189 |    
 | 
|---|
| 190 |    return 0;
 | 
|---|
| 191 | }
 | 
|---|
| 192 | 
 | 
|---|
| 193 | void V4L1_PWC::restoreSettings()
 | 
|---|
| 194 |  {
 | 
|---|
| 195 |    ioctl(fd, VIDIOCPWCRUSER);
 | 
|---|
| 196 |    getPictureSettings();
 | 
|---|
| 197 | }
 | 
|---|
| 198 | 
 | 
|---|
| 199 | void V4L1_PWC::restoreFactorySettings()
 | 
|---|
| 200 | {
 | 
|---|
| 201 |    ioctl(fd, VIDIOCPWCFACTORY);
 | 
|---|
| 202 |    getPictureSettings();
 | 
|---|
| 203 | }
 | 
|---|
| 204 | 
 | 
|---|
| 205 | int V4L1_PWC::setGain(int val, char *errmsg)
 | 
|---|
| 206 |  {
 | 
|---|
| 207 |    if(-1==ioctl(fd, VIDIOCPWCSAGC, &val))
 | 
|---|
| 208 |    {
 | 
|---|
| 209 |       snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSAGC %s", strerror(errno));
 | 
|---|
| 210 |       return -1;
 | 
|---|
| 211 |    }
 | 
|---|
| 212 |    else lastGain_=val;
 | 
|---|
| 213 |    
 | 
|---|
| 214 |    cerr << "setGain "<<val<<endl;
 | 
|---|
| 215 |    
 | 
|---|
| 216 |    return lastGain_;
 | 
|---|
| 217 | }
 | 
|---|
| 218 | 
 | 
|---|
| 219 | int V4L1_PWC::getGain()
 | 
|---|
| 220 | {
 | 
|---|
| 221 |    int gain;
 | 
|---|
| 222 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 223 |    static int cpt=0;
 | 
|---|
| 224 |    if ((cpt%4)==0)
 | 
|---|
| 225 |    {
 | 
|---|
| 226 |       if (-1==ioctl(fd, VIDIOCPWCGAGC, &gain))
 | 
|---|
| 227 |       {
 | 
|---|
| 228 |          //perror("VIDIOCPWCGAGC");
 | 
|---|
| 229 |          snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGAGC %s", strerror(errno));
 | 
|---|
| 230 |          cerr << msg << endl;
 | 
|---|
| 231 |          gain=lastGain_;
 | 
|---|
| 232 |       } else
 | 
|---|
| 233 |       {
 | 
|---|
| 234 |          ++cpt;
 | 
|---|
| 235 |          lastGain_=gain;
 | 
|---|
| 236 |       }
 | 
|---|
| 237 |    } else
 | 
|---|
| 238 |    {
 | 
|---|
| 239 |       ++cpt;
 | 
|---|
| 240 |       gain=lastGain_; 
 | 
|---|
| 241 |    }
 | 
|---|
| 242 |    //cerr << "get gain "<<gain<<endl;
 | 
|---|
| 243 |    if (gain < 0) gain*=-1;
 | 
|---|
| 244 |    return gain;
 | 
|---|
| 245 | }
 | 
|---|
| 246 | 
 | 
|---|
| 247 | int V4L1_PWC::setExposure(int val, char *errmsg)
 | 
|---|
| 248 |  {
 | 
|---|
| 249 |    //cout << "set exposure "<<val<<"\n";
 | 
|---|
| 250 |    
 | 
|---|
| 251 |    if (-1==ioctl(fd, VIDIOCPWCSSHUTTER, &val))
 | 
|---|
| 252 |    {
 | 
|---|
| 253 |      snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSSHUTTER %s", strerror(errno));
 | 
|---|
| 254 |      return -1;
 | 
|---|
| 255 |   }
 | 
|---|
| 256 |   
 | 
|---|
| 257 |   return 0;
 | 
|---|
| 258 | }
 | 
|---|
| 259 | 
 | 
|---|
| 260 | void V4L1_PWC::setCompression(int val)
 | 
|---|
| 261 | {
 | 
|---|
| 262 |    ioctl(fd, VIDIOCPWCSCQUAL, &val); 
 | 
|---|
| 263 | }
 | 
|---|
| 264 | 
 | 
|---|
| 265 | int V4L1_PWC::getCompression()
 | 
|---|
| 266 | {
 | 
|---|
| 267 |    int gain;
 | 
|---|
| 268 |    ioctl(fd, VIDIOCPWCGCQUAL , &gain);
 | 
|---|
| 269 |    if (gain < 0) gain*=-1;
 | 
|---|
| 270 |    return gain;
 | 
|---|
| 271 | }
 | 
|---|
| 272 | 
 | 
|---|
| 273 | int V4L1_PWC::setNoiseRemoval(int val, char *errmsg)
 | 
|---|
| 274 | {
 | 
|---|
| 275 |    if (-1 == ioctl(fd, VIDIOCPWCSDYNNOISE, &val))
 | 
|---|
| 276 |    {
 | 
|---|
| 277 |        snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCGDYNNOISE %s", strerror(errno));
 | 
|---|
| 278 |        return -1;
 | 
|---|
| 279 |    }
 | 
|---|
| 280 |    
 | 
|---|
| 281 |    return 0;
 | 
|---|
| 282 | }
 | 
|---|
| 283 | 
 | 
|---|
| 284 | int V4L1_PWC::getNoiseRemoval()
 | 
|---|
| 285 | {
 | 
|---|
| 286 |    int gain;
 | 
|---|
| 287 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 288 |    
 | 
|---|
| 289 |    if (-1 == ioctl(fd, VIDIOCPWCGDYNNOISE , &gain)) 
 | 
|---|
| 290 |    {
 | 
|---|
| 291 |          snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGDYNNOISE %s", strerror(errno));
 | 
|---|
| 292 |          cerr << msg << endl;
 | 
|---|
| 293 |    }
 | 
|---|
| 294 |       
 | 
|---|
| 295 |    cout <<"get noise = "<<gain<<endl;
 | 
|---|
| 296 |    return gain;
 | 
|---|
| 297 | }
 | 
|---|
| 298 | 
 | 
|---|
| 299 | int V4L1_PWC::setSharpness(int val, char *errmsg)
 | 
|---|
| 300 |  {
 | 
|---|
| 301 |    if (-1 == ioctl(fd, VIDIOCPWCSCONTOUR, &val))
 | 
|---|
| 302 |    {
 | 
|---|
| 303 |        snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSCONTOUR %s", strerror(errno));
 | 
|---|
| 304 |        return -1;
 | 
|---|
| 305 |   }
 | 
|---|
| 306 |   
 | 
|---|
| 307 |   return 0;
 | 
|---|
| 308 | }
 | 
|---|
| 309 | 
 | 
|---|
| 310 | int V4L1_PWC::getSharpness()
 | 
|---|
| 311 | {
 | 
|---|
| 312 |    int gain;
 | 
|---|
| 313 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 314 |    
 | 
|---|
| 315 |    if (-1 == ioctl(fd, VIDIOCPWCGCONTOUR, &gain)) 
 | 
|---|
| 316 |    {
 | 
|---|
| 317 |       snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGCONTOUR %s", strerror(errno));
 | 
|---|
| 318 |       cerr << msg << endl;
 | 
|---|
| 319 |   }
 | 
|---|
| 320 |    
 | 
|---|
| 321 |    cout <<"get sharpness = "<<gain<<endl;
 | 
|---|
| 322 |    return gain;
 | 
|---|
| 323 | }
 | 
|---|
| 324 | 
 | 
|---|
| 325 | int V4L1_PWC::setBackLight(bool val, char *errmsg)
 | 
|---|
| 326 | {
 | 
|---|
| 327 |    static int on=1;
 | 
|---|
| 328 |    static int off=0;
 | 
|---|
| 329 |    if (-1 == ioctl(fd,VIDIOCPWCSBACKLIGHT, &  val?&on:&off))
 | 
|---|
| 330 |    {
 | 
|---|
| 331 |         snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSBACKLIGHT %s", strerror(errno));
 | 
|---|
| 332 |         return -1;
 | 
|---|
| 333 |    }
 | 
|---|
| 334 |    
 | 
|---|
| 335 |    return 0;
 | 
|---|
| 336 | }
 | 
|---|
| 337 | 
 | 
|---|
| 338 | bool V4L1_PWC::getBackLight()
 | 
|---|
| 339 | {
 | 
|---|
| 340 |    int val;
 | 
|---|
| 341 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 342 |    
 | 
|---|
| 343 |    if (-1 == ioctl(fd,VIDIOCPWCGBACKLIGHT, & val)) 
 | 
|---|
| 344 |    {
 | 
|---|
| 345 |       snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCSBACKLIGHT %s", strerror(errno));
 | 
|---|
| 346 |       cerr << msg << endl;
 | 
|---|
| 347 |    }
 | 
|---|
| 348 | 
 | 
|---|
| 349 |    return val !=0;
 | 
|---|
| 350 | }
 | 
|---|
| 351 | 
 | 
|---|
| 352 | int V4L1_PWC::setFlicker(bool val, char *errmsg)
 | 
|---|
| 353 | {
 | 
|---|
| 354 |    static int on=1;
 | 
|---|
| 355 |    static int off=0;
 | 
|---|
| 356 |    if (-1 == ioctl(fd,VIDIOCPWCSFLICKER, val?&on:&off))
 | 
|---|
| 357 |    {
 | 
|---|
| 358 |       snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSFLICKER %s", strerror(errno));
 | 
|---|
| 359 |       return -1;
 | 
|---|
| 360 |    }
 | 
|---|
| 361 |    
 | 
|---|
| 362 |    return 0;
 | 
|---|
| 363 |    
 | 
|---|
| 364 | }
 | 
|---|
| 365 | 
 | 
|---|
| 366 | bool V4L1_PWC::getFlicker() 
 | 
|---|
| 367 | {
 | 
|---|
| 368 |    int val;
 | 
|---|
| 369 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 370 |    
 | 
|---|
| 371 |    if (-1 == ioctl(fd,VIDIOCPWCGFLICKER, & val))
 | 
|---|
| 372 |    {
 | 
|---|
| 373 |          snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGFLICKER %s", strerror(errno));
 | 
|---|
| 374 |          cerr << msg << endl;
 | 
|---|
| 375 |    }
 | 
|---|
| 376 |    
 | 
|---|
| 377 |    return val !=0;
 | 
|---|
| 378 | }
 | 
|---|
| 379 | 
 | 
|---|
| 380 | void V4L1_PWC::setGama(int val)
 | 
|---|
| 381 | {
 | 
|---|
| 382 |    picture_format.whiteness=val;
 | 
|---|
| 383 |    setPictureSettings();
 | 
|---|
| 384 | }
 | 
|---|
| 385 | 
 | 
|---|
| 386 | int V4L1_PWC::getGama() 
 | 
|---|
| 387 | {
 | 
|---|
| 388 |    return picture_format.whiteness;
 | 
|---|
| 389 | }
 | 
|---|
| 390 | 
 | 
|---|
| 391 | int V4L1_PWC::setFrameRate(int value, char *errmsg)
 | 
|---|
| 392 |  {
 | 
|---|
| 393 |    window.flags = (window.flags & ~PWC_FPS_MASK) | ((value << PWC_FPS_SHIFT) & PWC_FPS_MASK);
 | 
|---|
| 394 |    if (ioctl(fd, VIDIOCSWIN, &window))
 | 
|---|
| 395 |    {
 | 
|---|
| 396 |              snprintf(errmsg, ERRMSG_SIZ, "setFrameRate %s", strerror(errno));
 | 
|---|
| 397 |              return -1;
 | 
|---|
| 398 |    }
 | 
|---|
| 399 |    
 | 
|---|
| 400 |    ioctl(fd, VIDIOCGWIN, &window);
 | 
|---|
| 401 |    frameRate = value;
 | 
|---|
| 402 |    
 | 
|---|
| 403 |    return 0;
 | 
|---|
| 404 |    //emit exposureTime(multiplicateur_/(double)getFrameRate());
 | 
|---|
| 405 | }
 | 
|---|
| 406 | 
 | 
|---|
| 407 | int V4L1_PWC::getFrameRate() 
 | 
|---|
| 408 | {
 | 
|---|
| 409 |    return ((window.flags&PWC_FPS_FRMASK)>>PWC_FPS_SHIFT); 
 | 
|---|
| 410 | }
 | 
|---|
| 411 | 
 | 
|---|
| 412 | int V4L1_PWC::getWhiteBalance()
 | 
|---|
| 413 | {
 | 
|---|
| 414 |    char msg[ERRMSG_SIZ];
 | 
|---|
| 415 |    struct pwc_whitebalance tmp_whitebalance;
 | 
|---|
| 416 |    tmp_whitebalance.mode = tmp_whitebalance.manual_red = tmp_whitebalance.manual_blue = tmp_whitebalance.read_red = tmp_whitebalance.read_blue = PWC_WB_AUTO;
 | 
|---|
| 417 |    
 | 
|---|
| 418 |    if (ioctl(fd, VIDIOCPWCGAWB, &tmp_whitebalance)) 
 | 
|---|
| 419 |    {
 | 
|---|
| 420 |            snprintf(msg, ERRMSG_SIZ, "getWhiteBalance %s", strerror(errno));
 | 
|---|
| 421 |            cerr << msg << endl;
 | 
|---|
| 422 |    }
 | 
|---|
| 423 |    else
 | 
|---|
| 424 |    {
 | 
|---|
| 425 | #if 0
 | 
|---|
| 426 |       cout << "mode="<<tmp_whitebalance.mode
 | 
|---|
| 427 |            <<" mr="<<tmp_whitebalance.manual_red
 | 
|---|
| 428 |            <<" mb="<<tmp_whitebalance.manual_blue
 | 
|---|
| 429 |            <<" ar="<<tmp_whitebalance.read_red
 | 
|---|
| 430 |            <<" ab="<<tmp_whitebalance.read_blue
 | 
|---|
| 431 |            <<endl;
 | 
|---|
| 432 | #endif
 | 
|---|
| 433 |       /* manual_red and manual_blue are garbage :-( */
 | 
|---|
| 434 |       whiteBalanceMode_=tmp_whitebalance.mode;
 | 
|---|
| 435 |    }
 | 
|---|
| 436 |             
 | 
|---|
| 437 |       return whiteBalanceMode_;
 | 
|---|
| 438 |      
 | 
|---|
| 439 |       /*switch(whiteBalanceMode_) {
 | 
|---|
| 440 |       case PWC_WB_INDOOR:
 | 
|---|
| 441 |          setProperty("WhiteBalanceMode","Indor");
 | 
|---|
| 442 |          break;
 | 
|---|
| 443 |       case PWC_WB_OUTDOOR:
 | 
|---|
| 444 |          setProperty("WhiteBalanceMode","Outdoor");
 | 
|---|
| 445 |          break;
 | 
|---|
| 446 |       case PWC_WB_FL:
 | 
|---|
| 447 |          setProperty("WhiteBalanceMode","Neon");
 | 
|---|
| 448 |          break;
 | 
|---|
| 449 |       case PWC_WB_MANUAL:
 | 
|---|
| 450 |           setProperty("WhiteBalanceMode","Manual");
 | 
|---|
| 451 |           whiteBalanceRed_=tmp_whitebalance.manual_red;
 | 
|---|
| 452 |           whiteBalanceBlue_=tmp_whitebalance.manual_blue;
 | 
|---|
| 453 | 
 | 
|---|
| 454 |          break;
 | 
|---|
| 455 |       case PWC_WB_AUTO:
 | 
|---|
| 456 |          setProperty("WhiteBalanceMode","Auto");
 | 
|---|
| 457 |          whiteBalanceRed_=tmp_whitebalance.read_red;
 | 
|---|
| 458 |          whiteBalanceBlue_=tmp_whitebalance.read_blue;
 | 
|---|
| 459 |          break;
 | 
|---|
| 460 |       default:
 | 
|---|
| 461 |          setProperty("WhiteBalanceMode","???");
 | 
|---|
| 462 |       }
 | 
|---|
| 463 |          
 | 
|---|
| 464 |       emit whiteBalanceModeChange(whiteBalanceMode_);
 | 
|---|
| 465 | 
 | 
|---|
| 466 |       if (((whiteBalanceMode_ == PWC_WB_AUTO) && liveWhiteBalance_)
 | 
|---|
| 467 |           || whiteBalanceMode_ != PWC_WB_AUTO) {
 | 
|---|
| 468 |          setProperty("WhiteBalanceRed",whiteBalanceRed_);
 | 
|---|
| 469 |          emit whiteBalanceRedChange(whiteBalanceRed_);
 | 
|---|
| 470 |          setProperty("WhiteBalanceBlue",whiteBalanceBlue_);   
 | 
|---|
| 471 |          emit whiteBalanceBlueChange(whiteBalanceBlue_);
 | 
|---|
| 472 |          if (guiBuild()) {         
 | 
|---|
| 473 |             remoteCTRLWBred_->show();
 | 
|---|
| 474 |             remoteCTRLWBblue_->show();
 | 
|---|
| 475 |          }
 | 
|---|
| 476 |       } else {
 | 
|---|
| 477 |          if (guiBuild()) {         
 | 
|---|
| 478 |             remoteCTRLWBred_->hide();
 | 
|---|
| 479 |             remoteCTRLWBblue_->hide();
 | 
|---|
| 480 |          }
 | 
|---|
| 481 |       }
 | 
|---|
| 482 |    }*/
 | 
|---|
| 483 | }
 | 
|---|
| 484 | 
 | 
|---|
| 485 | int V4L1_PWC::setWhiteBalance(char *errmsg) 
 | 
|---|
| 486 | {
 | 
|---|
| 487 |    struct pwc_whitebalance wb;
 | 
|---|
| 488 |    wb.mode=whiteBalanceMode_;
 | 
|---|
| 489 |    if (wb.mode == PWC_WB_MANUAL)
 | 
|---|
| 490 |    {
 | 
|---|
| 491 |       wb.manual_red=whiteBalanceRed_;
 | 
|---|
| 492 |       wb.manual_blue=whiteBalanceBlue_;
 | 
|---|
| 493 |    }
 | 
|---|
| 494 |    
 | 
|---|
| 495 |    if (ioctl(fd, VIDIOCPWCSAWB, &wb))
 | 
|---|
| 496 |    {
 | 
|---|
| 497 |        snprintf(errmsg, ERRMSG_SIZ, "setWhiteBalance %s", strerror(errno)); 
 | 
|---|
| 498 |        return -1;
 | 
|---|
| 499 |    }
 | 
|---|
| 500 |    
 | 
|---|
| 501 |    return 0;
 | 
|---|
| 502 | }
 | 
|---|
| 503 | 
 | 
|---|
| 504 | int V4L1_PWC::setWhiteBalanceMode(int val, char *errmsg)
 | 
|---|
| 505 |  {
 | 
|---|
| 506 |    if (val == whiteBalanceMode_) 
 | 
|---|
| 507 |       return whiteBalanceMode_;
 | 
|---|
| 508 |       
 | 
|---|
| 509 |    if (val != PWC_WB_AUTO)
 | 
|---|
| 510 |    {
 | 
|---|
| 511 |       if ( val != PWC_WB_MANUAL)
 | 
|---|
| 512 |       {
 | 
|---|
| 513 |          whiteBalanceMode_=val;
 | 
|---|
| 514 |          if (setWhiteBalance(errmsg) < 0)
 | 
|---|
| 515 |            return -1;
 | 
|---|
| 516 |       }
 | 
|---|
| 517 |       
 | 
|---|
| 518 |       //whiteBalanceMode_=PWC_WB_AUTO;
 | 
|---|
| 519 |       whiteBalanceMode_= val;
 | 
|---|
| 520 |       if (setWhiteBalance(errmsg) < 0)
 | 
|---|
| 521 |        return -1;
 | 
|---|
| 522 |       getWhiteBalance();
 | 
|---|
| 523 |    }
 | 
|---|
| 524 | 
 | 
|---|
| 525 |    /*if (guiBuild()) {
 | 
|---|
| 526 |       if (val != PWC_WB_AUTO
 | 
|---|
| 527 |           || ( liveWhiteBalance_ && (val ==PWC_WB_AUTO))) {
 | 
|---|
| 528 |          remoteCTRLWBred_->show();
 | 
|---|
| 529 |          remoteCTRLWBblue_->show();
 | 
|---|
| 530 |       } else {
 | 
|---|
| 531 |          remoteCTRLWBred_->hide();
 | 
|---|
| 532 |          remoteCTRLWBblue_->hide();
 | 
|---|
| 533 |       }
 | 
|---|
| 534 |    }*/
 | 
|---|
| 535 |    
 | 
|---|
| 536 |    whiteBalanceMode_=val;
 | 
|---|
| 537 |    if (setWhiteBalance(errmsg) < 0)
 | 
|---|
| 538 |     return -1;
 | 
|---|
| 539 |    getWhiteBalance();
 | 
|---|
| 540 |    
 | 
|---|
| 541 |    return 0;
 | 
|---|
| 542 | }
 | 
|---|
| 543 | 
 | 
|---|
| 544 | int V4L1_PWC::setWhiteBalanceRed(int val, char *errmsg) 
 | 
|---|
| 545 | {
 | 
|---|
| 546 |    whiteBalanceMode_ = PWC_WB_MANUAL;
 | 
|---|
| 547 |    whiteBalanceRed_=val;
 | 
|---|
| 548 |    if (setWhiteBalance(errmsg) < 0)
 | 
|---|
| 549 |     return -1;
 | 
|---|
| 550 |     
 | 
|---|
| 551 |    return 0;
 | 
|---|
| 552 | }
 | 
|---|
| 553 | 
 | 
|---|
| 554 | int V4L1_PWC::setWhiteBalanceBlue(int val, char *errmsg)
 | 
|---|
| 555 | {
 | 
|---|
| 556 |    whiteBalanceMode_ = PWC_WB_MANUAL;
 | 
|---|
| 557 |    whiteBalanceBlue_=val;
 | 
|---|
| 558 |    if (setWhiteBalance(errmsg) < 0)
 | 
|---|
| 559 |      return -1;
 | 
|---|
| 560 |      
 | 
|---|
| 561 |    return 0;
 | 
|---|
| 562 | }
 | 
|---|
| 563 | 
 | 
|---|