vcap.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:4k
- /* Capture a frame of video from a V4L2 driver and send it
- * to stdout. Use vctrl to set image width, height, depth.
- *
- * This program was written by Bill Dirks.
- * This program is in the public domain.
- *
- * gcc -o xcaptest -L/usr/X11R6/lib/ -lXt -lXaw -Wall xcaptest.c
- *
- * ./vcat [-rgb | -bgr] [device-node]
- */
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <sys/mman.h>
- #include <errno.h>
- /* These are needed to use the Videum driver */
- #include <linux/fs.h>
- #include <linux/kernel.h>
- #include <linux/videodev2.h> /* Video for Linux Two */
- int start_capturing(void);
- #define STREAMBUFS 12
- typedef struct tag_vimage
- {
- struct v4l2_buffer vidbuf;
- char *data;
- } VIMAGE;
- VIMAGE vimage[STREAMBUFS];
- int vid;
- int
- main(int argc, char *argv[])
- {
- char *device = NULL;
- int wanted_format;
- int err;
- int i;
- int n;
- struct v4l2_capability cap;
- struct v4l2_format fmt;
- struct v4l2_fmtdesc fmtd;
- fd_set rdset;
- struct timeval timeout;
- struct v4l2_buffer tempbuf;
- for (i = 1; i < argc; ++i)
- {
- if (strcmp(argv[i], "-rgb") == 0)
- wanted_format = V4L2_PIX_FMT_BGR32;
- else if (strcmp(argv[i], "-bgr") == 0)
- wanted_format = V4L2_PIX_FMT_BGR32;
- else if (strcmp(argv[i],"-yuv") == 0)
- wanted_format = V4L2_PIX_FMT_YUYV;
- else if (argv[i][0] == '-')
- continue;
- else
- device = argv[i];
- }
- if (device == NULL)
- device = "/dev/video";
- vid = open(device, O_RDONLY);
- if (vid < 0)
- {
- fprintf(stderr, "Can't open %sn", device);
- return 1;
- }
- err = ioctl(vid, VIDIOC_QUERYCAP, &cap);
- if (err)
- {
- fprintf(stderr, "QUERYCAP returned error %dn", errno);
- return 1;
- }
- if (cap.type != V4L2_TYPE_CAPTURE)
- {
- fprintf(stderr, "Device %s is not a video capture device.n",
- device);
- return 1;
- }
- if (!(cap.flags & V4L2_FLAG_READ))
- {
- fprintf(stderr, "Device %s doesn't support read().n", device);
- return 1;
- }
- for (i = 0, err = 0; err == 0; ++i)
- {
- fmtd.index = i;
- err = ioctl(vid, VIDIOC_ENUM_CAPFMT, &fmtd);
- if (err) {
- printf("wanted format not supportedn");
- exit(1);
- }
- if (fmtd.pixelformat == wanted_format)
- break;
- }
- fmt.width = 704;
- fmt.height = 240;
- fmt.depth = fmtd.depth;
- fmt.flags = V4L2_FMT_FLAG_TOPFIELD | V4L2_FMT_FLAG_BOTFIELD;
- fmt.pixelformat = fmtd.pixelformat;
- if (ioctl(vid, VIDIOC_S_FMT, &fmt)) {
- fprintf(stderr, "G_FMT returned error %dn", errno);
- return 1;
- }
- if (start_capturing()) {
- fprintf(stderr, "Could not create cap buffersn");
- exit(1);
- }
- for(i=0; i < 60 * 30; i++) {
- FD_ZERO(&rdset);
- FD_SET(vid, &rdset);
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- n = select(vid + 1, &rdset, NULL, NULL, &timeout);
- err = -1;
- if (n == -1)
- fprintf(stderr, "select error.n");
- else if (n == 0)
- fprintf(stderr, "select timeoutn");
- else if (FD_ISSET(vid, &rdset))
- err = 0;
- if (err == 0)
- {
- tempbuf.type = vimage[0].vidbuf.type;
- err = ioctl(vid, VIDIOC_DQBUF, &tempbuf);
- if (err)
- printf("DQBUF returned error %dn",
- errno);
- err = ioctl(vid, VIDIOC_QBUF, &tempbuf);
- if (err)
- printf("QBUF returned error %dn",
- errno);
- }
- }
- return 0;
- }
- int
- start_capturing()
- {
- struct v4l2_requestbuffers req;
- int err;
- int i;
- req.count = STREAMBUFS;
- req.type = V4L2_BUF_TYPE_CAPTURE;
- err = ioctl(vid, VIDIOC_REQBUFS, &req);
- if (err < 0 || req.count < 1)
- {
- printf("REQBUFS returned error %d, count %dn",
- errno,req.count);
- return 1;
- }
- for (i = 0; i < req.count; ++i)
- {
- vimage[i].vidbuf.index = i;
- vimage[i].vidbuf.type = V4L2_BUF_TYPE_CAPTURE;
- err = ioctl(vid, VIDIOC_QUERYBUF, &vimage[i].vidbuf);
- if (err < 0)
- {
- printf("QUERYBUF returned error %dn",errno);
- return 1;
- }
- vimage[i].data = mmap(0, vimage[i].vidbuf.length, PROT_READ,
- MAP_SHARED, vid,
- vimage[i].vidbuf.offset);
- if ((int)vimage[i].data == -1)
- {
- printf("mmap() returned error %dn", errno);
- return 1;
- }
- }
- for (i = 0; i < req.count; ++i)
- if ((err = ioctl(vid, VIDIOC_QBUF, &vimage[i].vidbuf)))
- {
- printf("QBUF returned error %dn",errno);
- return 1;
- }
- err = ioctl(vid, VIDIOC_STREAMON, vimage[0].vidbuf.type);
- if (err)
- printf("STREAMON returned error %dn",errno);
- return 0;
- }