Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vidl2_v4l_istream.cxx

Go to the documentation of this file.
00001 // This is brl/bbas/vidl2/vidl2_v4l_istream.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author Brendan McCane
00008 // \date   16 Mar 2006
00009 //
00010 //-----------------------------------------------------------------------------
00011 
00012 #include "vidl2_v4l_istream.h"
00013 #include "vidl2_v4l_params.h"
00014 #include "vidl2_pixel_format.h"
00015 #include "vidl2_frame.h"
00016 
00017 //: Destructor
00018 vidl2_v4l_istream::~vidl2_v4l_istream()
00019 {
00020     close();
00021 }
00022 
00023 //: open a device
00024 bool vidl2_v4l_istream::open(const vcl_string &device_name)
00025 {
00026     close();
00027     frame_number_ = 0;
00028 
00029     fd_ = ::open(device_name.c_str(), O_RDWR);
00030 
00031     if (fd_==-1)
00032         perror("problem with v4l");
00033 
00034     if (-1 == ioctl (fd_, VIDIOCGCAP, &vc)) {
00035         perror ("VIDIOCGCAP");
00036         return false;
00037     }
00038     vcl_cout << "name = " << vc.name << vcl_endl
00039              << "type = " << vc.type << vcl_endl
00040              << "channels = " << vc.channels << vcl_endl
00041              << "maxwidth = " << vc.maxwidth << vcl_endl
00042              << "maxheight = " << vc.maxheight << vcl_endl;
00043 
00044     if (-1 == ioctl (fd_, VIDIOCGWIN, &vw)) {
00045         perror ("VIDIOCGWIN");
00046         return false;
00047     }
00048     defaults_.ni_ = vw.width;
00049     defaults_.nj_ = vw.height;
00050 
00051     if (-1 == ioctl (fd_, VIDIOCGPICT, &vp)) {
00052         perror ("VIDIOCGPICT");
00053         return false;
00054     }
00055 
00056     defaults_.brightness_ = vp.brightness;
00057     defaults_.hue_ = vp.hue;
00058     defaults_.colour_ = vp.colour;
00059     defaults_.contrast_ = vp.contrast;
00060     defaults_.whiteness_ = vp.whiteness;
00061     defaults_.depth_ = vp.depth;
00062     defaults_.pixel_format_ = vidl2_v4l_params::v4lpf_to_vidl2pf(vp.palette);
00063     if (defaults_.pixel_format_ ==  VIDL2_PIXEL_FORMAT_UNKNOWN)
00064         defaults_.pixel_format_ = VIDL2_PIXEL_FORMAT_YUV_420P;
00065 
00066     if (-1 == ioctl (fd_, VIDIOCGMBUF, &vm)) {
00067         perror ("VIDIOCGMBUF");
00068         return false;
00069     }
00070     // for the moment just use one mmapped frame
00071     buf = mmap(0, vm.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd_,0);
00072     if (buf==(unsigned char *)-1)
00073     {
00074         perror("problem with mmap");
00075         close();
00076         return false;
00077     }
00078 
00079     // this looks a bit redundant (and it is), but some other things
00080     // are also set in set_params besides the actual driver controls
00081     bool sp_ret = set_params(defaults_);
00082     vcl_cerr << "sp_ret = " << sp_ret << vcl_endl;
00083     // serious problems if we can't set the params to the defaults
00084     if (!sp_ret)
00085     {
00086         vcl_cerr << "Problem in constructor, can't set camera to default\n"
00087                  << "Trying to continue anyway ...\n";
00088     }
00089 
00090     return sp_ret;
00091 }
00092 
00093 //: return true if the stream is open for reading
00094 bool vidl2_v4l_istream::is_open() const
00095 {
00096     return fd_>0;
00097 }
00098 
00099 //: return true if the stream is in a valid state
00100 bool vidl2_v4l_istream::is_valid() const
00101 {
00102     return is_open();
00103 }
00104 
00105 //: close the stream
00106 void vidl2_v4l_istream::close()
00107 {
00108     ::close(fd_);
00109     fd_ = -1;
00110 }
00111 
00112 //: set the parameters for this stream.
00113 // If all the parameters are set as requested, return true; else return false
00114 bool vidl2_v4l_istream::set_params(const vidl2_v4l_params &p)
00115 {
00116     bool success=true;
00117 
00118     params_ = p;
00119 
00120     vw.width = p.ni_;
00121     vw.height = p.nj_;
00122     if (-1 == ioctl (fd_, VIDIOCSWIN, &vw)) {
00123         vcl_cerr << "VIDIOCSWIN\n";
00124         perror ("VIDIOCGWIN");
00125         return false;
00126     }
00127     if (-1 == ioctl (fd_, VIDIOCGWIN, &vw)) {
00128         vcl_cerr << "VIDIOCGWIN\n";
00129         perror ("VIDIOCGWIN");
00130         return false;
00131     }
00132     if ((vw.width!=p.ni_)||(vw.height!=p.nj_))
00133     {
00134         vcl_cerr << "width not equal to default\n";
00135         success = false;
00136     }
00137 
00138     vp.brightness = p.brightness_;
00139     vp.hue =  p.hue_;
00140     vp.colour = p.colour_;
00141     vp.contrast = p.contrast_;
00142     vp.whiteness = p.whiteness_;
00143     vp.depth = p.depth_;
00144     vp.palette = vidl2_v4l_params::vidl2pf_to_v4lpf(p.pixel_format_);
00145     if (-1 == ioctl (fd_, VIDIOCSPICT, &vp)) {
00146         vcl_cerr << "VIDIOCSPICT\n";
00147         perror ("VIDIOCSPICT");
00148         return false;
00149     }
00150     if (-1 == ioctl (fd_, VIDIOCGPICT, &vp)) {
00151         vcl_cerr << "VIDIOCGPICT\n";
00152         perror ("VIDIOCGPICT");
00153         return false;
00154     }
00155 
00156     if (vp.brightness != p.brightness_)
00157     {
00158         success = false;
00159         vcl_cerr << "vp.brightness = " << vp.brightness << vcl_endl
00160                  << "p.brightness = " << p.brightness_ << vcl_endl;
00161     }
00162     if (vp.hue != p.hue_)
00163     {
00164         success = false;
00165         vcl_cerr << "vp.hue = " << vp.hue << vcl_endl
00166                  << "p.hue = " << p.hue_ << vcl_endl;
00167     }
00168     if (vp.colour != p.colour_)
00169     {
00170         success = false;
00171         vcl_cerr << "vp.colour = " << vp.colour << vcl_endl
00172                  << "p.colour = " << p.colour_ << vcl_endl;
00173     }
00174     if (vp.contrast != p.contrast_)
00175     {
00176         success = false;
00177         vcl_cerr << "vp.contrast = " << vp.contrast << vcl_endl
00178                  << "p.contrast = " << p.contrast_ << vcl_endl;
00179     }
00180     if (vp.whiteness != p.whiteness_)
00181     {
00182         success = false;
00183         vcl_cerr << "vp.whiteness = " << vp.whiteness << vcl_endl
00184                  << "p.whiteness = " << p.whiteness_ << vcl_endl;
00185     }
00186     if (vp.depth != p.depth_)
00187     {
00188         success = false;
00189         vcl_cerr << "vp.depth = " << vp.depth << vcl_endl
00190                  << "p.depth = " << p.depth_ << vcl_endl;
00191     }
00192     if (vp.palette != vidl2_v4l_params::vidl2pf_to_v4lpf(p.pixel_format_))
00193     {
00194         success = false;
00195         vcl_cerr << "vp.palette = " << vp.palette << vcl_endl
00196                  << "p.pixel_format = " << p.pixel_format_ << vcl_endl;
00197     }
00198 
00199     mm.width = vw.width;
00200     mm.height = vw.height;
00201     mm.format = vp.palette;
00202     mm.frame = 0;
00203 
00204     cur_frame_ = new vidl2_shared_frame(
00205         buf, vw.width, vw.height, vidl2_v4l_params::v4lpf_to_vidl2pf(vp.palette));
00206 
00207     vcl_cerr << "success = " << success << vcl_endl;
00208     return success;
00209 }
00210 
00211 //: advance to the next frame (but don't acquire an image)?
00212 // I'm quite confused by this description - I don't even know what it means.
00213 // I'm using the vidl2_dc1394_istream as a model here which clearly
00214 // advances and acquires - contrary to the first sentence description
00215 bool vidl2_v4l_istream::advance()
00216 {
00217     if (ioctl(fd_, VIDIOCMCAPTURE, &mm)<0) {
00218         perror("VIDIOCMCAPTURE");
00219         return false;
00220     }
00221 
00222     int i = -1;
00223 
00224     // shouldn't have to loop here, but apparently we do. Something to
00225     // do with interrupts.
00226     while (i < 0) {
00227         i = ioctl(fd_, VIDIOCSYNC, &mm.frame);
00228         if (i < 0 && errno == EINTR){
00229             perror("VIDIOCSYNC problem");
00230             continue;
00231         }
00232         if (i < 0) {
00233             perror("VIDIOCSYNC");
00234             // You may want to exit here, because something has gone
00235             // pretty badly wrong...
00236             return false;
00237         }
00238         break;
00239     }
00240 
00241     frame_number_++;
00242 
00243     return true;
00244 }
00245 
00246 //: Read the next frame from the stream
00247 //  Not sure why this one is needed ...
00248 vidl2_frame_sptr vidl2_v4l_istream::read_frame()
00249 {
00250     if (advance())
00251         return current_frame();
00252     return NULL;
00253 }

Generated on Thu Jan 10 14:51:31 2008 for contrib/brl/bbas/vidl2 by  doxygen 1.4.4