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

📄 vidcat.c~

📁 在龙芯上使用摄像头 我修改了代码
💻 C~
字号:
/* * vidcat.c * * Copyright (C) 1998 Rasca, Berlin * EMail: thron@gmx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h>#include <linux/types.h>#include <linux/videodev.h>#include <time.h>#ifdef HAVE_LIBZ#include <zlib.h>#endif#undef HAVE_LIBPNG#ifdef HAVE_LIBPNG#include <png.h>#endif///#ifdef HAVE_LIBJPEG#include <jpeglib.h>//#endif#ifdef HAVE_X11#include <X11/Xlib.h>#include <X11/Xutil.h> #include <setjmp.h>#include <X11/keysym.h>int screen;Window xcanvas;int depth;XImage *image;Display *display;GC image_gc;long *buffer_bpp;XImage *xim;XSetWindowAttributes window_attributes;unsigned long window_mask;XSizeHints window_hints;#endif#define DEF_WIDTH	320#define DEF_HEIGHT	240#define FMT_UNKNOWN	0#define FMT_PPM		1#define FMT_PNG		2#define FMT_JPEG	3#define FMT_DEFAULT	2#define FMT_DISPLAY		4#define IN_TV			0#define IN_COMPOSITE	1#define IN_COMPOSITE2	2#define IN_SVIDEO		3#define IN_DEFAULT		8#define NORM_PAL		0#define NORM_NTSC		1#define NORM_SECAM		2#define NORM_DEFAULT	0#define QUAL_DEFAULT	80#define VERSION         "0.1"/* */voidusage (char *pname){	fprintf (stderr,	"VidCat, Version %s\n"	"Usage: %s <options>\n"	" -s NxN                      define size of the output image (default:"		" %dx%d)\n"	" -f {ppm|jpeg|png|display}           output format of the image\n"	" -i {tv|comp1|comp2|s-video} which input channel to use\n"	" -q <quality>                only for jpeg: quality setting (1-100,"		" default: %d)\n"	" -d <device>                 video device (default: "VIDEO_DEV")\n"	" -l                          loop on, doesn't make sense in most cases\n"	" -b                          make a raw PPM instead of an ASCII one\n"	"Example: vidcat | xsetbg stdin\n",		VERSION, basename(pname), DEF_WIDTH, DEF_HEIGHT, QUAL_DEFAULT);	exit (1);}/* * read rgb image from v4l device * return: mmap'ed buffer and size */char *get_image (int dev, int width, int height, int input,int norm,int fmt,int *size){	struct video_capability vid_caps;	struct video_mbuf vid_buf;	struct video_mmap vid_mmap;	struct video_channel vid_chnl;	char *map;	int len;	if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {		perror ("ioctl (VIDIOCGCAP)");		return (NULL);	}	if (input != IN_DEFAULT) {		vid_chnl.channel = -1;		if (ioctl (dev, VIDIOCGCHAN, &vid_chnl) == -1) {			perror ("ioctl (VIDIOCGCHAN)");		} else {			vid_chnl.channel = input;			vid_chnl.norm    = norm;			if (ioctl (dev, VIDIOCSCHAN, &vid_chnl) == -1) {				perror ("ioctl (VIDIOCSCHAN)");				return (NULL);			}		}	}	if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {		/* to do a normal read()		 */	   		map = malloc (width * height * 3);		len = read (dev, map, width * height * 3);		if (len <=  0) {			free (map);			return (NULL);		}		*size = 0;		return (map);	}	map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0);	if ((unsigned char *)-1 == (unsigned char *)map) {		perror ("mmap()");		return (NULL);	}	vid_mmap.format = fmt;	vid_mmap.frame = 0;	vid_mmap.width = width;	vid_mmap.height =height;	if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {		perror ("VIDIOCMCAPTURE");		munmap (map, vid_buf.size);		return (NULL);	}	if (ioctl (dev, VIDIOCSYNC, &vid_mmap) == -1) {		perror ("VIDIOCSYNC");		munmap (map, vid_buf.size);		return (NULL);	}	*size = vid_buf.size;	return (map);}/* */voidput_image_jpeg (char *image, int width, int height, int quality){#ifdef HAVE_LIBJPEG	int y, x, line_width;	JSAMPROW row_ptr[1];	struct jpeg_compress_struct cjpeg;	struct jpeg_error_mgr jerr;	char *line;	FILE *longxin_fd ;		longxin_fd = fopen ("longxin.jpg","w");	if (longxin_fd < 0 ) printf ("Open longxin.jpg error\n");		line = malloc (width * 3);	if (!line)		return;	cjpeg.err = jpeg_std_error(&jerr);	jpeg_create_compress (&cjpeg);	cjpeg.image_width = width;	cjpeg.image_height= height;	cjpeg.input_components = 3;	cjpeg.in_color_space = JCS_RGB;	jpeg_set_defaults (&cjpeg);	jpeg_set_quality (&cjpeg, quality, TRUE);	cjpeg.dct_method = JDCT_FASTEST;//	jpeg_stdio_dest (&cjpeg, stdout);	jpeg_stdio_dest (&cjpeg,longxin_fd);	    	jpeg_start_compress (&cjpeg, TRUE);	row_ptr[0] = line;	line_width = width * 3;	for ( y = 0; y < height; y++) {	for (x = 0; x < line_width; x+=3) {			line[x]   = image[x+2];			line[x+1] = image[x+1];			line[x+2] = image[x];		}		jpeg_write_scanlines (&cjpeg, row_ptr, 1);		image += line_width;	}	jpeg_finish_compress (&cjpeg);	jpeg_destroy_compress (&cjpeg);	free (line);	fclose (longxin_fd);#endif}/* * write png image to stdout */voidput_image_png (char *image, int width, int height){#ifdef HAVE_LIBPNG	int y;	char *p;	png_infop info_ptr;	png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,						NULL, NULL, NULL);	if (!png_ptr)		return;	info_ptr = png_create_info_struct (png_ptr);	if (!info_ptr)		return;	png_init_io (png_ptr, stdout);	png_set_IHDR (png_ptr, info_ptr, width, height,					8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,					PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);	png_set_bgr (png_ptr);	png_write_info (png_ptr, info_ptr);	p = image;	for (y = 0; y < height; y++) {		png_write_row (png_ptr, p);		p+=width*3;	}	png_write_end (png_ptr, info_ptr);#endif}/* * write ppm image to stdout */voidput_image_ppm (char *image, int width, int height, int binary){	int x, y, ls=0;	unsigned char *p = (unsigned char *)image;	if (!binary) {	printf ("P3\n%d %d\n%d\n", width, height, 255);	for (x = 0; x < width; x++) {		for (y = 0; y < height; y++) {			printf ("%03d %03d %03d  ", p[2], p[1], p[0]);			p += 3;			if (ls++ > 4) {				printf ("\n");				ls = 0;			}		}	}	printf ("\n");	} else {		unsigned char buff[3];		printf ("P6\n%d %d\n%d\n", width, height, 255);		for (x = 0; x < width * height; x++) {			buff[0] = p[2];			buff[1] = p[1];			buff[2] = p[0];			fwrite (buff, 1, 3, stdout);			p += 3;		}	}	fflush (stdout);}static voidconverter_color24to16(unsigned char * src_buf,int count){               	int i,j;	unsigned short color;	unsigned char red,green,blue;        // BGR ,no RGB	for ( i = 0 ,j=0 ; i<count; i += 3 ){        	red   = (src_buf[i +2]   * 0x1f ) / 0xff;       	        green = (src_buf[i + 1 ] * 0x3f ) / 0xff;        	blue  = (src_buf[i ]     * 0x1f ) / 0xff;        	color = (red << 11) | (green << 5) | blue;		color = color & 0xffff;		        src_buf [ j  ] = color & 0xff;		src_buf [j  +1 ] = (color >> 8 ) & 0xff ;		j += 2 ;	}}/* * write image to display */voidput_image_display (char *image, int width, int height){#ifdef HAVE_X11        static int have_display = 0;        int x, y, ls=0;	unsigned char *p = (unsigned char *)image;	if (depth == 16 ){	    	    converter_color24to16 (image,width * height * 3);	    memcpy (buffer_bpp,image,width * height *2);	    	} else if (depth == 24) {	    	   memcpy (buffer_bpp,image,width * height * 3);	} else {	    printf("Don't support %d bits color display !\n",depth);	}		if (!have_display){	    while (1) {	    		XEvent x_event;		XNextEvent(display, &x_event);				switch  (x_event.type) 		{		    		case Expose:		    		    XPutImage (display, xcanvas, image_gc, xim, 0, 0, \			       0, 0, width, height);		    		    XFlush(display);		    have_display = 1;    		    break;            		case KeyPress:		    if(XLookupKeysym(&x_event.xkey, 0) == XK_q)		    {			exit (0);		    }		    		    break;		}				return ;	    }	} else {	    XPutImage (display, xcanvas, image_gc, xim, 0, 0, \		       0, 0, width, height);	    	    XFlush(display);	    	}		#endif}void display_init (){#ifdef HAVE_X11    display = XOpenDisplay(NULL);    screen = DefaultScreen (display);    depth = DefaultDepth (display, screen);    window_attributes.border_pixel = BlackPixel (display, screen);    window_attributes.background_pixel = BlackPixel (display, screen);    window_attributes.override_redirect = 0;    window_mask = CWBackPixel | CWBorderPixel;    xcanvas = XCreateWindow (display, DefaultRootWindow (display), 0, 0, \			     DEF_WIDTH, DEF_HEIGHT, 0, depth, InputOutput, CopyFromParent, window_mask, \			     &window_attributes);     buffer_bpp = malloc ( DEF_WIDTH *  DEF_HEIGHT * depth / 8 );    xim = XCreateImage (display, CopyFromParent, depth, ZPixmap, 0,			(char *) buffer_bpp, DEF_WIDTH,			  DEF_HEIGHT , depth , DEF_WIDTH * depth / 8 );    image_gc = XCreateGC (display, xcanvas, 0, 0);            XMapWindow (display, xcanvas);        XSelectInput(display, xcanvas, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask);#endif /* HAVE_X11 */    }/* * main() */intmain (int argc, char *argv[]){	int width = DEF_WIDTH, height = DEF_HEIGHT, size, dev = -1, c;	char *image, *device = "/dev/video_capture";	int max_try = 5;	/* we try 5 seconds/times to open the device */	int quality = QUAL_DEFAULT;	/* default jpeg quality setting */	int input = IN_DEFAULT;	int norm  = NORM_DEFAULT;	int palette = VIDEO_PALETTE_RGB24;	int loop =0 ;	int binary = 0;	long secstart, secend, frame;	#ifdef HAVE_LIBJPEG	int format = FMT_JPEG;#else#ifdef HAVE_LIBPNG	int format = FMT_PNG;#else	int format = FMT_PPM;#endif#endif		while ((c = getopt (argc, argv, "bs:f:q:i:d:l")) != EOF) {		switch (c) {			case 'b':				binary = 1;				break;			case 'd':				device = optarg;				break;			case 's':				sscanf (optarg, "%dx%d", &width, &height);				break;			case 'f':			        if (strcasecmp ("display", optarg) == 0)					format = FMT_DISPLAY;				else if (strcasecmp ("ppm", optarg) == 0)					format = FMT_PPM;				else if (strcasecmp ("png", optarg) == 0)					format = FMT_PNG;				else if (strcasecmp ("jpeg", optarg) == 0)					format = FMT_JPEG;				else					format = FMT_UNKNOWN;				break;			case 'q':				sscanf (optarg, "%d", &quality);				break;			case 'i':				if (strcasecmp ("tv", optarg) == 0) {					input = IN_TV;				} else if (strcasecmp ("comp1", optarg) == 0) {					input = IN_COMPOSITE;				} else if (strcasecmp ("comp2", optarg) ==0) {					input = IN_COMPOSITE2;				} else if (strcasecmp ("s-video", optarg) == 0) {					input = IN_SVIDEO;				}				break;			case 'l':				loop = 1;				break;			default:				usage (argv[0]);				break;		}	}	    /* open the video4linux device */	    while (max_try) {		dev = open("/dev/video_capture", O_RDWR);		if (dev == -1) {		    if (!--max_try) {			fprintf (stderr, "Can't open device %s\n", VIDEO_DEV);			exit (0);		    }		    sleep (1);		} else {		    break;		}	    }	display_init ();	secstart = secend = frame = 0;        time (&secstart);	while (1){	    	    if (frame == 50){		time (&secend);		printf ("It takes %d second(s) at 50 frame, %d frame/second!\n",secend - secstart, frame /(secend -secstart));		secstart = secend = frame = 0;		time (&secstart);	    }	  	    frame ++;	    image = get_image (dev, width, height, input, norm, palette, &size);	    if (image) {		switch (format) {		case FMT_PPM:		    put_image_ppm (image, width, height, binary);		    break;		case FMT_DISPLAY:		    put_image_display (image, width, height );			    break;		case FMT_PNG:		    put_image_png (image, width, height);		    break;		case FMT_JPEG:		    put_image_display (image, width, height);		    put_image_jpeg (image, width, height, quality);		    break;		default:		    fprintf (stderr, "Unknown format (%d)\n", format);		    break;		}			if (size)		    munmap (image, size);		else if (image)		    free (image);	    } else {		fprintf (stderr, "Error: Can't get image\n");	    }	}	close (dev);	return (0);		}

⌨️ 快捷键说明

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