00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <fcntl.h>
00023 #include <unistd.h>
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026
00027 #include <sys/stat.h>
00028 #include <sys/ioctl.h>
00029 #include <sys/mman.h>
00030
00031 #include "ccvt/conv.h"
00032 #include "pwc-ioctl.h"
00033
00034 #include "Video4LinuxSource.h"
00035
00036 #include <string.h>
00037
00038 Video4LinuxSource::Video4LinuxSource(char* device, bool sup_memory_map)
00045 {
00046 video_capability cap;
00047 video_picture grab_pic ;
00048
00049 capture = sup_memory_map ;
00050
00051 get_capability(cap);
00052
00053 if(capture){
00054
00055
00056 if ((fd = open("/dev/video0",O_RDWR)) == -1 ) {
00057 exit(1);
00058 }
00059
00060 if (ioctl(fd,VIDIOCGCAP,&cap) == -1) {
00061 fprintf(stderr,"wrong device\n");
00062 exit(1);
00063 }
00064 memset (&grab_pic, 0, sizeof(struct video_picture));
00065 if (ioctl (fd, VIDIOCGPICT, &grab_pic) == -1) {
00066 fprintf (stderr, "no pict");
00067 exit(1);
00068 }
00069
00070 get_size(width,height);
00071
00072 vmmap.frame = 0 ;
00073 vmmap.width = width ;
00074 vmmap.height = height ;
00075 vmmap.format = VIDEO_PALETTE_RGB24;
00076 size = vmmap.width * vmmap.height * (24/8) ;
00077
00078 buff = (unsigned char *)mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,
00079 fd,0);
00080
00081 convert_rgb = conv_bgr24_rgb96;
00082 convert_grey = conv_rgb24_grey;
00083 }
00084 else{
00085
00086
00087
00088 fd = open(device, O_RDWR);
00089 if (fd == -1)
00090 throw "error opening device";
00091
00092
00093 get_size(width,height);
00094 size = width * height;
00095
00096 buffsize = int(size * 1.5 + 0.5);
00097 buff = new (unsigned char)[buffsize];
00098
00099
00100 get_palette(palette);
00101 set_palette(palette);
00102
00103 }
00104
00105
00106 type = Image::COLOUR;
00107 }
00108
00109
00110 Video4LinuxSource::~Video4LinuxSource()
00115 {
00116
00117 if (capture)
00118 munmap(buff, buffsize);
00119
00120
00121 delete [] buff;
00122
00123 close(fd);
00124 }
00125
00126
00127 void Video4LinuxSource::set_size(unsigned int w, unsigned int h)
00140 {
00141 video_window win;
00142
00143
00144 get_captureWindows(win);
00145
00146 win.width = w;
00147 win.height = h;
00148
00149 set_captureWindows(win);
00150 get_captureWindows(win);
00151
00152
00153 if(capture){
00154
00155 width = w; height = h;
00156
00157 vmmap.width = width ;
00158 vmmap.height = height ;
00159 vmmap.format = VIDEO_PALETTE_RGB24;
00160 size = vmmap.width * vmmap.height * (24/8) ;
00161
00162 ioctl(fd,VIDIOCGMBUF,&mbuf) ;
00163
00164
00165 buff = (unsigned char *)mmap(0,mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,
00166 fd,0);
00167
00168 }
00169 else if(width !=win.width || height != win.height){
00170 width = w; height = h;
00171
00172 delete [] buff;
00173
00174 size = win.width * win.height;
00175 buffsize = int(size * 1.5 + 0.5);
00176 buff = new (unsigned char)[buffsize];
00177 cerr << "size: " << size << endl;
00178 cerr << "buffsize: " << buffsize << endl;
00179 }
00180 }
00181
00182
00183 void Video4LinuxSource::set_framerate(unsigned int fps)
00195 {
00196 video_window win;
00197
00198
00199 get_captureWindows(win);
00200
00201 win.flags &= ~PWC_FPS_FRMASK;
00202 win.flags |= (fps << PWC_FPS_SHIFT);
00203
00204 set_captureWindows(win);
00205 }
00206
00207
00208 void Video4LinuxSource::set_palette(int pal)
00220 {
00221 video_picture pic;
00222
00223
00224 get_imageProperties(pic);
00225
00226 pic.palette = pal;
00227
00228 pic.depth = 24 ;
00229
00230 set_imageProperties(pic);
00231 get_imageProperties(pic);
00232
00233 cerr << "Setting pallette " << pal << " " << pic.palette << " " << pic.depth << endl ;
00234
00235
00236 switch (pic.palette) {
00237 case VIDEO_PALETTE_RGB32:
00238 convert_rgb = conv_rgb32_rgb96;
00239 convert_grey = conv_rgb32_grey;
00240 break;
00241 case VIDEO_PALETTE_YUV420P:
00242 default:
00243 convert_rgb = conv_420p_rgb96;
00244 convert_grey = conv_420p_grey;
00245 break;
00246 };
00247 }
00248
00249
00250 void Video4LinuxSource::set_channel(int channel)
00257 {
00258 set_videoSource(channel);
00259 }
00260
00261
00262 void Video4LinuxSource::get_size(unsigned int& w, unsigned int& h)
00263 {
00264 if(capture){
00265 w = width ;
00266 h = height ;
00267 }
00268 else{
00269 video_window win;
00270 get_captureWindows(win);
00271
00272 w = win.width;
00273 h = win.height;
00274 }
00275 }
00276
00277
00278 void Video4LinuxSource::get_framerate(unsigned int& fps)
00279 {
00280 video_window win;
00281 get_captureWindows(win);
00282 fps = (win.flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
00283 }
00284
00285
00286 void Video4LinuxSource::get_palette(int& pal)
00287 {
00288 video_picture pic;
00289 get_imageProperties(pic);
00290 pal = pic.palette;
00291 }
00292
00293
00294 ImageSource& Video4LinuxSource::operator >> (ImageRGB& img)
00295 {
00296 unsigned char* src = buff;
00297
00298 if (capture) {
00299
00300 ioctl(fd,VIDIOCMCAPTURE,&vmmap) ;
00301 src += mbuf.offsets[currentBuffer];
00302
00303 if(!currentBuffer) currentBuffer++ ;
00304 else currentBuffer=0 ;
00305
00306 vmmap.frame = currentBuffer ;
00307 }
00308 else{
00309 read(fd, src, buffsize);
00310 }
00311
00312 convert_rgb(width, height, src, (int *)img.data);
00313
00314 if(capture){
00315
00316 ioctl(fd,VIDIOCSYNC,¤tBuffer) ;
00317 }
00318
00319 return *this;
00320 }
00321
00322
00323 ImageSource& Video4LinuxSource::operator >> (ImageGrey& img)
00324 {
00325 unsigned char* src = buff;
00326
00327 if (capture) {
00328 ioctl(fd,VIDIOCMCAPTURE,&vmmap) ;
00329 src += mbuf.offsets[currentBuffer];
00330
00331 if(!currentBuffer) currentBuffer++ ;
00332 else currentBuffer=0 ;
00333
00334 vmmap.frame = currentBuffer ;
00335 } else
00336 read(fd, src, buffsize);
00337
00338 convert_grey(width, height, src, img.brightness);
00339
00340 if(capture){
00341
00342 ioctl(fd,VIDIOCSYNC,¤tBuffer) ;
00343 }
00344
00345
00346 return *this;
00347 }
00348
00349
00350 ImageSource& Video4LinuxSource::operator >> (Image& img)
00351 {
00352 unsigned char* src = buff;
00353
00354 if (capture) {
00355 ioctl(fd,VIDIOCMCAPTURE,&vmmap) ;
00356 src += mbuf.offsets[currentBuffer];
00357
00358 if(!currentBuffer) currentBuffer++ ;
00359 else currentBuffer=0 ;
00360
00361 vmmap.frame = currentBuffer ;
00362
00363 } else
00364 read(fd, src, buffsize);
00365
00366 if (type == Image::COLOUR)
00367 convert_rgb(width, height, src, img.data[0]);
00368 else {
00369 convert_grey(width, height, src, img.brightness);
00370 }
00371
00372 if(capture){
00373
00374 ioctl(fd,VIDIOCSYNC,¤tBuffer) ;
00375 }
00376
00377
00378 return *this;
00379 }
00380
00381
00382
00383 int Video4LinuxSource::set_frameBuffer(video_buffer& fbuf)
00385 { return ioctl(fd, VIDIOCSFBUF, &fbuf); }
00386
00387 int Video4LinuxSource::set_captureWindows(video_window& win)
00389 { return ioctl(fd, VIDIOCSWIN, &win); }
00390
00391 int Video4LinuxSource::set_videoSource(int chan)
00393 { return ioctl(fd, VIDIOCSCHAN, chan); }
00394
00395 int Video4LinuxSource::set_imageProperties(video_picture& pic)
00397 { return ioctl(fd, VIDIOCSPICT, &pic); }
00398
00399 int Video4LinuxSource::set_tuning(video_tuner& tuner)
00401 { return ioctl(fd, VIDIOCSTUNER, &tuner); }
00402
00403
00404
00405
00406 int Video4LinuxSource::get_capability(video_capability& cap)
00408 { return ioctl(fd, VIDIOCGCAP, &cap); }
00409
00410 int Video4LinuxSource::get_frameBuffer(video_buffer& fbuf)
00412 { return ioctl(fd, VIDIOCGFBUF, &fbuf); }
00413
00414 int Video4LinuxSource::get_captureWindows(video_window& win)
00416 { return ioctl(fd, VIDIOCGWIN, &win); }
00417
00418 int Video4LinuxSource::get_videoSource(video_channel& chan)
00420 { return ioctl(fd, VIDIOCGCHAN, &chan); }
00421
00422 int Video4LinuxSource::get_imageProperties(video_picture& pic)
00424 { return ioctl(fd, VIDIOCGPICT, &pic); }
00425
00426 int Video4LinuxSource::get_tuning(video_tuner& tuner)
00428 { return ioctl(fd, VIDIOCGTUNER, &tuner); }
00429
00430 int Video4LinuxSource::get_memoryBuffer(video_mbuf& mbuf)
00432 { return ioctl(fd, VIDIOCGMBUF, &mbuf); }
00433
00434
00435
00436
00437 void Video4LinuxSource::print_capability(video_capability& cap)
00438 {
00439 cerr << "name: " << cap.name << endl;
00440
00441 cerr << " [ can capture to memory:\t\t\t| "
00442 << ((cap.type & VID_TYPE_CAPTURE)? "X" : " ") << " ]" << endl;
00443 cerr << " [ has a tuner of some form:\t\t\t| "
00444 << ((cap.type & VID_TYPE_TUNER)? "X" : " ") << " ]" << endl;
00445 cerr << " [ has teletext capability:\t\t\t| "
00446 << ((cap.type & VID_TYPE_TELETEXT)? "X" : " ") << " ]" << endl;
00447 cerr << " [ can overlay images onto frame buffer:\t| "
00448 << ((cap.type & VID_TYPE_OVERLAY)? "X" : " ") << " ]" << endl;
00449 cerr << " [ overlay is chromakeyed:\t\t\t| "
00450 << ((cap.type & VID_TYPE_CHROMAKEY)? "X" : " ") << " ]" << endl;
00451 cerr << " [ overlay clipping is supported:\t\t| "
00452 << ((cap.type & VID_TYPE_CLIPPING)? "X" : " ") << " ]" << endl;
00453 cerr << " [ overlay overwrites frame buffer memory:\t| "
00454 << ((cap.type & VID_TYPE_FRAMERAM)? "X" : " ") << " ]" << endl;
00455 cerr << " [ hardware supports image scaling:\t\t| "
00456 << ((cap.type & VID_TYPE_SCALES)? "X" : " ") << " ]" << endl;
00457 cerr << " [ image capture is greyscale only:\t\t| "
00458 << ((cap.type & VID_TYPE_MONOCHROME)? "X" : " ") << " ]" << endl;
00459 cerr << " [ capture can be of only part of the image:\t| "
00460 << ((cap.type & VID_TYPE_SUBCAPTURE)? "X" : " ") << " ]" << endl;
00461
00462 cerr << "channels: " << cap.channels << endl;
00463 cerr << "audios: " << cap.channels << endl;
00464 cerr << "maxwidth: " << cap.maxwidth << endl;
00465 cerr << "maxheight: " << cap.maxheight << endl;
00466 cerr << "minwidth: " << cap.minwidth << endl;
00467 cerr << "minheight: " << cap.minheight << endl;
00468 }
00469
00470
00471 void Video4LinuxSource::print_captureWindows(video_window& win)
00472 {
00473 cerr << "x co-ord: " << win.x << endl;
00474 cerr << "y co-ord: " << win.y << endl;
00475 cerr << "width: " << win.width << endl;
00476 cerr << "height: " << win.height << endl;
00477 cerr << "chromakey: " << win.chromakey << endl;
00478 __u32 mask = 0x1 << sizeof(mask)*8 - 1;
00479 cerr << "flags: ";
00480 for (unsigned int b = 0; b < sizeof(mask)*8; b++, mask >>= 1)
00481 cerr << (win.flags & mask ? "1" : "0");
00482 cerr << endl;
00483 }
00484
00485
00486 void Video4LinuxSource::print_videoSource(video_channel& chan)
00487 {
00488 cerr << "number: " << chan.channel << endl;
00489 cerr << "name: " << chan.name << endl;
00490 cerr << "tuners: " << chan.tuners << endl;
00491 cerr << "flags: " << endl;
00492 cerr << " [ channel has tuners:\t\t\t| "
00493 << ((chan.flags & VIDEO_VC_TUNER)? "X" : " ") << " ]" << endl;
00494 cerr << " [ channel has audio:\t\t\t| "
00495 << ((chan.flags & VIDEO_VC_AUDIO)? "X" : " ") << " ]" << endl;
00496
00497
00498
00499 cerr << "type: " << endl;
00500 cerr << " [ input is a tv input:\t\t\t| "
00501 << ((chan.flags & VIDEO_TYPE_TV)? "X" : " ") << " ]" << endl;
00502 cerr << " [ input is a camera:\t\t\t| "
00503 << ((chan.flags & VIDEO_TYPE_CAMERA)? "X" : " ") << " ]" << endl;
00504 cerr << "norm: " << chan.norm << endl;
00505 }
00506
00507
00508 void Video4LinuxSource::print_memoryBuffer(video_mbuf& mbuf)
00509 {
00510 cerr << "size: " << mbuf.size << endl;
00511 cerr << "frames: " << mbuf.frames << endl;
00512 cerr << "offset: " << mbuf.offsets[1] << endl;
00513 }
00514