vcap.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:4k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /* Capture a frame of video from a V4L2 driver and send it
  2.  * to stdout. Use vctrl to set image width, height, depth.
  3.  *
  4.  * This program was written by Bill Dirks.
  5.  * This program is in the public domain.
  6.  *
  7.  * gcc -o xcaptest -L/usr/X11R6/lib/ -lXt -lXaw -Wall xcaptest.c
  8.  *
  9.  * ./vcat [-rgb | -bgr] [device-node]
  10.  */
  11. #include <sys/time.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include <sys/ioctl.h>
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <sys/mman.h>
  20. #include <errno.h>
  21. /* These are needed to use the Videum driver */
  22. #include <linux/fs.h>
  23. #include <linux/kernel.h>
  24. #include <linux/videodev2.h>  /* Video for Linux Two */
  25. int start_capturing(void);
  26. #define STREAMBUFS 12
  27. typedef struct tag_vimage
  28. {
  29. struct v4l2_buffer vidbuf;
  30. char *data;
  31. } VIMAGE;
  32. VIMAGE vimage[STREAMBUFS];
  33. int vid;
  34. int
  35. main(int argc, char *argv[])
  36. {
  37. char *device = NULL;
  38. int wanted_format;
  39. int err;
  40. int i;
  41. int n;
  42. struct v4l2_capability cap;
  43.         struct v4l2_format fmt;
  44. struct v4l2_fmtdesc fmtd;
  45. fd_set rdset;
  46. struct timeval timeout;
  47. struct v4l2_buffer tempbuf;
  48. for (i = 1; i < argc; ++i)
  49. {
  50. if (strcmp(argv[i], "-rgb") == 0)
  51. wanted_format = V4L2_PIX_FMT_BGR32;
  52. else if (strcmp(argv[i], "-bgr") == 0)
  53. wanted_format = V4L2_PIX_FMT_BGR32;
  54. else if (strcmp(argv[i],"-yuv") == 0)
  55. wanted_format = V4L2_PIX_FMT_YUYV;
  56. else if (argv[i][0] == '-')
  57. continue;
  58. else
  59. device = argv[i];
  60. }
  61. if (device == NULL)
  62. device = "/dev/video";
  63. vid = open(device, O_RDONLY);
  64. if (vid < 0)
  65. {
  66. fprintf(stderr, "Can't open %sn", device);
  67. return 1;
  68. }
  69. err = ioctl(vid, VIDIOC_QUERYCAP, &cap);
  70. if (err)
  71. {
  72. fprintf(stderr, "QUERYCAP returned error %dn", errno);
  73. return 1;
  74. }
  75. if (cap.type != V4L2_TYPE_CAPTURE)
  76. {
  77. fprintf(stderr, "Device %s is not a video capture device.n",
  78. device);
  79. return 1;
  80. }
  81. if (!(cap.flags & V4L2_FLAG_READ))
  82. {
  83. fprintf(stderr, "Device %s doesn't support read().n", device);
  84. return 1;
  85. }
  86. for (i = 0, err = 0; err == 0; ++i)
  87. {
  88. fmtd.index = i;
  89. err = ioctl(vid, VIDIOC_ENUM_CAPFMT, &fmtd);
  90. if (err) {
  91. printf("wanted format not supportedn");
  92. exit(1);
  93. }
  94. if (fmtd.pixelformat == wanted_format)
  95. break;
  96. }
  97. fmt.width = 704;
  98. fmt.height = 240;
  99. fmt.depth = fmtd.depth;
  100. fmt.flags = V4L2_FMT_FLAG_TOPFIELD | V4L2_FMT_FLAG_BOTFIELD;
  101. fmt.pixelformat = fmtd.pixelformat;
  102. if (ioctl(vid, VIDIOC_S_FMT, &fmt)) {
  103. fprintf(stderr, "G_FMT returned error %dn", errno);
  104. return 1;
  105. }
  106. if (start_capturing()) {
  107. fprintf(stderr, "Could not create cap buffersn");
  108. exit(1);
  109. }
  110. for(i=0; i < 60 * 30; i++) {
  111. FD_ZERO(&rdset);
  112. FD_SET(vid, &rdset);
  113. timeout.tv_sec = 1;
  114. timeout.tv_usec = 0;
  115. n = select(vid + 1, &rdset, NULL, NULL, &timeout);
  116. err = -1;
  117. if (n == -1)
  118. fprintf(stderr, "select error.n");
  119. else if (n == 0)
  120. fprintf(stderr, "select timeoutn");
  121. else if (FD_ISSET(vid, &rdset))
  122. err = 0;
  123. if (err == 0)
  124. {
  125. tempbuf.type = vimage[0].vidbuf.type;
  126. err = ioctl(vid, VIDIOC_DQBUF, &tempbuf);
  127. if (err)
  128. printf("DQBUF returned error %dn",
  129.        errno);
  130. err = ioctl(vid, VIDIOC_QBUF, &tempbuf);
  131. if (err)
  132. printf("QBUF returned error %dn",
  133.        errno);
  134. }
  135. }
  136. return 0;
  137. }
  138. int 
  139. start_capturing()
  140. {
  141. struct v4l2_requestbuffers req;
  142. int err;
  143. int i;
  144. req.count = STREAMBUFS;
  145. req.type = V4L2_BUF_TYPE_CAPTURE;
  146. err = ioctl(vid, VIDIOC_REQBUFS, &req);
  147. if (err < 0 || req.count < 1)
  148. {
  149. printf("REQBUFS returned error %d, count %dn",
  150.        errno,req.count);
  151. return 1;
  152. }
  153. for (i = 0; i < req.count; ++i)
  154. {
  155. vimage[i].vidbuf.index = i;
  156. vimage[i].vidbuf.type = V4L2_BUF_TYPE_CAPTURE;
  157. err = ioctl(vid, VIDIOC_QUERYBUF, &vimage[i].vidbuf);
  158. if (err < 0)
  159. {
  160. printf("QUERYBUF returned error %dn",errno);
  161. return 1;
  162. }
  163. vimage[i].data = mmap(0, vimage[i].vidbuf.length, PROT_READ,
  164.       MAP_SHARED, vid, 
  165.       vimage[i].vidbuf.offset);
  166. if ((int)vimage[i].data == -1)
  167. {
  168. printf("mmap() returned error %dn", errno);
  169. return 1;
  170. }
  171. }
  172. for (i = 0; i < req.count; ++i)
  173. if ((err = ioctl(vid, VIDIOC_QBUF, &vimage[i].vidbuf)))
  174. {
  175. printf("QBUF returned error %dn",errno);
  176. return 1;
  177. }
  178. err = ioctl(vid, VIDIOC_STREAMON, vimage[0].vidbuf.type);
  179. if (err)
  180. printf("STREAMON returned error %dn",errno);
  181. return 0;
  182. }