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

📄 videodog44.c

📁 linux下
💻 C
字号:
/* videodog4.c - v4l capture using the double buffer capability */
/* experimental code */
/* tested only w/ cpia driver over paralel port */



#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/videodev.h>
#include <unistd.h>		/* read */
#include <errno.h>		/* errno */
#include <stdlib.h>
#include <termios.h>
#include <math.h>
#include <sys/fcntl.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <sys/shm.h>

#include <sys/resource.h>
#include <string.h>

void DOT (void) { static int indice=0; fprintf(stderr,"%d", indice++); }


#define VIDEO_BUFFERS	2 // numero de buffers usados na captura

// padrao de imagens

#define WIDTH	320
#define	HEIGHT	240
#define	DEPTH	3
#define	IMGSIZE	(WIDTH * HEIGHT * DEPTH)



// structs globais

struct video_mbuf mbuf;
struct video_picture pic;
struct video_channel chn;
struct video_mmap buf[VIDEO_BUFFERS];
struct video_capability cap;
unsigned char *buffer;


int video_fd;
static int frame_flag=0;

int _grab_frame (int frame) { 		// captura

	if (ioctl(video_fd,  VIDIOCMCAPTURE, buf + frame) == -1) ; // captura para o frame determinado
	return 0;
}
	

int _grab_sync ( int frame ) { 		// sincroniza
	if (ioctl (video_fd, VIDIOCSYNC, buf+frame) == -1); // sincroniza o frame determinado
		return 0;
	return frame; // apenas para controle, retorna o frame
			
}


int _grab_open (char *device, int width, int height, int depth) {
	
	unsigned int size=0;

	
	if ((video_fd=open(device, O_RDWR)) < 0 ) return -1;
	
	if (ioctl (video_fd, VIDIOCGCAP, &cap) < 0) return -1;

	if (width > cap.maxwidth || height > cap.maxheight ||
		width < cap.minwidth || height < cap.minheight)
		               return -1;
	
	if (ioctl (video_fd, VIDIOCGPICT, &pic) < 0) return -1;
	
	chn.type = VIDEO_TYPE_CAMERA;
	chn.norm = VIDEO_MODE_PAL;
	chn.channel = 1;
	
	if (ioctl (video_fd, VIDIOCSCHAN, &chn) < 0) return -1;
	
	// mmap

	buf[0].frame = 0;
	buf[1].frame = 1;
	buf[0].width = buf[1].width = width;
	buf[0].height = buf[1].height = height;
	
	switch (depth) {

	case 1:
		buf[0].format = buf[1].format = VIDEO_PALETTE_GREY;
		break;
	case 2:
	        buf[0].format = buf[1].format = VIDEO_PALETTE_RGB565;
	        break;
	case 3:
	default:
	        buf[0].format = buf[1].format = VIDEO_PALETTE_RGB24;
	        break;
	}
			
	size = width * height * depth;
	mbuf.size = size * VIDEO_BUFFERS;
	mbuf.frames = 0;
	mbuf.offsets[0] = 0;
	mbuf.offsets[1] = size;

	if (ioctl (video_fd, VIDIOCGMBUF, &mbuf) < 0) return -1;
	buffer = mmap (0, mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, video_fd, 0);
	
	if (buffer == (unsigned char *) -1) return -1;
	if (_grab_frame(frame_flag) < 0) return 0;
	
	if (frame_flag) frame_flag=0;
	else frame_flag=1;
	
	return 0;
	
}

void _grab_close (void) {
	munmap (buffer, mbuf.size);
	close (video_fd);
}


unsigned char *_grab_pix (void) { 	// retorna um frame, alternando

//	static int frame=frame_flag; // registro static , inicia no frame_flag e a cada chamada alterna
	if (_grab_frame(frame_flag) < 0) return 0;

	frame_flag=!frame_flag;

	if(_grab_sync(!frame_flag) < 0) return 0;

	return buffer + mbuf.offsets[frame_flag]; // inverte
}

void _save_test_pnm (unsigned char *buffer, int wido, int heio, unsigned long si) {

	static int indo=0;
	FILE *fp;
	char bewf[128];

	sprintf (bewf, "image-%d.pnm", indo);
	indo++;
	if ((fp = fopen (bewf, "w")) == NULL) return;
	fprintf (fp, "P6\n%d %d\n255\n", wido, heio);
	fwrite (buffer, si, 1, fp);
	fclose (fp);

	}

void _save_test_ppm (unsigned char *image, int width, int height)
// this is a shameless copy from vidcat merged together with
// Gleicon's _save_test_pnm  Franz <fre@wenglor.de>
{
	
	unsigned char *p = (unsigned char *)image;
	unsigned char rgb[3];
        static int indo=0;
	int fp,j,k; 
   unsigned char header[16];
   //unsigned char *p;
    //unsigned char rgb[3];
    char bewf[128];

        sprintf (bewf, "image-%d.ppm", indo);

	 indo++;
   if ((fp = open (bewf, O_WRONLY | O_CREAT, 0644)) < 0) {
    printf ("ppm open failed: %d\n", errno);
    exit (1);
//fp = fopen(filename,"w"); 
//if(fp == NULL) 
//return -1; 
}
sprintf(header,"P6\n%d %d\n255\n",width, height);
//fprintf(fp,"P6\n%d %d\n255\n",screen_width, screen_height); 
write (fp, header, strlen(header));
//fwrite(img, screen_height, 3*screen_width, fp); 

   for (j=0; j<height; j++) {
    for (k=0; k<width; k++) {
      rgb[2] = *p++;		
      rgb[1] = *p++;		
      rgb[0] = *p++;		
      //p++;			
      write(fp, rgb, 3);
    }
 }

close(fp); 
//return 0; 

} 
	/*
        ls=sizeof(unsigned char);
        if ((fp = fopen (bewf, "w")) == NULL) return;

        fprintf (fp,"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, ls, 3, fp);
                p += 3;
        }

	fflush (fp);
        fclose (fp);*/


int main (void) {

	time_t t, t2;
	//struct tm *mytm;

	int a;
	//unsigned char *bufo;
	int interlock=0;


	if (_grab_open("/dev/video0", WIDTH, HEIGHT, DEPTH) < 0) {
		fprintf (stderr,"cant open\n");
		exit(0);
		}
	while (1) {
	time(&t);

	for (a=0; a< 30; a++) {
		ioctl (video_fd,  VIDIOCMCAPTURE, &buf[interlock]);
		interlock = !interlock;

		ioctl (video_fd, VIDIOCSYNC, &buf[interlock] );

                _save_test_ppm (_grab_pix(), WIDTH, HEIGHT);
	}

	time (&t2);

	fprintf (stderr,"Time: initial: %ld \nfinal: %ld\nelapsed: %ld \n", (time_t)t, (time_t)t2, (time_t)t2-t);

        }

	_grab_close();
return 0;
}

⌨️ 快捷键说明

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