contrib/oul/oufgl/frame_grabber_vil.cxx
Go to the documentation of this file.
00001 #include "frame_grabber_vil.h"
00002 #include <vcl_cstdio.h> // for perror()
00003 #include <vcl_cstdlib.h> // for exit()
00004 #include <vcl_cerrno.h>
00005 
00006 // Constructor
00007 // Sets up the framegrabber.
00008 
00009 using namespace std;
00010 
00011 FrameGrabberVil::FrameGrabberVil(const string &device_name,
00012                                  int width, int height)
00013 {
00014   fd = open(device_name.c_str(), O_RDWR);
00015   if (fd<0)
00016   {
00017     vcl_perror("Couldn't open device");
00018     vcl_exit(-1);
00019   }
00020 
00021   ioctl(fd, VIDIOCSCHAN, 1);
00022 
00023   struct video_capability vcap;
00024   ioctl(fd, VIDIOCGCAP, &vcap);
00025   vcl_cout << "camera name = " << vcap.name << vcl_endl
00026            << "max image size = " << vcap.maxwidth << ' '
00027            << vcap.maxheight << vcl_endl;
00028   if (vcap.type && VID_TYPE_CAPTURE)
00029     vcl_cout << "can capture\n";
00030   else vcl_cout << "can't capture\n";
00031 
00032   struct video_picture vp;
00033   ioctl(fd, VIDIOCGPICT, &vp);
00034   vcl_cout << "vp.pallette = " << vp.palette << vcl_endl;
00035 
00036   vp.palette = VIDEO_PALETTE_YUV420P;
00037   if (ioctl(fd, VIDIOCSPICT, &vp)>=0)
00038     vcl_cout << "Successfully set palette to YUV420P\n";
00039   else
00040   {
00041     vcl_perror("Error setting pallette\n");
00042     vcl_cerr << "Capture may not work\n";
00043   }
00044   struct video_window vw;
00045   ioctl(fd, VIDIOCGWIN, &vw);
00046   vw.x = vw.y = 0;
00047   vw.width = width;
00048   vw.height = height;
00049   vcl_cout << "trying to set to window = " << vw.x << ' ' << vw.y
00050            << ' ' << vw.width << ' ' << vw.height << vcl_endl;
00051   // try setting the image size
00052   ioctl(fd, VIDIOCSWIN, &vw);
00053   // now read the actual size back
00054   ioctl(fd, VIDIOCGWIN, &vw);
00055   vcl_cout << "actually setting window to = " << vw.x << ' ' << vw.y
00056            << ' ' << vw.width << ' ' << vw.height << vcl_endl;
00057   // set the size to the actual size
00058   width = vw.width;
00059   height = vw.height;
00060 
00061   // Query the actual buffers available
00062   if (ioctl(fd, VIDIOCGMBUF, &vm) < 0) {
00063     vcl_perror("VIDIOCGMBUF");
00064     vcl_exit(-1);
00065   }
00066   vcl_cout << "vm.size = " << vm.size << " vm.frames = "
00067            << vm.frames << vcl_endl;
00068   vm.frames = 1;
00069 
00070   // MMap all available buffers
00071   bigbuf=(unsigned char*)mmap(0,vm.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
00072 
00073   if (bigbuf==(unsigned char *)-1) {
00074     vcl_perror("mmap");
00075     vcl_exit(-1);
00076   }
00077 
00078   mm.height = height; /* Your own height */
00079   mm.width  = width;  /* Your own width */
00080   mm.format = VIDEO_PALETTE_YUV420P; /* Your own format */
00081   mm.frame = 0;
00082 
00083   typedef vil_image_view<vxl_byte>* Type;
00084   frame = new Type[vm.frames];
00085 
00086   for (int i=0; i<vm.frames; i++)
00087   {
00088     vcl_cout << "offset = " << vm.offsets[i] << vcl_endl;
00089     frame[i] =
00090       new vil_image_view<vxl_byte>(bigbuf+vm.offsets[i],width,height,
00091                                    1,1,width,1);
00092   }
00093 #if 0
00094   if (ioctl(fd, VIDIOCMCAPTURE, &mm)<0) {
00095     vcl_perror("VIDIOCMCAPTURE");
00096     vcl_exit(-1);
00097   }
00098 #endif
00099 }
00100 
00101 FrameGrabberVil::~FrameGrabberVil()
00102 {
00103   close(fd);
00104   delete frame;
00105   munmap(bigbuf, vm.size);
00106 }
00107 
00108 vil_image_view<vxl_byte> *FrameGrabberVil::grab_frame()
00109 {
00110   int frame_num = mm.frame;
00111   mm.frame = (mm.frame+1)%vm.frames;
00112   if (ioctl(fd, VIDIOCMCAPTURE, &mm)<0) {
00113     vcl_perror("VIDIOCMCAPTURE");
00114     vcl_exit(-1);
00115   }
00116 
00117   int i = -1;
00118   while (i < 0) {
00119     i = ioctl(fd, VIDIOCSYNC, &frame_num);
00120     if (i < 0 && errno == EINTR)
00121     {
00122       vcl_perror("VIDIOCSYNC problem");
00123       continue;
00124     }
00125     if (i < 0) {
00126       vcl_perror("VIDIOCSYNC");
00127       // You may want to exit here, because something has gone
00128       // pretty badly wrong...
00129     }
00130     break;
00131   }
00132   return frame[i];
00133 }