On hand has a UVC (USB video Class) camera (also known as the drive-free camera), by the way to learn V4L2 programming, write code in the process of reference to the predecessors of the blog, feel very good writing, special will link posted here
Http://www.cnblogs.com/emouse/archive/2013/03/04/2943243.html
About V4L2 can learn the blog of predecessors, here just write an example code to see the knowledge point is also not able to write code novice as a reference.
Platform Description:
OK210 Development Board. The
screen is a 800*480 RGB32 format screen with the Development Board.
the camera output format is 640*480 YUYV422 format
About YUYV format please read this blog
Http://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html
About RGB32.
Rgb32:low memory address--> High memory address
| Pixel | Pixel | Pixel | Pixel | Pixel | Pixel | ...
| ——-| ——-| ——-| ——-| ——-| ——-|
| b| G| r| a| b| G| r| a| b| G| r| a| b| G| r| a| b| G| r| a| b| G| r| A|..
A indicates transparency, 0 indicates opacity, and 255 indicates maximum transparency
All the code is as follows:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include < errno.h> #include <linux/fb.h> #include <linux/videodev2.h> #include <sys/ioctl.h> #include < sys/mman.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include < pthread.h> int status = 1;
Stop flag bit, 1 start, 0 stop/* listener thread when starting the camera, enter Q from keyboard, end program/void * Listen (void * arg) {while (1) {char buf[20];
scanf ("%s", buf);
if (strcmp ("Q", buf) = = 0) {status = 0;
Break
} usleep (10);
}//* screen initialization and destruction function */char * fb_init (char * devname, int * fd, int * len);
void fb_destory (int fd, char * screen_bbf, int screenlen);
/* Function function: Perform image conversion, convert UVC output yuyv format image into RGB32 format image return value: No parameters: YUV yuyv format image store address BUF RGB32 format image store address
Length image size (in bytes) */void Process_image (unsigned char * yuv, unsigned char *buf, int length); /* Function function:Output image return value to screen: No parameters: SCREEN_BBF Memory Map The address of the screen in the program BUF RGB32 format data address Width image Height/void show_image (char * screen_bbf, Char *buf,
int width, int height);
* * Save the memory address of the camera memory map and data length * * struct buffer {char * start;
unsigned int length;
};
int width,height;
int main (int argc, char * * argv) {* * camera captures images in YUYV format, screen displays images that require RGB32 format, and the screen size and camera vision are not the same
This applies a piece of memory as a buffer, storage format converted data/unsigned char * BBF = (unsigned char *) malloc (640*480*4);
printf ("BBF Address:%p\n", BBF);
/**************** set screen ****************/int fb_fd, Screenlen;
char * SCREEN_BBF = Fb_init ("/dev/fb0", &FB_FD, &screenlen);
/*************** start setting up camera ********************//* Open camera device/int cam_fd = open ("/dev/video3", O_RDWR);
if (cam_fd = = 1) {printf ("Error:%s\n", Strerror (errno));
return-1;
} * * Get the description of the camera information structure/struct v4l2_capability cap;
int rel = IOCTL (CAM_FD, Vidioc_querycap, &cap);
if (rel = = 1) {printf ("Error:%s\n", Strerror (errno));
Goto ERROR;
}/* To determine that the device support does not support capturing images and stream output functions */if ((Cap.capabilities & v4l2_cap_video_capture) = = v4l2_cap_video_capture)
printf ("It ' s camer!\n");
else {printf ("It ' s not a camer!\n");
Goto ERROR;
} if ((Cap.capabilities & v4l2_cap_streaming) = = v4l2_cap_streaming) printf ("It ' s stream device!\n");
else {printf ("It ' s not a stream device!\n");
Goto ERROR; printf ("Driver name:%s\n\ Card name:%s\nbus info:%s\n\ Driver Version:%u.%u.%u\n", \ Cap.driver , Cap.card, cap.bus_info,\ (cap.version>>16) &0xff, (cap.version>>8) &0xff, (cap.version) &
0xFF);
* * Get the video camera to capture the format of the information * * struct V4l2_format fmt;
memset (&fmt, 0, sizeof (FMT)); Fmt.type = V4l2_buf_type_video_CAPTURE;
rel = IOCTL (CAM_FD, VIDIOC_G_FMT, &fmt);
if (rel = = 1) {printf ("Get FMT failed!\n");
Goto ERROR;
} width = fmt.fmt.pix.width;
Height = fmt.fmt.pix.height; printf (width:%d height:%d\n\ pixelformat:%d\n\ field:%d\n\ bytesperline:%d\n\ sizeimage:%d\n \ colorspace:%d\n\ priv:%d\n ", fmt.fmt.pix.width,\ fmt.fmt.pix.height,\, Fmt.fmt.pix.pixelformat,
\ Fmt.fmt.pix.field, \ Fmt.fmt.pix.bytesperline, \ Fmt.fmt.pix.sizeimage, \ Fmt.fmt.pix.colorspace, \
FMT.FMT.PIX.PRIV);
/* Get all the formats supported by the camera * * struct V4L2_FMTDESC fmtdesc;
Fmtdesc.index = 0;
Fmtdesc.type = v4l2_buf_type_video_capture;
printf ("Support format: \ n"); while (IOCTL (CAM_FD, VIDIOC_ENUM_FMT, &fmtdesc)!=-1) {printf ("\t%d.%s\n", Fmtdesc.index+1, Fmtdesc.descript
ION);
fmtdesc.index++;
* * Apply a data frame queue to the camera/* struct v4l2_requestbuffers req; Req.cOunt = 4;
Req.type = v4l2_buf_type_video_capture;
Req.memory = V4l2_memory_mmap;
rel = IOCTL (CAM_FD, Vidioc_reqbufs, &req);
if (Rel < 0) {printf ("Request buffers Error:%s\n", Strerror (errno));
Goto ERROR;
else printf ("Request buffers successed!\n");
/* Request array memory for storing image buffer address and length/struct buffer * buffers = (struct buffer *) malloc (4*sizeof (struct buffer *));
if (buffers = = NULL) {printf ("malloc buffers err:%s\n", Strerror (errno));
Goto ERROR;
/* * Map memory of buffer to user space */int n_buffers = 0;
for (; n_buffers < req.count; n_buffers++) {struct V4l2_buffer buf;
memset (&buf, 0, sizeof (BUF));
Buf.type = v4l2_buf_type_video_capture;
Buf.memory = V4l2_memory_mmap;
Buf.index = n_buffers; if (-1 = = IOCTL (CAM_FD, Vidioc_querybuf, &buf)) {//Get the address of the buffer frame printf ("Set BUF error:%s\n", Strerror (Errn
o));
Goto ERROR; } else {printf ("Set buf success!\n");
} buffers[n_buffers].length = Buf.length; /* Mapped memory space */Buffers[n_buffers].start = mmap (NULL, Buf.length, prot_read|
Prot_write, map_shared, CAM_FD, Buf.m.offset);
if (NULL = = Buffers[n_buffers].start) {printf ("Mmap Error:%s\n", Strerror (errno));
Goto Map_error; else printf ("Mmap success!
Address =%p\n ", Buffers[n_buffers].start);
IOCTL (CAM_FD, Vidioc_qbuf, &buf);
*/* Open video stream/enum V4l2_buf_type type = v4l2_buf_type_video_capture;
if ( -1 = = IOCTL (CAM_FD, Vidioc_streamon, &type)) goto Map_error;
else printf ("Start stream!\n");
/* Create a listener thread to stop the program */pthread_t PD;
Pthread_create (&PD, NULL, listen, NULL);
/* Start capturing camera data and showing on screen/while (status) {/* Initialize Select monitor/Fd_set FDS;
Fd_zero (&fds); Fd_set (CAM_FD, &fDS);
struct Timeval TV;
tv.tv_sec = 0;
Tv.tv_usec = 125000;
int ret = SELECT (cam_fd+1, &fds, NULL, NULL, &TV);
if (ret = = 1) {printf ("Error:listen failes\n");
else if (ret = 0) {printf ("Time Out!\n");
else {struct V4l2_buffer buf;
memset (&buf, 0, sizeof (BUF));
Buf.type = v4l2_buf_type_video_capture;
Buf.memory = V4l2_memory_mmap; /* Get a frame of data */if (IOCTL (CAM_FD, Vidioc_dqbuf, &buf)!=-1) {/* for format conversion * * p
Rocess_image (Buffers[buf.index].start, BBF, buffers[buf.index].length);
/* Display on the screen/Show_image (SCREEN_BBF, BBF, width, height); /* Put frames back into queue/if ( -1!= (IOCTL (CAM_FD, Vidioc_qbuf, &buf)) printf ("Putting in Success")
!\n "); else printf ("Put in failed!\n");
else printf ("Get frame failed!\n");
\ */* Close video stream/enum V4l2_buf_type type = v4l2_buf_type_video_capture;
IOCTL (CAM_FD, Vidioc_streamoff, &type);/* Unlock memory map, close file descriptor, program end/int i;
For (i=0 i<4; i++) {if (Buffers[i].start!= NULL) munmap (Buffers[i].start, buffers[i].length);
Close (CAM_FD);
Fb_destory (FB_FD, SCREEN_BBF, Screenlen);
Free (BBF);
return 0;
Map_error:for (n_buffers=0 n_buffers<4; n_buffers++) {if (Buffers[n_buffers].start!= NULL)
Munmap (Buffers[n_buffers].start, buffers[n_buffers].length);
} error:fb_destory (FB_FD, SCREEN_BBF, Screenlen);
Close (CAM_FD);
Free (BBF);
return-1;
}/* Do not know why the RGB32 on the screen in the Yuvy format is better than the YUYV format expansion of the program is in the Yuvy format, YUYV conversion procedures should be v0 = yuv[count*4+0];
y0 = yuv[count*4+1];
u0 = yuv[count*4+2];
y1 = yuv[count*4+3]; * * void Process_image(unsigned char * YUV, unsigned char * buf, int length)
{int count;
int y0,u0,y1,v0;
For (count=0 count<length/4; count++) {y0 = yuv[count*4+0];
u0 = yuv[count*4+1];
y1 = yuv[count*4+2];
V0 = yuv[count*4+3]; Buf[count*8+0] = 1.164* (y0-16) + 2.018* (u0-128); b buf[count*8+1] = 1.164* (y0-16)-0.380* (u0-128) + 0.813* (v0-128); G buf[count*8+2] = 1.164* (y0-16) + 1.159* (v0-128); R Buf[count*8+3] = 0; Transparency Buf[count*8+4] = 1.164* (y1-16) + 2.018* (u0-128); b buf[count*8+5] = 1.164* (y1-16)-0.380* (u0-128) + 0.813* (v0-128); G Buf[count*8+6] = 1.164* (y1-16) + 1.159* (v0-128); R Buf[count*8+7] = 0;
Transparency} void Show_image (char * screen_bbf, char * buf, int width, int height) {int i,j;
For (i=0 i
The effect chart is as follows: