Source code-sample program for capturing and using framebuffer Based on the UVC camera of v4l2

Source: Internet
Author: User
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <getopt.h>  #include <fcntl.h>  #include <unistd.h>#include <errno.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/time.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <asm/types.h>#include <linux/videodev2.h>#include <linux/fb.h>#define CLEAR(x) memset (&(x), 0, sizeof (x))struct buffer {void * start;size_t length;};static char * dev_name = NULL;static int fd = -1;struct buffer * buffers = NULL;static unsigned int n_buffers = 0;static int time_in_sec_capture=5;static int fbfd = -1;static struct fb_var_screeninfo vinfo;static struct fb_fix_screeninfo finfo;static char *fbp=NULL;static long screensize=0;static void errno_exit (const char * s){fprintf (stderr, "%s error %d, %s\n",s, errno, strerror (errno));exit (EXIT_FAILURE);}static int xioctl (int fd,int request,void * arg){int r;do r = ioctl (fd, request, arg);while (-1 == r && EINTR == errno);return r;}inline int clip(int value, int min, int max) {return (value > max ? max : value < min ? min : value);}static void process_image (const void * p){//ConvertYUVToRGB32unsigned char* in=(char*)p;int width=640;int height=480;int istride=1280;int x,y,j;int y0,u,y1,v,r,g,b;long location=0;for ( y = 100; y < height + 100; ++y) {for (j = 0, x=100; j < width * 2 ; j += 4,x +=2) {location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +(y+vinfo.yoffset) * finfo.line_length;y0 = in[j];u = in[j + 1] - 128;                y1 = in[j + 2];        v = in[j + 3] - 128;        r = (298 * y0 + 409 * v + 128) >> 8;g = (298 * y0 - 100 * u - 208 * v + 128) >> 8;b = (298 * y0 + 516 * u + 128) >> 8;fbp[ location + 0] = clip(b, 0, 255);fbp[ location + 1] = clip(g, 0, 255);fbp[ location + 2] = clip(r, 0, 255);    fbp[ location + 3] = 255;    r = (298 * y1 + 409 * v + 128) >> 8;g = (298 * y1 - 100 * u - 208 * v + 128) >> 8;b = (298 * y1 + 516 * u + 128) >> 8;fbp[ location + 4] = clip(b, 0, 255);fbp[ location + 5] = clip(g, 0, 255);fbp[ location + 6] = clip(r, 0, 255);    fbp[ location + 7] = 255;    }in +=istride;}}static int read_frame (void){struct v4l2_buffer buf;unsigned int i;CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {switch (errno) {case EAGAIN:return 0;case EIO:    default:errno_exit ("VIDIOC_DQBUF");}}assert (buf.index < n_buffers);assert (buf.field ==V4L2_FIELD_NONE);process_image (buffers[buf.index].start);if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");return 1;}static void run (void){unsigned int count;int frames;frames = 30 * time_in_sec_capture;while (frames-- > 0) {for (;;) {fd_set fds;struct timeval tv;int r;FD_ZERO (&fds);FD_SET (fd, &fds);tv.tv_sec = 2;tv.tv_usec = 0;r = select (fd + 1, &fds, NULL, NULL, &tv);if (-1 == r) {if (EINTR == errno)continue;errno_exit ("select");}if (0 == r) {fprintf (stderr, "select timeout\n");exit (EXIT_FAILURE);}if (read_frame ())break;}}}static void stop_capturing (void){enum v4l2_buf_type type;type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))errno_exit ("VIDIOC_STREAMOFF");}static void start_capturing (void){unsigned int i;enum v4l2_buf_type type;for (i = 0; i < n_buffers; ++i) {struct v4l2_buffer buf;CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = i;if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))errno_exit ("VIDIOC_QBUF");}type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))errno_exit ("VIDIOC_STREAMON");}static void uninit_device (void){unsigned int i;for (i = 0; i < n_buffers; ++i)if (-1 == munmap (buffers[i].start, buffers[i].length))errno_exit ("munmap");if (-1 == munmap(fbp, screensize)) {printf(" Error: framebuffer device munmap() failed.\n");exit (EXIT_FAILURE) ;}    free (buffers);}static void init_mmap (void){struct v4l2_requestbuffers req;//mmap framebufferfbp = (char *)mmap(NULL,screensize,PROT_READ | PROT_WRITE,MAP_SHARED ,fbfd, 0);if ((int)fbp == -1) {printf("Error: failed to map framebuffer device to memory.\n");exit (EXIT_FAILURE) ;}memset(fbp, 0, screensize);CLEAR (req);req.count = 4;req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;req.memory = V4L2_MEMORY_MMAP;if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {if (EINVAL == errno) {fprintf (stderr, "%s does not support memory mapping\n", dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_REQBUFS");}}if (req.count < 4) {    //if (req.count < 2)fprintf (stderr, "Insufficient buffer memory on %s\n",dev_name);exit (EXIT_FAILURE);}buffers = calloc (req.count, sizeof (*buffers));if (!buffers) {fprintf (stderr, "Out of memory\n");exit (EXIT_FAILURE);}for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {struct v4l2_buffer buf;CLEAR (buf);buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;buf.memory = V4L2_MEMORY_MMAP;buf.index = n_buffers;if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))errno_exit ("VIDIOC_QUERYBUF");buffers[n_buffers].length = buf.length;buffers[n_buffers].start =mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,fd, buf.m.offset);if (MAP_FAILED == buffers[n_buffers].start)errno_exit ("mmap");}}static void init_device (void){struct v4l2_capability cap;struct v4l2_cropcap cropcap;struct v4l2_crop crop;struct v4l2_format fmt;unsigned int min;// Get fixed screen informationif (-1==xioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {printf("Error reading fixed information.\n");exit (EXIT_FAILURE);}// Get variable screen informationif (-1==xioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {printf("Error reading variable information.\n");exit (EXIT_FAILURE);}screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {if (EINVAL == errno) {fprintf (stderr, "%s is no V4L2 device\n",dev_name);exit (EXIT_FAILURE);} else {errno_exit ("VIDIOC_QUERYCAP");}}if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {fprintf (stderr, "%s is no video capture device\n",dev_name);exit (EXIT_FAILURE);}if (!(cap.capabilities & V4L2_CAP_STREAMING)) {fprintf (stderr, "%s does not support streaming i/o\n",dev_name);exit (EXIT_FAILURE);}CLEAR (cropcap);cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;crop.c = cropcap.defrect;if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {switch (errno) {case EINVAL:    break;default:break;}}}else {     }CLEAR (fmt);fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.width = 640;  fmt.fmt.pix.height = 480;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;fmt.fmt.pix.field = V4L2_FIELD_NONE;if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))errno_exit ("VIDIOC_S_FMT");init_mmap ();}static void close_device (void){if (-1 == close (fd))errno_exit ("close");fd = -1;close(fbfd);}static void open_device (void){struct stat st;  if (-1 == stat (dev_name, &st)) {fprintf (stderr, "Cannot identify '%s': %d, %s\n",dev_name, errno, strerror (errno));exit (EXIT_FAILURE);}if (!S_ISCHR (st.st_mode)) {fprintf (stderr, "%s is no device\n", dev_name);exit (EXIT_FAILURE);}//open framebufferfbfd = open("/dev/fb0", O_RDWR);if (fbfd==-1) {printf("Error: cannot open framebuffer device.\n");exit (EXIT_FAILURE);}//open camerafd = open (dev_name, O_RDWR| O_NONBLOCK, 0);if (-1 == fd) {fprintf (stderr, "Cannot open '%s': %d, %s\n",dev_name, errno, strerror (errno));exit (EXIT_FAILURE);}}static void usage (FILE * fp,int argc,char ** argv){fprintf (fp,"Usage: %s [options]\n\n""Options:\n""-d | --device name Video device name [/dev/video]\n""-h | --help Print this message\n""-t | --how long will display in seconds\n""",argv[0]);}static const char short_options [] = "d:ht:";static const struct option long_options [] = {{ "device", required_argument, NULL, 'd' },{ "help", no_argument, NULL, 'h' },{ "time", no_argument, NULL, 't' },{ 0, 0, 0, 0 }};int main (int argc,char ** argv){dev_name = "/dev/video0";for (;;)  {int index;int c;c = getopt_long (argc, argv,short_options, long_options,&index);if (-1 == c)break;switch (c) {case 0:break;case 'd':dev_name = optarg;break;case 'h':usage (stdout, argc, argv);exit (EXIT_SUCCESS);case 't':time_in_sec_capture = atoi(optarg);break;default:usage (stderr, argc, argv);exit (EXIT_FAILURE);}}open_device ();init_device ();start_capturing ();run ();stop_capturing ();uninit_device ();close_device ();exit (EXIT_SUCCESS);return 0;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.