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

📄 video_test.c

📁 LINUX下使用ZC0301摄像头的基于v4l1的视频采集程序
💻 C
字号:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <linux/types.h> 
#include <linux/videodev.h>
#include <errno.h>
#include <time.h>
#include <gtk/gtk.h>

#define VIDEO_PALETTE_JPEG 21
#define COLS      320
#define ROWS      240

int cam,size,i,frame,jpeg_size;
struct video_capability cap;
struct video_picture pic;
struct video_window win;
struct video_capture vicap;
struct video_channel vidcan;
struct video_mbuf vidbuf;
struct video_buffer buffer;
struct video_mmap mapbuf;
guchar *bigbuf;
guchar *buf;



GtkWidget *window, *darea;GdkPixbuf* pixbuf;
//on_darea_expose (GtkWidget *widget);
void draw(GtkWidget *widget);void display(window,darea);int get_jpegsize (unsigned char *buf, int insize);
int main (int argc, char *argv[])
{
//-------------------------------------------------------------------
              /* OPEN VIDEO DEVICE */
//-------------------------------------------------------------------		size = (320*240)>>2;
	cam = open("/dev/video0", O_RDWR );
	if (cam<0){printf("ERROR: THERE IS NO CAMERA CONECTED\n");
		exit(-1);}
//--------------------------------------------------------------------
		/* VIDEO CAPABILITIES*/
//---------------------------------------------------------------------
	if (-1==ioctl(cam,VIDIOCGCAP,&cap)){perror("ioctl VIDIOCGCAP");
		exit(-1);}
	printf("------------------------------------\n");
	printf("------------------------------------\n");
	printf("name hola-> %s\n", cap.name);
	printf("type -> %d\n", cap.type);
	printf("channels -> %d\n", cap.channels);
	printf("audios -> %d\n", cap.audios );
	printf("maxwidth -> %d\n", cap.maxwidth );
	printf("maxheight -> %d\n", cap.maxheight);
	printf("minwidth -> %d\n", cap.minwidth );
	printf("minheight -> %d\n", cap.minheight );
	printf("------------------------------------\n");//---------------------------------------------------------------------
	ioctl( cam, VIDIOCGPICT, &pic );
	printf("------------------------------------\n");
	printf("brightness -> %d \n", pic.brightness/256 );
	printf("hue -> %d\n", pic.hue/256);
	printf("colour -> %d\n", pic.colour/256 );
	printf("contrast -> %d \n", pic.contrast/256 );
	printf("whiteness -> %d\n", pic.whiteness/256 );
	printf("depth -> %d\n", pic.depth );
	printf("palette -> %d \n", pic.palette );
	printf("------------------------------------\n");

//-----------------------------------------------------------------------
		/* MAPPING BUFFER */
//------------------------------------------------------------------------
	mapbuf.width = COLS;//初始化过程,对mmap结构赋初值	mapbuf.height = ROWS;	mapbuf.format = VIDEO_PALETTE_JPEG;//设置图像格式
	if (-1==ioctl(cam,VIDIOCGMBUF,&vidbuf)){perror("ioctl VIDIOCGMBUF"); 
		exit(-1);}
	printf("------------------------------------\n");
	printf("size  -> %d\n",vidbuf.size);
	printf("frames -> %d\n",vidbuf.frames);
	printf("offsets -> %d\n",vidbuf.offsets);
	printf("------------------------------------\n");
	bigbuf = (char *)mmap(0,vidbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, cam, 0);
//------------------------------------------------------------------------------
		/* CREATE DISPLAY WINDOWS AND IMAGE AREA */
//------------------------------------------------------------------------------

	gtk_init (&argc, &argv);							// Initialize GTK functions.
	gdk_init (&argc, &argv);							// Initialize GDK functions.
	gdk_rgb_init();									// Initialize GDK_RGB functions.
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);					// Create windows.
	darea = gtk_drawing_area_new();							// Create Image area.			 					
//----------------------------------------------------------------------
		    /* SET BUFFERS*/
//----------------------------------------------------------------------		 

	for(frame=0; frame<vidbuf.frames;frame++){					// turn on both of the buffers
		mapbuf.frame = frame;							// to start capture process.
		if (ioctl(cam,VIDIOCMCAPTURE, &mapbuf)<0){				// Now they can store images.
			perror("VIDIOCMCAPTURE");
			exit(-1);}
		}
	frame = 0;

