OpenVideo Documentation

   Main Page       Modules       Class Hierarchy       Alphabetical List       Compound List       File List       Compound Members       Related Pages   

V4LSrc.cxx

Go to the documentation of this file.
00001 /* ========================================================================
00002  * Copyright (C) 2005  Graz University of Technology
00003  *
00004  * This framework is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This framework is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this framework; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  * For further information please contact Denis Kalkofen under
00019  * <kalkofen@icg.tu-graz.ac.at> or write to Denis Kalkofen,
00020  * Graz University of Technology, Inffeldgasse 16a, A8010 Graz,
00021  * Austria.
00022  * ========================================================================
00023  * PROJECT: OpenVideo
00024  * ======================================================================== */
00033 #include <openvideo/nodes/V4LSrc.h>
00034 
00035 #include <openvideo/State.h>
00036 #include <iostream>
00037 #include <cstdlib>
00038 
00039 #ifdef ENABLE_V4LSRC
00040 
00041 // Check to see whether they are portable
00042 #include <sys/mman.h>  /* mmap */
00043 #include <fcntl.h>
00044 
00045 using namespace std;
00046 
00047 // Initialize variable to default values.
00048 V4LSrc::V4LSrc() : videoWidth(640), videoHeight(480), 
00049            videoMode(VIDEO_MODE_PAL), videoChannel(VideoCompositeSource), 
00050            pixelFormat(FORMAT_B8G8R8), videoPixelFormat(V4L_FORMAT_RGB24), 
00051            videoBuffer(NULL), videoFd(-1), videoFrame(0) 
00052 {
00053   strcpy(videoDevice, "/dev/video0");
00054 
00055   state=new State();
00056   state->clear();
00057   state->width=videoWidth;
00058   state->height=videoHeight;
00059   state->format=pixelFormat;    
00060 }
00061     
00062 V4LSrc::~V4LSrc()
00063 {
00064   if (videoFd >= 0) {
00065     close(videoFd);
00066   }
00067 
00068   if (videoBuffer != NULL) {
00069     munmap(videoBuffer, videoInfo.size);
00070   }
00071   
00072   delete state;
00073 }
00074 
00075 void
00076 V4LSrc::start()
00077 {
00078   state->clear();
00079   state->width=videoWidth;
00080   state->height=videoHeight;
00081   state->format=pixelFormat;    
00082   
00083   if ((videoFd = open(videoDevice, O_RDWR)) < 0) {
00084     cerr << "Couldn't open " << videoDevice << endl;
00085 
00086     return;
00087   } 
00088   
00089   if (V4LMGetMMInfo(videoFd, &videoInfo) < 0) {
00090     cerr << "Couldn't acquire info struct." << endl;
00091 
00092     close(videoFd);
00093 
00094     return;
00095   } 
00096 
00097   cout << "v4lMMinfo" << endl 
00098        << "\tframes: " << videoInfo.frames << endl
00099        << "\tsize: " << videoInfo.size << endl;
00100 
00101   if (videoInfo.frames < 2) {
00102     cerr << "Device doesn't support double buffering." << endl;
00103     
00104     close (videoFd);
00105 
00106     return;
00107   } 
00108 
00109   if (V4LSetSource(videoFd, videoChannel, videoMode) <0){
00110     cerr << "Couldn't set requested source (channel, mode)." << endl;
00111     
00112     close(videoFd);
00113     
00114     return;
00115   } 
00116 
00118   V4LCaps videoCaps; 
00119 
00120   if (V4LGetCaps(videoFd, &videoCaps) < 0) {
00121     cerr << "Couldn't get Caps structure." << endl;
00122     
00123     close(videoFd);
00124     
00125     return;
00126   } 
00127 
00128   if (videoWidth < videoCaps.minwidth) 
00129     videoWidth = videoCaps.minwidth;
00130   else if (videoWidth > videoCaps.maxwidth)
00131     videoWidth = videoCaps.maxwidth;
00132 
00133   if (videoHeight < videoCaps.minheight) 
00134     videoHeight = videoCaps.minheight;
00135   else if (videoHeight > videoCaps.maxheight)
00136     videoHeight = videoCaps.maxheight;
00137 
00138   V4LFormat  v4lFormat;
00139   v4lFormat.width  = videoWidth;
00140   v4lFormat.height = videoHeight;
00141   v4lFormat.format = videoPixelFormat;
00142   
00143   V4LMSetFormat(&v4lFormat);
00144 
00145   // FIXME: Should check that we got the correct format.
00146   V4LMGetFormat(&v4lFormat);
00147   cout << "v4LFormat:" << endl
00148        << "\twidth: " << v4lFormat.width << endl
00149        << "\tvheight: " << v4lFormat.height << endl
00150        << "\tformat: " << v4lFormat.format << endl;
00151 
00152   // Initialize picture attributes to mid-range
00153   V4LSetBrightness(videoFd, 65535 / 2);
00154   V4LSetContrast(videoFd,   65535 / 2);
00155   V4LSetSaturation(videoFd, 65535 / 2);
00156   V4LSetHue(videoFd,        65535 / 2);
00157 
00158   if ((videoBuffer = (unsigned char *) mmap(0, videoInfo.size, 
00159                    PROT_READ| PROT_WRITE, 
00160                    MAP_SHARED , videoFd, 0)) 
00161       == MAP_FAILED) {
00162     cerr << "Failed to mmap buffer." << endl ;
00163     
00164     close(videoFd);
00165     return;
00166   }
00167 
00168   // Start capture for first frame.
00169   if (V4LMCapture(videoFd, videoFrame) < 0) {
00170     cerr << "Couldn't start of frame." << endl << flush;
00171     return;
00172   }
00173 }
00174 
00175 void
00176 V4LSrc::process()
00177 {
00178   timeval timestamp;
00179 
00180   if (videoFd < 0) {
00181     state->frame = NULL;
00182     return;
00183   }
00184 
00185   // Wait for this frame
00186   if (V4LMSync(videoFd, videoFrame) < 0) {
00187     cerr << "Couldn't sync with the device." << endl << flush;
00188     
00189     state->frame = NULL;
00190     
00191     return;
00192   } 
00193   
00194   // start capture of next frame
00195   if (V4LMCapture(videoFd, 1-videoFrame) < 0) {
00196     cerr << "Couldn't capture frame." << endl << flush;
00197 
00198     state->frame = NULL;
00199     
00200     return;
00201   }
00202   
00203   assert(videoBuffer);
00204   
00205   // Get pointer to the captured frame
00206   state->frame = videoBuffer + videoInfo.offsets[videoFrame];
00207 
00208   // switch image buffer (capture is double buffered)
00209   videoFrame = 1 - videoFrame; // 0<->1
00210 }
00211 
00212 void
00213 V4LSrc::postProcess()
00214 {
00215   state->frame=NULL;
00216 }
00217 
00218 bool 
00219 V4LSrc::setParameter(string key, string value)
00220 {
00221   cout << "V4LSrc::setParameter: " << key << " " << value << endl;
00222   if(Node::setParameter(key,value))
00223       return true;
00224 
00225   
00226   if(key=="width")
00227     {
00228       this->videoWidth=atoi(value.c_str());
00229       return true;
00230     }
00231   else if(key=="height")
00232     {
00233       this->videoHeight=atoi(value.c_str());
00234       return true;
00235     }
00236   else if (key=="device") 
00237     {    
00238       strcpy(this->videoDevice, value.c_str());
00239       return true;
00240     }
00241   else if (key=="format")
00242     {
00243       PIXEL_FORMAT pf = PixelFormat::StringToFormat(value);
00244 
00245       switch(pf) {
00246       case (FORMAT_B8G8R8):
00247     pixelFormat = pf;
00248     videoPixelFormat = V4L_FORMAT_RGB24;
00249     break;
00250 
00251       case (FORMAT_B8G8R8X8):
00252     pixelFormat = pf;
00253     videoPixelFormat = V4L_FORMAT_RGB32;
00254     break;
00255 
00256       case (FORMAT_R5G6B5):
00257     pixelFormat = pf;
00258     videoPixelFormat = V4L_FORMAT_RGB16;
00259     break;
00260 
00261       case (FORMAT_L8):
00262     pixelFormat = pf;
00263     videoPixelFormat = V4L_FORMAT_Y8;
00264     break;
00265 
00266       default:
00267     cout << "PixelFormat " << value << " is not supported. "
00268          << "Using default value " << PixelFormat::FormatToString(pixelFormat) << endl;
00269       }
00270 
00271       return true;
00272     }
00273   else if (key=="videoMode")
00274     {
00275       if (value=="PAL")
00276     {
00277       videoMode = VIDEO_MODE_PAL;
00278       return true;
00279     }
00280       else if (value=="NTSC")
00281     {
00282       videoMode = VIDEO_MODE_NTSC;
00283 
00284       return true;
00285     }
00286       else {
00287     assert(false && "Wrong videoMode parameter.");
00288       }
00289       
00290       return false;
00291     }
00292   else if (key=="videoChannel")
00293     {
00294       if (value=="TV")
00295     {
00296       videoChannel=VideoTVSource;
00297     }
00298       else if (value=="Composite")
00299     {
00300 
00301       videoChannel=VideoCompositeSource;
00302     
00303     }
00304       else if (value=="SVideo")
00305     {
00306       videoChannel=VideoSVideoSource;
00307     }
00308       else {
00309     assert(false && "Wrong videoChannel.");
00310       }
00311 
00312       return true;
00313     }
00314   else 
00315     {
00316       cout << "No key: " << key << endl;
00317     }
00318   return false;
00319 }
00320 
00321 #endif // ENABLE_V4LSRC
 This page was generated at Wed May 31 13:04:16 2006 for OpenVideo by Doxygen.
 If you have any comments, please send a message to schmalstieg@icg.tu-graz.ac.at.
www.studierstube.org