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

📄 v4l_layer.cpp

📁 ARM交叉编译工具链
💻 CPP
字号:
/*
  * this src is used for testing the v4l and the sdl .
  * Beside this,it provides a simple wrap of v4l and sdl .
  * You can use it any where,but should keep this header.
  * Any suggestion is appreicated.
  *
  *	Tianjin University , China.
  *	
  *	vinqosky@gmail.com
  */

#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <asm/types.h>

#include "v4l_layer.h"

#define noDEBUG_V4L_OUTPUT
#define noDEBUG_V4L
#define noDEBUG_V4L_FRAME_OUTPUT

#ifdef DEBUG_V4L_OUTPUT
FILE *output;
#endif //DEBUG_V4L_OUTPUT

#ifdef DEBUG_V4L_FRAME_OUTPUT
int save_pnm(u_int8_t *buf,int x,int y,int depth)
{
	static int inc = 0;
	FILE *fp;

	char bewf[128];
	sprintf(bewf,"image-%d.pnm",inc);

	if((fp = fopen(bewf,"w+")) == NULL)
	{
		perror("open image. pnm\n");
		exit(1);
	}

	if(depth == 3)
		fprintf(fp,"P6\n%d %d\n255\n",x,y);
	else if(depth == 1)
		fprintf(fp,"P5\n%d %d \n255\n",x,y);

	fwrite((unsigned char *)buf,x*y*depth,1,fp);
	inc++;

	fclose(fp);
}
#endif //DEBUG_V4L_FRAME_OUTPUT

int CV4lSrc::init(char * deviceName,int width,int height)
{
	int frame;

	//here to copy the device string
	m_device_ptr = (char *)malloc((strlen(deviceName)*sizeof(char)+1));
	if(m_device_ptr == NULL)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in copy device name.\n");
#endif //DEBUG_V4L
		return -1;
	}

	memset(m_device_ptr,0,strlen(deviceName));
	strncpy(m_device_ptr,deviceName,strlen(deviceName));

	//here to open the device
	if((m_fd = open(m_device_ptr,O_RDWR)) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Device name = %s\n",m_device_ptr);
		fprintf(stderr,"Error in open device.\n");
#endif //DEBUG_V4L
		return -1;
	}

	//here to get the capability of the device
	if(ioctl(m_fd,VIDIOCGCAP,&m_cap) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in VIDIOCGCAP.\n");
#endif //DEBUG_V4L
		return -1;
	}

 	//here to get the picture parameters of the device
	if(ioctl(m_fd,VIDIOCGPICT,&m_pic) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in VIDIOCGPICT.\n");
#endif //DEBUG_V4L
		return -1;
	}

	//here to get the buf size and other parameters of the device
	if(ioctl(m_fd,VIDIOCGMBUF,&m_vm) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in VIDIOCGMBUF.\n");
#endif //DEBUG_V4L
		return -1;
	} 

	//check the width and height,after that init the video_mmap m_buf
	if(width>0&&width<m_cap.maxwidth)
		m_buf.width = width;
	else
		m_buf.width = m_cap.maxwidth;
	
	if(height>0&&height<m_cap.maxheight)
		m_buf.height = height;
	else
		m_buf.height = m_cap.maxheight;
	
	m_buf.frame = 0;
	m_buf.format = VIDEO_PALETTE_RGB24;
	m_depth = 3;

	//mmap to share the buf 
	m_data = (u_int8_t *)mmap(0,m_vm.size,PROT_READ|PROT_WRITE,MAP_SHARED,m_fd,0);
	if(m_data == NULL)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"mmap() failed.\n");
#endif //DEBUG_V4L
		return -1;
	}

	for(frame = 0;frame<m_vm.frames;frame++)
	{
		m_buf.frame = frame;
		if(ioctl(m_fd,VIDIOCMCAPTURE,&m_buf) == -1)
		{
			//ERROR
#ifdef DEBUG_V4L
			fprintf(stderr,"Error in VIDIOCMCAPTURE (init).\n");
#endif //DEBUG_V4L
			return -1;
		}
	}

	//init the m_frame
	m_frame = 0;

#ifdef DEBUG_V4L_OUTPUT
	if((output = fopen("v4lOutput.raw","w+")) == NULL)
	{
		fprintf(stderr,"Error in open v4lOutput.raw \n");
	}
#endif //DEBUG_V4L_OUTPUT

	return 1;
	
}

void CV4lSrc::closeIt()
{
	//free anything and close anything
	if(m_device_ptr != NULL)
		free(m_device_ptr);
	
	close(m_fd);
	munmap(m_data,m_vm.size);
	
#ifdef DEBUG_V4L_OUTPUT
	if(output != NULL)
		fclose(output);
#endif //DEBUG_V4L_OUTPUT
}

void CV4lSrc::setFrameWidth(int width)
{
	m_buf.width = width;
}

void CV4lSrc::setFrameHeight(int height)
{
	m_buf.height = height;
}

void CV4lSrc::setFrame(int width,int height)
{
	setFrameWidth(width);
	setFrameHeight(height);
}

int CV4lSrc::setPicture(int hue, int contrast, int brightness, int colour)
{
	if(hue>-1)
		m_pic.hue = hue;
	if(contrast>-1)
		m_pic.contrast = contrast;
	if(brightness>-1)
		m_pic.brightness = brightness;
	if(colour>-1)
		m_pic.colour = colour;

	if(ioctl(m_fd,VIDIOCSPICT,&m_pic) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in VIDIOCSPICT (setPicture).\n");
#endif //DEBUG_V4L
		return -1;
	}

	return 1;
}

/*
 *
 * 
 */
int CV4lSrc::getAFrame(u_int8_t *data)
{
	u_int8_t *temp = NULL;
	
	if(ioctl(m_fd,VIDIOCSYNC,&m_frame) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in VIDIOCSYNC (getAFrame).\n");
#endif //DEBUG_V4L
		return -1;
	}

	temp = m_data + m_vm.offsets[m_frame];
	memcpy(data,temp,m_buf.width*m_buf.height*m_depth);

#ifdef DEBUG_V4L_OUTPUT
	if(output!=NULL)
	{
		fwrite((unsigned char*)data,m_buf.width*m_buf.heigth*m_depth,1,output);
	}
#endif //DEBUG_V4L_OUTPUT

#ifdef DEBUG_V4L_FRAME_OUTPUT
	save_pnm(data,m_buf.width,m_buf.height,m_depth);
#endif //DEBUG_V4L_FRAME_OUTPUT

	releaseTheFrame();
	
	return 1;
}

int CV4lSrc::releaseTheFrame()
{
	m_buf.frame = m_frame;
	if(ioctl(m_fd,VIDIOCMCAPTURE,&m_buf) == -1)
	{
		//ERROR
#ifdef DEBUG_V4L
		fprintf(stderr,"Error in VIDIOCMCAPTURE (releaseTheFrame).\n");
#endif //DEBUG_V4L
		return -1;
	}

	m_frame++;
	if(m_frame>=m_vm.frames)
		m_frame = 0;

	return 1;
}


⌨️ 快捷键说明

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