00001
00002
00003
00004
00005
00006 #ifndef VIDEODEVICE_H
00007 #define VIDEODEVICE_H
00008
00009 extern "C"
00010 {
00011 #include <unistd.h>
00012 #include <fcntl.h>
00013 #include <linux/videodev.h>
00014 }
00015
00016 #include <opencv/cv.hpp>
00017 #include <string>
00018 #include <iostream>
00019 #include "imagesource.h"
00020 #include "../image.h"
00021
00022 using namespace std;
00023
00024 namespace seemicro
00025 {
00026
00032 class fileResource
00033 {
00034 int f;
00035
00036 public:
00037
00038 fileResource(const char *n, const int flags)
00039 {
00040 if((f = open(n, flags)) <= 0)
00041 {
00042 std::cerr << '"' << n << "\": "; perror("open");
00043 throw bad_alloc();
00044 }
00045 }
00046
00047 fileResource(int ff) { f=ff; }
00048
00049 ~fileResource() { if(f>=0) close(f); }
00050
00051 operator int() { return f; }
00052 };
00053
00061 struct videoDevice : public ImageSource
00062 {
00064 fileResource video_fd;
00065
00071 struct video_capability capability;
00072 struct video_window win;
00073 struct video_channel vc;
00074 struct video_picture pict;
00075 struct video_mbuf vm;
00076 struct video_mmap mm;
00077 struct video_info vinfo;
00078
00082 unsigned char *pict_buf;
00083
00085 int fmt;
00086
00092 int imgFmt;
00093
00097 int last_VIDIOCMCAPTURE_was_successful;
00098
00100 int framesCaptured;
00101
00103 int keyFrameRate;
00104
00114 bool verbogen;
00115
00120 unsigned char *imageDataOld;
00121
00122
00142 videoDevice(string device="/dev/video0", int imgFmt=VIDEO_PALETTE_GREY, int channel=-1,
00143 unsigned int reqWidth=0, unsigned int reqHeight=0);
00144
00145 ~videoDevice();
00146
00154 int setPicture(int *reqFmt, bool quiet=false);
00155
00160 bool probeFmt(int fmt);
00161
00165 CvSize* size();
00166
00175 int captureFrame(void);
00176
00182 int syncFrame(void);
00183
00189 float framerate(void);
00190
00194 void processKeyFrame(void)
00195 {
00196 processFrame();
00197 }
00198
00199 void processFrame(myrect *AROI=NULL)
00200 {
00201 myrect ROI;
00202 if(AROI) ROI = *AROI;
00203 else ROI=myrect(0, 0, size()->width, size()->height);
00204
00205 if(syncFrame())
00206 {
00207 cerr << "syncFrame(): error\n";
00208 return;
00209 }
00210
00211 if(captureFrame())
00212 {
00213 cerr << "captureFrame(): error\n";
00214
00215 return;
00216 }
00217
00218
00219
00220 if(imgFmt==fmt==VIDEO_PALETTE_GREY || imgFmt==fmt==VIDEO_PALETTE_RGB24 ||
00221 (imgFmt==VIDEO_PALETTE_GREY && fmt==VIDEO_PALETTE_YUV420P))
00222 {
00223
00224
00225
00226
00227
00228
00229
00230
00231 if(!verbogen)
00232 {
00233 assert(img);
00234 imageDataOld = (unsigned char*)img->imageData;
00235 verbogen=true;
00236 }
00237 img->imageData = (char*)pict_buf + vm.offsets[mm.frame];
00238 return;
00239 }
00240
00241 if(imgFmt==VIDEO_PALETTE_RGB24 && fmt==VIDEO_PALETTE_YUV420P)
00242 {
00243
00244
00245 yuv420p_unpack_2_rgb24(pict_buf + vm.offsets[mm.frame],
00246 img->imageData, win.width, win.height);
00247 return;
00248 }
00249
00250 if(imgFmt==VIDEO_PALETTE_GREY && fmt==VIDEO_PALETTE_RGB24)
00251 {
00252
00253 __u32& w = win.width;
00254
00255 for(int y=0; y<ROI.r.height; y++)
00256 {
00257 int line = ROI.r.y + y;
00258 unsigned char *src = pict_buf + vm.offsets[mm.frame] + (line * w + ROI.r.x) * 3;
00259 unsigned char *dst = (unsigned char *)img->imageData + line * img->widthStep + ROI.r.x;
00260 for(int x=0;x<ROI.r.width; x++)
00261 {
00262
00263
00264
00265
00266 *dst++ = (src[0]+src[1]+src[2])/3;
00267 src += 3;
00268 }
00269 }
00270 return;
00271 }
00272
00273 cerr << "Konvertierung nicht unterstützt! Ignoring.\n";
00274 }
00275
00276 };
00277
00278 }
00279
00280 #endif // VIDEODEVICE_H
00281