⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grabber-video4linux.cpp

📁 Linux support for Philips USB webcams halted Latest version: pwc-9.0.2.tar.gz (including documents
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* =========================================================================     Copyright (c) 1997 Regents of Koji OKAMURA, oka@kobe-u.ac.jp     All rights reserved.     largely rewritten for new bttv/video4linux interface     by Gerd Knorr <kraxel@cs.tu-berlin.de>     Added brightness, contrast, hue and saturation controls.     by Jean-Marc Orliaguet <jmo@medialab.chalmers.se>     Added support for various YUV byte orders.     by Jean-Marc Orliaguet <jmo@medialab.chalmers.se>     Added support for NTSC/PAL/SECAM video norm selection. (14/10/99)     by Jean-Marc Orliaguet <jmo@medialab.chalmers.se>   ========================================================================= */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <errno.h>#include <sys/types.h>#include <sys/fcntl.h>  #include <sys/ioctl.h>#include <sys/time.h>#include <sys/mman.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/keysym.h>extern "C" {#include <asm/types.h>#include <linux/videodev.h>}#include "grabber.h"#include "vic_tcl.h"#include "device-input.h"#include "module.h"/* here you can tune the device names */static const char *devlist[] = {    "/dev/video0", "/dev/video1", "/dev/video2", "/dev/video3",    NULL};#define DEBUG(x)//#define DEBUG(x) (x)#define NTSC_WIDTH  640#define NTSC_HEIGHT 480#define PAL_WIDTH   768#define PAL_HEIGHT  576#define CIF_WIDTH   352#define CIF_HEIGHT  288/* pass 0/1 by reference */static const int  one = 1, zero = 0;#define CF_422 0#define CF_411 1#define CF_CIF 2/* YUV Byte order */#define BYTE_ORDER_YUYV 0#define BYTE_ORDER_YVYU 1#define BYTE_ORDER_UYVY 2#define BYTE_ORDER_VYUY 3/* VIDEO NORMS */#define MAX_NORMS 4class V4lGrabber : public Grabber {public:    V4lGrabber(const char * cformat, const char *dev);    virtual ~V4lGrabber();    virtual int  command(int argc, const char*const* argv);    virtual void start();    virtual void stop();    virtual int  grab();protected:    void format();    void setsize();    void packed422_to_planar422(char *, char*);    void packed422_to_planar411(char *, char*);    void vcvt_420p_422p(int width, int height, void *src, void *dst);    void vcvt_420p_411p(int width, int height, void *src, void *dst);    void vcvt_420i_yuyv(int width, int height, int plus, void *src, void *dst);    struct video_capability  capability;    struct video_channel     *channels;    struct video_picture     pict;    struct video_window      win;    /* mmap */    int                      have_mmap;    int                      grab_count;    int                      sync_count;    struct video_mmap        gb_even;    struct video_mmap        gb_odd;    struct video_mbuf        gb_buffers;    char                     *mem;    int fd_;    int format_;    int have_422P;    int have_422;    int have_420P;    int v4lformat_;    int byteorder_;    int cformat_;    int port_;    int norm_;        unsigned char *tm_;    int width_;    int height_;    int max_width_;    int max_height_;    int decimate_;};/* ----------------------------------------------------------------- */class V4lDevice : public InputDevice {public:    V4lDevice(const char *dev, const char*, char *attr);    virtual int command(int argc, const char*const* argv);private:    const char *dev_;};V4lDevice::V4lDevice(const char *dev, const char *name, char *attr) : InputDevice(name){    dev_ = dev;    attributes_ = attr;    fprintf(stderr,"V4l:  ==> %s\n",attr);}int V4lDevice::command(int argc, const char*const* argv){    Tcl& tcl = Tcl::instance();    if (argc == 3) {	if (strcmp(argv[1], "open") == 0) {	    TclObject* o = 0;	    o = new V4lGrabber(argv[2],dev_);	    if (o != 0)		tcl.result(o->name());	    return (TCL_OK);	}    }    return (InputDevice::command(argc, argv));}/* ----------------------------------------------------------------- */class V4lScanner {public:    V4lScanner(const char **dev);};static V4lScanner find_video4linux_devices(devlist);V4lScanner::V4lScanner(const char **dev){    static const char *palette_name[] = {	"", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", 	"yuv422", "yuyv422", "uyvy422", "yuv420", "yuv411", "RAW", "yuv422P", "yuv411P", "yuv420P", "yuv410P" };        struct video_capability  capability;    struct video_channel     channel;    struct video_picture     pict;    int  j,i,fd;    char *nick, *attr;    for (i = 0; dev[i] != NULL; i++) {	fprintf(stderr,"V4l: trying %s... ",dev[i]);	if (-1 == (fd = open(dev[i],O_RDONLY))) {	    perror("open");	    continue;	}	if (-1 == ioctl(fd,VIDIOCGCAP,&capability)) {	    perror("ioctl VIDIOCGCAP");	    close(fd);	    continue;	}	if (!(capability.type & VID_TYPE_CAPTURE)) {	    fprintf(stderr,"device can't capture\n");	    close(fd);	    continue;	}	fprintf(stderr,"ok, %s\nV4l:   %s; size: %dx%d => %dx%d%s\n",		capability.name,		capability.type & VID_TYPE_MONOCHROME ? "mono" : "color",		capability.minwidth,capability.minheight,		capability.maxwidth,capability.maxheight,		capability.type & VID_TYPE_SCALES ? " (scales)" : "");	attr = new char[512];	strcpy(attr,"format { 411 422 cif } ");        if (capability.maxwidth  > PAL_WIDTH/2 &&	    capability.maxheight > PAL_HEIGHT/2) {	    strcat(attr,"size { small large cif } ");	} else {	    strcat(attr,"size { small cif } ");	}		fprintf(stderr,"V4l:   ports:");	strcat(attr,"port { ");	for (j = 0; j < capability.channels; j++) {	    channel.channel = j;	    if (-1 == ioctl(fd,VIDIOCGCHAN,&channel)) {		perror("ioctl VIDIOCGCHAN");	    } else {		fprintf(stderr," %s",channel.name);		strcat(attr,channel.name);		strcat(attr," ");	    }	}	fprintf(stderr,"\n");	strcat(attr,"} ");	if (-1 == ioctl(fd,VIDIOCGPICT,&pict)) {	    perror("ioctl VIDIOCGPICT");	}	fprintf(stderr,"V4l:   depth=%d, palette=%s\n",		pict.depth,(pict.palette<sizeof(palette_name)/sizeof(char*))?		palette_name[pict.palette]:"??");	strcat(attr,"type {auto pal ntsc secam}");	nick = new char[strlen(capability.name)+6];	sprintf(nick,"v4l- %s",capability.name);	new V4lDevice(dev[i],nick,attr);	close(fd);    }}/* ----------------------------------------------------------------- */V4lGrabber::V4lGrabber(const char *cformat, const char *dev){    int i;    struct video_mmap 	     vid_mmap;    have_mmap = 0;    have_422P = 0;    have_422  = 0;    have_420P = 0;    printf("Videodev: %s\n", dev);    printf("Cformat: %s\n", cformat);    fd_ = open(dev, O_RDWR);    if (fd_ < 0) {	perror("open");	exit(1);    }    vid_mmap.format = VIDEO_PALETTE_YUV420P;    vid_mmap.frame = 0;    vid_mmap.width = PAL_WIDTH;    vid_mmap.height = PAL_HEIGHT;        if (-1 != ioctl(fd_, VIDIOCMCAPTURE, &vid_mmap)) {      have_422P = 0;      have_422 = 0;      have_420P = 1;      printf("Device capture VIDEO_PALETTE_YUV420P\n");    }    vid_mmap.format = VIDEO_PALETTE_YUV422;    vid_mmap.frame = 0;    vid_mmap.width = PAL_WIDTH;    vid_mmap.height = PAL_HEIGHT;        if (-1 != ioctl(fd_, VIDIOCMCAPTURE, &vid_mmap)) {      have_422P = 0;      have_422 = 1;      printf("Device capture VIDEO_PALETTE_YUV422\n");    }    vid_mmap.format = VIDEO_PALETTE_YUV422P;    vid_mmap.frame = 0;    vid_mmap.width = PAL_WIDTH;    vid_mmap.height = PAL_HEIGHT;    if (-1 != ioctl(fd_, VIDIOCMCAPTURE, &vid_mmap)) {           have_422P = 1;	   printf("Device capture VIDEO_PALETTE_YUV422P\n");    }    if( !( have_422P || have_422 || have_420P))   {      fprintf(stderr,"No suituable palette found\n");      exit(1);    }    /* Release device */    close(fd_);    fd_ = open(dev, O_RDWR);    if (fd_ < 0) {	perror("open");	exit(1);    }    /* ask for capabilities */    if (-1 == ioctl(fd_,VIDIOCGCAP,&capability)) {	perror("ioctl VIDIOCGCAP");	exit(1);    }    channels = (struct video_channel*)	calloc(capability.channels,sizeof(struct video_channel));    for (i = 0; i < capability.channels; i++) {	channels[i].channel = i;	if (-1 == ioctl(fd_,VIDIOCGCHAN,&channels[i])) {	    perror("ioctl VIDIOCGCHAN");	}    }    if (-1 == ioctl(fd_,VIDIOCGPICT,&pict)) {	perror("ioctl VIDIOCGPICT");    }    /* map grab buffer */    gb_buffers.size = 2*0x151000;    gb_buffers.offsets[0] = 0;    gb_buffers.offsets[1] = 0x151000;    if (-1 == ioctl(fd_,VIDIOCGMBUF,&gb_buffers)) {	perror("ioctl VIDIOCGMBUF");    }    mem = (char *)mmap(0,gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd_,0);    if ((char*)-1 == mem) {	perror("mmap");	fprintf(stderr,"V4l: device has no mmap support\n");    } else {	fprintf(stderr,"v4l: mmap()'ed buffer size = 0x%x\n",		gb_buffers.size);	have_mmap = 1;    }        /* fill in defaults */    if(!strcmp(cformat, "411"))	cformat_ = CF_411;    if(!strcmp(cformat, "422"))	cformat_ = CF_422;    if(!strcmp(cformat, "cif"))	cformat_ = CF_CIF;        port_      = 0;    norm_      = 0;    decimate_  = 2;}V4lGrabber::~V4lGrabber(){    DEBUG(fprintf(stderr,"V4l: destructor\n"));    if (have_mmap)	munmap(mem,gb_buffers.size);    close(fd_);}int V4lGrabber::command(int argc, const char*const* argv){    int i;    struct video_channel     channel;    static const char *norms[] = {"pal", "ntsc", "secam", "auto"};    Tcl &tcl = Tcl::instance();    byteorder_ = 0;    if ( tcl.attr("yuv_byteOrder") != NULL ) 	byteorder_ = atoi( tcl.attr("yuv_byteOrder") );    if ( ! ((byteorder_ >= 0) && (byteorder_ <= 3)) ) byteorder_=0;    if (argc == 3) {	if (strcmp(argv[1], "decimate") == 0) {	    decimate_ = atoi(argv[2]);	    if (running_)		format();	}	if (strcmp(argv[1], "port") == 0) {	    for (i = 0; i < capability.channels; i++)		if(!strcmp(argv[2], channels[i].name)) {		    port_ = i;	    }	    if (running_)		format();    	    return (TCL_OK);	}        if (strcmp(argv[1], "brightness") == 0) {                        u_char val = atoi(argv[2]);					pict.brightness=val*256;			    			if (-1 == ioctl(fd_,VIDIOCSPICT,&pict))        		perror("ioctl VIDIOCSPICT");                        DEBUG(fprintf(stderr, "V4l: Brightness = %d\n", val));                        return (TCL_OK);        }        if (strcmp(argv[1], "contrast") == 0) {                        u_char val = atoi(argv[2]);						pict.contrast=val*256;    			if (-1 == ioctl(fd_,VIDIOCSPICT,&pict))        		perror("ioctl VIDIOCSPICT");                        DEBUG(fprintf(stderr, "V4l: Contrast = %d\n", val));                        return (TCL_OK);        }        if (strcmp(argv[1], "hue") == 0) {                        u_char val = atoi(argv[2]);						pict.hue=val*256;    			if (-1 == ioctl(fd_,VIDIOCSPICT,&pict))        		perror("ioctl VIDIOCSPICT");                        DEBUG(fprintf(stderr, "V4l: Hue = %d\n", val));                        return (TCL_OK);        }        if (strcmp(argv[1], "saturation") == 0) {                        u_char val = atoi(argv[2]);                        pict.colour=val*256;    			if (-1 == ioctl(fd_,VIDIOCSPICT,&pict))        		perror("ioctl VIDIOCSPICT");                        DEBUG(fprintf(stderr, "V4l: Saturation = %d\n", val));                        return (TCL_OK);        }	if (strcmp(argv[1], "controls") == 0) {		if (strcmp(argv[2], "reset") == 0) {			pict.brightness=32768;			pict.contrast=32768;			pict.colour=32768;			pict.hue=32768;                        if (-1 == ioctl(fd_,VIDIOCSPICT,&pict))                        perror("ioctl VIDIOCSPICT");                        DEBUG(fprintf(stderr, "V4l: Resetting controls\n"));                        return (TCL_OK);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -