1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Appendix E. Video Grabber example using libv4l</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="LINUX MEDIA INFRASTRUCTURE API"><link rel="up" href="v4l2spec.html" title="Part I. Video for Linux Two API Specification"><link rel="prev" href="capture-example.html" title="Appendix D. Video Capture Example"><link rel="next" href="ix01.html" title="List of Types"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Appendix E. Video Grabber example using libv4l</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="capture-example.html">Prev</a> </td><th width="60%" align="center">Part I. Video for Linux Two API Specification</th><td width="20%" align="right"> <a accesskey="n" href="ix01.html">Next</a></td></tr></table><hr></div><div class="appendix"><div class="titlepage"><div><div><h2 class="title"><a name="v4l2grab-example"></a>Appendix E. Video Grabber example using libv4l</h2></div></div></div><p>This program demonstrates how to grab V4L2 images in ppm format by 2using libv4l handlers. The advantage is that this grabber can potentially work 3with any V4L2 driver.</p><pre class="programlisting"> 4/* V4L2 video picture grabber 5 Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@infradead.org> 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation version 2 of the License. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 */ 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20#include <fcntl.h> 21#include <errno.h> 22#include <sys/ioctl.h> 23#include <sys/types.h> 24#include <sys/time.h> 25#include <sys/mman.h> 26#include <linux/videodev2.h> 27#include "../libv4l/include/libv4l2.h" 28 29#define CLEAR(x) memset(&(x), 0, sizeof(x)) 30 31struct buffer { 32 void *start; 33 size_t length; 34}; 35 36static void xioctl(int fh, int request, void *arg) 37{ 38 int r; 39 40 do { 41 r = v4l2_ioctl(fh, request, arg); 42 } while (r == -1 && ((errno == EINTR) || (errno == EAGAIN))); 43 44 if (r == -1) { 45 fprintf(stderr, "error %d, %s\n", errno, strerror(errno)); 46 exit(EXIT_FAILURE); 47 } 48} 49 50int main(int argc, char **argv) 51{ 52 struct <a class="link" href="vidioc-g-fmt.html#v4l2-format" title="Table A.72. struct v4l2_format">v4l2_format</a> fmt; 53 struct <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> buf; 54 struct <a class="link" href="vidioc-reqbufs.html#v4l2-requestbuffers" title="Table A.100. struct v4l2_requestbuffers">v4l2_requestbuffers</a> req; 55 enum <a class="link" href="buffer.html#v4l2-buf-type" title="Table 3.3. enum v4l2_buf_type">v4l2_buf_type</a> type; 56 fd_set fds; 57 struct timeval tv; 58 int r, fd = -1; 59 unsigned int i, n_buffers; 60 char *dev_name = "/dev/video0"; 61 char out_name[256]; 62 FILE *fout; 63 struct buffer *buffers; 64 65 fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0); 66 if (fd < 0) { 67 perror("Cannot open device"); 68 exit(EXIT_FAILURE); 69 } 70 71 CLEAR(fmt); 72 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 73 fmt.fmt.pix.width = 640; 74 fmt.fmt.pix.height = 480; 75 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; 76 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; 77 xioctl(fd, VIDIOC_S_FMT, &fmt); 78 if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) { 79 printf("Libv4l didn't accept RGB24 format. Can't proceed.\n"); 80 exit(EXIT_FAILURE); 81 } 82 if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480)) 83 printf("Warning: driver is sending image at %dx%d\n", 84 fmt.fmt.pix.width, fmt.fmt.pix.height); 85 86 CLEAR(req); 87 req.count = 2; 88 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 89 req.memory = V4L2_MEMORY_MMAP; 90 xioctl(fd, VIDIOC_REQBUFS, &req); 91 92 buffers = calloc(req.count, sizeof(*buffers)); 93 for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { 94 CLEAR(buf); 95 96 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 97 buf.memory = V4L2_MEMORY_MMAP; 98 buf.index = n_buffers; 99 100 xioctl(fd, VIDIOC_QUERYBUF, &buf); 101 102 buffers[n_buffers].length = buf.length; 103 buffers[n_buffers].start = v4l2_mmap(NULL, buf.length, 104 PROT_READ | PROT_WRITE, MAP_SHARED, 105 fd, buf.m.offset); 106 107 if (MAP_FAILED == buffers[n_buffers].start) { 108 perror("mmap"); 109 exit(EXIT_FAILURE); 110 } 111 } 112 113 for (i = 0; i < n_buffers; ++i) { 114 CLEAR(buf); 115 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 116 buf.memory = V4L2_MEMORY_MMAP; 117 buf.index = i; 118 xioctl(fd, VIDIOC_QBUF, &buf); 119 } 120 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 121 122 xioctl(fd, VIDIOC_STREAMON, &type); 123 for (i = 0; i < 20; i++) { 124 do { 125 FD_ZERO(&fds); 126 FD_SET(fd, &fds); 127 128 /* Timeout. */ 129 tv.tv_sec = 2; 130 tv.tv_usec = 0; 131 132 r = select(fd + 1, &fds, NULL, NULL, &tv); 133 } while ((r == -1 && (errno = EINTR))); 134 if (r == -1) { 135 perror("select"); 136 return errno; 137 } 138 139 CLEAR(buf); 140 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 141 buf.memory = V4L2_MEMORY_MMAP; 142 xioctl(fd, VIDIOC_DQBUF, &buf); 143 144 sprintf(out_name, "out%03d.ppm", i); 145 fout = fopen(out_name, "w"); 146 if (!fout) { 147 perror("Cannot open image"); 148 exit(EXIT_FAILURE); 149 } 150 fprintf(fout, "P6\n%d %d 255\n", 151 fmt.fmt.pix.width, fmt.fmt.pix.height); 152 fwrite(buffers[buf.index].start, buf.bytesused, 1, fout); 153 fclose(fout); 154 155 xioctl(fd, VIDIOC_QBUF, &buf); 156 } 157 158 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 159 xioctl(fd, VIDIOC_STREAMOFF, &type); 160 for (i = 0; i < n_buffers; ++i) 161 v4l2_munmap(buffers[i].start, buffers[i].length); 162 v4l2_close(fd); 163 164 return 0; 165} 166</pre></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="capture-example.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="v4l2spec.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ix01.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix D. Video Capture Example </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> List of Types</td></tr></table></div></body></html> 167