?? v4l_layer.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;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -