00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
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
00018 vidl2_v4l_istream::~vidl2_v4l_istream()
00019 {
00020 close();
00021 }
00022
00023
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
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
00080
00081 bool sp_ret = set_params(defaults_);
00082 vcl_cerr << "sp_ret = " << sp_ret << vcl_endl;
00083
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
00094 bool vidl2_v4l_istream::is_open() const
00095 {
00096 return fd_>0;
00097 }
00098
00099
00100 bool vidl2_v4l_istream::is_valid() const
00101 {
00102 return is_open();
00103 }
00104
00105
00106 void vidl2_v4l_istream::close()
00107 {
00108 ::close(fd_);
00109 fd_ = -1;
00110 }
00111
00112
00113
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
00212
00213
00214
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
00225
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
00235
00236 return false;
00237 }
00238 break;
00239 }
00240
00241 frame_number_++;
00242
00243 return true;
00244 }
00245
00246
00247
00248 vidl2_frame_sptr vidl2_v4l_istream::read_frame()
00249 {
00250 if (advance())
00251 return current_frame();
00252 return NULL;
00253 }