//---------------------------------------------------------------------
		       /* CAPTURING*/
//---------------------------------------------------------------------		
	display(window,darea);								// Call display.
	while (1){
		i = -1;
		while(i<0){
	
			i= ioctl(cam,VIDIOCSYNC, &frame);				// Wait until the actual buffer
			if(i < 0 && errno == EINTR) continue;				// is full. When it happends 
			if (i < 0) {							// it start to capture to	
				perror ("VIDIOCSYNC");					// the other buffer.
				exit(-1);
			}
		break;
	}

	buf = bigbuf + vidbuf.offsets[frame];
	mapbuf.frame = frame;	jpeg_size = get_jpegsize(buf,size);	printf("jpeg_size -- %d \n",jpeg_size);
	draw(darea);
	//if (ioctl(cam,VIDIOCMCAPTURE, &mapbuf)<0) {perror("VIDIOCMCAPTURE");		// Turn on the buffer that
	//	exit(-1);}								// was being used.

	frame++;


	if (frame>=vidbuf.frames) frame=0;

	}	gtk_main();										// Go to main process ().
}


//------------------------------------------------------------------------
			/* DISPLAY IMAGES */
//------------------------------------------------------------------------

/*void display(window,darea)
  {
    	gint x, y;
    	static first = 1;
 	if (first)
   	{
       		gtk_container_add (GTK_CONTAINER (window), darea);				// Put darea in windows.
   
        	gtk_signal_connect (GTK_OBJECT (darea), "expose-event",				// Put RGB image in darea.
                        GTK_SIGNAL_FUNC (on_darea_expose), NULL);

 		first = 0;
   	}		
   
   	gtk_drawing_area_size (GTK_DRAWING_AREA (darea), COLS, ROWS);				// Set darea size.
   	gtk_widget_show_all (window);								// Show windows in screen.      
   	gtk_main();										// Go to main process ().
  }*/void display(window,darea){       	gtk_container_add (GTK_CONTAINER (window), darea);				// Put darea in windows.	gtk_drawing_area_size (GTK_DRAWING_AREA (darea), COLS, ROWS);				// Set darea size.
   	gtk_widget_show_all (window);								// Show windows in screen.    }
/*on_darea_expose (GtkWidget *widget)
  { 	GdkPixbufLoader* pixbuf_loader = gdk_pixbuf_loader_new(); 				// create a pixbuf loader object. 	gdk_pixbuf_loader_write( pixbuf_loader, buf, COLS*ROWS, 0 ); // parse the image.	gdk_pixbuf_loader_close (pixbuf_loader, 0 ); // tell the pixbuf loader the end of the parsing the image.	pixbuf = gdk_pixbuf_loader_get_pixbuf( pixbuf_loader ); // get the new pixbuf just created by the pixbuf loader.	gtk_widget_realize(darea);	gdk_draw_pixbuf (GTK_WIDGET (darea)->window, NULL,pixbuf,0,0,0,0, COLS,ROWS, GDK_RGB_DITHER_NORMAL, 0, 0);
   	gtk_main_quit();
  }*/void draw(GtkWidget *widget)
{ 	jpeg_size = get_jpegsize(buf , size);	GdkPixbufLoader* pixbuf_loader = gdk_pixbuf_loader_new(); 				// create a pixbuf loader object. 	gdk_pixbuf_loader_write( pixbuf_loader, buf, jpeg_size, 0 ); // parse the image.	gdk_pixbuf_loader_close (pixbuf_loader, 0 ); // tell the pixbuf loader the end of the parsing the image.	pixbuf = gdk_pixbuf_loader_get_pixbuf( pixbuf_loader ); // get the new pixbuf just created by the pixbuf loader.	gtk_widget_realize(darea);	gdk_draw_pixbuf (GTK_WIDGET (darea)->window, NULL,pixbuf,0,0,0,0, COLS,ROWS, GDK_RGB_DITHER_NORMAL, 0, 0);

}
int get_jpegsize (unsigned char *buf, int insize){ int i; 	 for ( i= 1024 ; i< insize; i++) { 	if ((buf[i] == 0xFF) && (buf[i+1] == 0xD9)) return i+10; } return -1;}


⌨️ 快捷键说明

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