• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

v4l1_pwc.cpp

Go to the documentation of this file.
00001 /*
00002     Phlips webcam driver for V4L 1
00003     Copyright (C) 2005 by Jasem Mutlaq
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019 */
00020 
00021 #include <iostream>
00022 
00023 #include <sys/ioctl.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <fcntl.h>
00027 #include <unistd.h>
00028 #include <stdio.h>
00029 #include <errno.h>
00030 #include <sys/mman.h>
00031 #include <string.h>
00032 
00033 #include "ccvt.h"
00034 #include "pwc-ioctl.h"
00035 #include "v4l1_pwc.h"
00036 #include "../eventloop.h"
00037 
00038 #define ERRMSG_SIZ  1024
00039 
00040 extern int errno;
00041 using namespace std;
00042 
00043 V4L1_PWC::V4L1_PWC()
00044 {
00045    frameRate=15;
00046    fd=-1;
00047    streamActive = true;
00048 
00049    YBuf       = NULL;
00050    UBuf       = NULL;
00051    VBuf       = NULL;
00052    colorBuffer= NULL;
00053    buffer_start=NULL;
00054 }
00055 
00056 V4L1_PWC::~V4L1_PWC()
00057 {
00058 
00059 } 
00060 
00061 int V4L1_PWC::connectCam(const char * devpath, char *errmsg)
00062 {
00063    options= (ioNoBlock|ioUseSelect|haveBrightness|haveContrast|haveColor);
00064    struct pwc_probe probe;
00065    bool IsPhilips = false;
00066    frameRate=15;
00067    fd=-1;
00068    streamActive = true;
00069    buffer_start=NULL;
00070    
00071    if (-1 == (fd=open(devpath,
00072                            O_RDONLY | ((options & ioNoBlock) ? O_NONBLOCK : 0)))) {
00073       
00074       strncpy(errmsg, strerror(errno), 1024);
00075       cerr << strerror(errno);
00076       return -1;
00077    } 
00078   
00079    cerr << "Device opened" << endl;
00080    
00081    if (fd != -1) {
00082       if (-1 == ioctl(fd,VIDIOCGCAP,&capability)) {
00083          cerr << "Error: ioctl (VIDIOCGCAP)" << endl;
00084      strncpy(errmsg, "ioctl (VIDIOCGCAP)", 1024);
00085      return -1;
00086       }
00087       if (-1 == ioctl (fd, VIDIOCGWIN, &window)) {
00088          cerr << "Error: ioctl (VIDIOCGWIN)" << endl;
00089      strncpy(errmsg, "ioctl (VIDIOCGWIN)", 1024);
00090      return -1;
00091       }
00092       if (-1 == ioctl (fd, VIDIOCGPICT, &picture_format)) {
00093          cerr << "Error: ioctl (VIDIOCGPICT)" << endl;
00094      strncpy(errmsg, "ioctl (VIDIOCGPICT)", 1024);
00095      return -1;
00096       }
00097       init(0);
00098    }
00099    
00100   // Check to see if it's really a philips webcam       
00101   if (ioctl(fd, VIDIOCPWCPROBE, &probe) == 0) 
00102   {
00103         if (!strcmp(capability.name,probe.name))
00104         {
00105            IsPhilips = true;
00106            type_=probe.type;
00107             }
00108  }
00109      
00110   if (IsPhilips)
00111       cerr << "Philips webcam type " << type_ << " detected" << endl;
00112   else
00113   {
00114    strncpy(errmsg, "No Philips webcam detected.", 1024);
00115    return -1;
00116   }
00117     
00118    cerr << "initial size w:" << window.width << " -- h: " << window.height << endl;
00119    
00120    
00121    mmapInit();
00122    
00123    setWhiteBalanceMode(PWC_WB_AUTO, errmsg);
00124    multiplicateur_=1;
00125    skippedFrame_=0;
00126    lastGain_=getGain();
00127 
00128    cerr << "All successful, returning\n";
00129    return fd;
00130 }
00131 
00132 void V4L1_PWC::checkSize(int & x, int & y) 
00133 {
00134  if (x>=capability.maxwidth && y >= capability.maxheight)
00135    {
00136       x=capability.maxwidth;
00137       y=capability.maxheight;
00138    } else if (x>=352 && y >=288 && type_<700) {
00139       x=352;y=288;
00140    } else if (x>=320 && y >= 240) {
00141       x=320;y=240;
00142    } else if (x>=176 && y >=144 && type_<700 ) {
00143       x=176;y=144;
00144    } else if (x>=160 && y >=120 ) {
00145       x=160;y=120;
00146    } else {
00147       x=capability.minwidth;
00148       y=capability.minheight;
00149    }
00150 }
00151 
00152 bool V4L1_PWC::setSize(int x, int y) 
00153 {
00154 
00155    int oldX, oldY;
00156    char msg[ERRMSG_SIZ];
00157    checkSize(x,y);
00158    
00159    oldX = window.width;
00160    oldY = window.height;
00161    
00162    window.width=x;
00163    window.height=y;
00164    
00165    if (ioctl (fd, VIDIOCSWIN, &window))
00166    {
00167        snprintf(msg, ERRMSG_SIZ, "ioctl(VIDIOCSWIN) %s", strerror(errno));
00168        cerr << msg << endl;
00169        window.width=oldX;
00170        window.height=oldY;
00171        return false;
00172    }
00173    ioctl (fd, VIDIOCGWIN, &window);
00174 
00175    cerr << "New size is x=" << window.width << " " << "y=" << window.height <<endl;
00176    
00177    allocBuffers();
00178    
00179    return true;
00180 }
00181 
00182 int V4L1_PWC::saveSettings(char *errmsg)
00183 {
00184    if (ioctl(fd, VIDIOCPWCSUSER)==-1)
00185     {
00186       snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSUSER %s", strerror(errno));
00187       return -1;
00188    }
00189    
00190    return 0;
00191 }
00192 
00193 void V4L1_PWC::restoreSettings()
00194  {
00195    ioctl(fd, VIDIOCPWCRUSER);
00196    getPictureSettings();
00197 }
00198 
00199 void V4L1_PWC::restoreFactorySettings()
00200 {
00201    ioctl(fd, VIDIOCPWCFACTORY);
00202    getPictureSettings();
00203 }
00204 
00205 int V4L1_PWC::setGain(int val, char *errmsg)
00206  {
00207    if(-1==ioctl(fd, VIDIOCPWCSAGC, &val))
00208    {
00209       snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSAGC %s", strerror(errno));
00210       return -1;
00211    }
00212    else lastGain_=val;
00213    
00214    cerr << "setGain "<<val<<endl;
00215    
00216    return lastGain_;
00217 }
00218 
00219 int V4L1_PWC::getGain()
00220 {
00221    int gain;
00222    char msg[ERRMSG_SIZ];
00223    static int cpt=0;
00224    if ((cpt%4)==0)
00225    {
00226       if (-1==ioctl(fd, VIDIOCPWCGAGC, &gain))
00227       {
00228          //perror("VIDIOCPWCGAGC");
00229      snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGAGC %s", strerror(errno));
00230      cerr << msg << endl;
00231          gain=lastGain_;
00232       } else
00233       {
00234          ++cpt;
00235          lastGain_=gain;
00236       }
00237    } else
00238    {
00239       ++cpt;
00240       gain=lastGain_; 
00241    }
00242    //cerr << "get gain "<<gain<<endl;
00243    if (gain < 0) gain*=-1;
00244    return gain;
00245 }
00246 
00247 int V4L1_PWC::setExposure(int val, char *errmsg)
00248  {
00249    //cout << "set exposure "<<val<<"\n";
00250    
00251    if (-1==ioctl(fd, VIDIOCPWCSSHUTTER, &val))
00252    {
00253      snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSSHUTTER %s", strerror(errno));
00254      return -1;
00255   }
00256   
00257   return 0;
00258 }
00259 
00260 void V4L1_PWC::setCompression(int val)
00261 {
00262    ioctl(fd, VIDIOCPWCSCQUAL, &val); 
00263 }
00264 
00265 int V4L1_PWC::getCompression()
00266 {
00267    int gain;
00268    ioctl(fd, VIDIOCPWCGCQUAL , &gain);
00269    if (gain < 0) gain*=-1;
00270    return gain;
00271 }
00272 
00273 int V4L1_PWC::setNoiseRemoval(int val, char *errmsg)
00274 {
00275    if (-1 == ioctl(fd, VIDIOCPWCSDYNNOISE, &val))
00276    {
00277        snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCGDYNNOISE %s", strerror(errno));
00278        return -1;
00279    }
00280    
00281    return 0;
00282 }
00283 
00284 int V4L1_PWC::getNoiseRemoval()
00285 {
00286    int gain;
00287    char msg[ERRMSG_SIZ];
00288    
00289    if (-1 == ioctl(fd, VIDIOCPWCGDYNNOISE , &gain)) 
00290    {
00291      snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGDYNNOISE %s", strerror(errno));
00292      cerr << msg << endl;
00293    }
00294       
00295    cout <<"get noise = "<<gain<<endl;
00296    return gain;
00297 }
00298 
00299 int V4L1_PWC::setSharpness(int val, char *errmsg)
00300  {
00301    if (-1 == ioctl(fd, VIDIOCPWCSCONTOUR, &val))
00302    {
00303        snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSCONTOUR %s", strerror(errno));
00304        return -1;
00305   }
00306   
00307   return 0;
00308 }
00309 
00310 int V4L1_PWC::getSharpness()
00311 {
00312    int gain;
00313    char msg[ERRMSG_SIZ];
00314    
00315    if (-1 == ioctl(fd, VIDIOCPWCGCONTOUR, &gain)) 
00316    {
00317       snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGCONTOUR %s", strerror(errno));
00318       cerr << msg << endl;
00319   }
00320    
00321    cout <<"get sharpness = "<<gain<<endl;
00322    return gain;
00323 }
00324 
00325 int V4L1_PWC::setBackLight(bool val, char *errmsg)
00326 {
00327    static int on=1;
00328    static int off=0;
00329    if (-1 == ioctl(fd,VIDIOCPWCSBACKLIGHT, &  val?&on:&off))
00330    {
00331         snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSBACKLIGHT %s", strerror(errno));
00332     return -1;
00333    }
00334    
00335    return 0;
00336 }
00337 
00338 bool V4L1_PWC::getBackLight()
00339 {
00340    int val;
00341    char msg[ERRMSG_SIZ];
00342    
00343    if (-1 == ioctl(fd,VIDIOCPWCGBACKLIGHT, & val)) 
00344    {
00345       snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCSBACKLIGHT %s", strerror(errno));
00346       cerr << msg << endl;
00347    }
00348 
00349    return val !=0;
00350 }
00351 
00352 int V4L1_PWC::setFlicker(bool val, char *errmsg)
00353 {
00354    static int on=1;
00355    static int off=0;
00356    if (-1 == ioctl(fd,VIDIOCPWCSFLICKER, val?&on:&off))
00357    {
00358       snprintf(errmsg, ERRMSG_SIZ, "VIDIOCPWCSFLICKER %s", strerror(errno));
00359       return -1;
00360    }
00361    
00362    return 0;
00363    
00364 }
00365 
00366 bool V4L1_PWC::getFlicker() 
00367 {
00368    int val;
00369    char msg[ERRMSG_SIZ];
00370    
00371    if (-1 == ioctl(fd,VIDIOCPWCGFLICKER, & val))
00372    {
00373          snprintf(msg, ERRMSG_SIZ, "VIDIOCPWCGFLICKER %s", strerror(errno));
00374      cerr << msg << endl;
00375    }
00376    
00377    return val !=0;
00378 }
00379 
00380 void V4L1_PWC::setGama(int val)
00381 {
00382    picture_format.whiteness=val;
00383    setPictureSettings();
00384 }
00385 
00386 int V4L1_PWC::getGama() 
00387 {
00388    return picture_format.whiteness;
00389 }
00390 
00391 int V4L1_PWC::setFrameRate(int value, char *errmsg)
00392  {
00393    window.flags = (window.flags & ~PWC_FPS_MASK) | ((value << PWC_FPS_SHIFT) & PWC_FPS_MASK);
00394    if (ioctl(fd, VIDIOCSWIN, &window))
00395    {
00396              snprintf(errmsg, ERRMSG_SIZ, "setFrameRate %s", strerror(errno));
00397          return -1;
00398    }
00399    
00400    ioctl(fd, VIDIOCGWIN, &window);
00401    frameRate = value;
00402    
00403    return 0;
00404    //emit exposureTime(multiplicateur_/(double)getFrameRate());
00405 }
00406 
00407 int V4L1_PWC::getFrameRate() 
00408 {
00409    return ((window.flags&PWC_FPS_FRMASK)>>PWC_FPS_SHIFT); 
00410 }
00411 
00412 int V4L1_PWC::getWhiteBalance()
00413 {
00414    char msg[ERRMSG_SIZ];
00415    struct pwc_whitebalance tmp_whitebalance;
00416    tmp_whitebalance.mode = tmp_whitebalance.manual_red = tmp_whitebalance.manual_blue = tmp_whitebalance.read_red = tmp_whitebalance.read_blue = PWC_WB_AUTO;
00417    
00418    if (ioctl(fd, VIDIOCPWCGAWB, &tmp_whitebalance)) 
00419    {
00420            snprintf(msg, ERRMSG_SIZ, "getWhiteBalance %s", strerror(errno));
00421        cerr << msg << endl;
00422    }
00423    else
00424    {
00425 #if 0
00426       cout << "mode="<<tmp_whitebalance.mode
00427            <<" mr="<<tmp_whitebalance.manual_red
00428            <<" mb="<<tmp_whitebalance.manual_blue
00429            <<" ar="<<tmp_whitebalance.read_red
00430            <<" ab="<<tmp_whitebalance.read_blue
00431            <<endl;
00432 #endif
00433       /* manual_red and manual_blue are garbage :-( */
00434       whiteBalanceMode_=tmp_whitebalance.mode;
00435    }
00436             
00437       return whiteBalanceMode_;
00438      
00439       /*switch(whiteBalanceMode_) {
00440       case PWC_WB_INDOOR:
00441          setProperty("WhiteBalanceMode","Indor");
00442          break;
00443       case PWC_WB_OUTDOOR:
00444          setProperty("WhiteBalanceMode","Outdoor");
00445          break;
00446       case PWC_WB_FL:
00447          setProperty("WhiteBalanceMode","Neon");
00448          break;
00449       case PWC_WB_MANUAL:
00450           setProperty("WhiteBalanceMode","Manual");
00451           whiteBalanceRed_=tmp_whitebalance.manual_red;
00452           whiteBalanceBlue_=tmp_whitebalance.manual_blue;
00453 
00454          break;
00455       case PWC_WB_AUTO:
00456          setProperty("WhiteBalanceMode","Auto");
00457          whiteBalanceRed_=tmp_whitebalance.read_red;
00458          whiteBalanceBlue_=tmp_whitebalance.read_blue;
00459          break;
00460       default:
00461          setProperty("WhiteBalanceMode","???");
00462       }
00463          
00464       emit whiteBalanceModeChange(whiteBalanceMode_);
00465 
00466       if (((whiteBalanceMode_ == PWC_WB_AUTO) && liveWhiteBalance_)
00467           || whiteBalanceMode_ != PWC_WB_AUTO) {
00468          setProperty("WhiteBalanceRed",whiteBalanceRed_);
00469          emit whiteBalanceRedChange(whiteBalanceRed_);
00470          setProperty("WhiteBalanceBlue",whiteBalanceBlue_);   
00471          emit whiteBalanceBlueChange(whiteBalanceBlue_);
00472          if (guiBuild()) {         
00473             remoteCTRLWBred_->show();
00474             remoteCTRLWBblue_->show();
00475          }
00476       } else {
00477          if (guiBuild()) {         
00478             remoteCTRLWBred_->hide();
00479             remoteCTRLWBblue_->hide();
00480          }
00481       }
00482    }*/
00483 }
00484 
00485 int V4L1_PWC::setWhiteBalance(char *errmsg) 
00486 {
00487    struct pwc_whitebalance wb;
00488    wb.mode=whiteBalanceMode_;
00489    if (wb.mode == PWC_WB_MANUAL)
00490    {
00491       wb.manual_red=whiteBalanceRed_;
00492       wb.manual_blue=whiteBalanceBlue_;
00493    }
00494    
00495    if (ioctl(fd, VIDIOCPWCSAWB, &wb))
00496    {
00497        snprintf(errmsg, ERRMSG_SIZ, "setWhiteBalance %s", strerror(errno)); 
00498        return -1;
00499    }
00500    
00501    return 0;
00502 }
00503 
00504 int V4L1_PWC::setWhiteBalanceMode(int val, char *errmsg)
00505  {
00506    if (val == whiteBalanceMode_) 
00507       return whiteBalanceMode_;
00508       
00509    if (val != PWC_WB_AUTO)
00510    {
00511       if ( val != PWC_WB_MANUAL)
00512       {
00513          whiteBalanceMode_=val;
00514          if (setWhiteBalance(errmsg) < 0)
00515        return -1;
00516       }
00517       
00518       //whiteBalanceMode_=PWC_WB_AUTO;
00519       whiteBalanceMode_= val;
00520       if (setWhiteBalance(errmsg) < 0)
00521        return -1;
00522       getWhiteBalance();
00523    }
00524 
00525    /*if (guiBuild()) {
00526       if (val != PWC_WB_AUTO
00527           || ( liveWhiteBalance_ && (val ==PWC_WB_AUTO))) {
00528          remoteCTRLWBred_->show();
00529          remoteCTRLWBblue_->show();
00530       } else {
00531          remoteCTRLWBred_->hide();
00532          remoteCTRLWBblue_->hide();
00533       }
00534    }*/
00535    
00536    whiteBalanceMode_=val;
00537    if (setWhiteBalance(errmsg) < 0)
00538     return -1;
00539    getWhiteBalance();
00540    
00541    return 0;
00542 }
00543 
00544 int V4L1_PWC::setWhiteBalanceRed(int val, char *errmsg) 
00545 {
00546    whiteBalanceMode_ = PWC_WB_MANUAL;
00547    whiteBalanceRed_=val;
00548    if (setWhiteBalance(errmsg) < 0)
00549     return -1;
00550     
00551    return 0;
00552 }
00553 
00554 int V4L1_PWC::setWhiteBalanceBlue(int val, char *errmsg)
00555 {
00556    whiteBalanceMode_ = PWC_WB_MANUAL;
00557    whiteBalanceBlue_=val;
00558    if (setWhiteBalance(errmsg) < 0)
00559      return -1;
00560      
00561    return 0;
00562 }
00563 

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal