Guest User

Untitled

a guest
Jan 16th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.23 KB | None | 0 0
  1. // C++ / V4L2 Includes
  2. #include <linux/videodev2.h>
  3. #include <fcntl.h> /* low-level i/o */
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <sys/stat.h>
  7. #include <sys/types.h>
  8. #include <sys/time.h>
  9. #include <sys/mman.h>
  10. #include <sys/ioctl.h>
  11. #include <cstdlib>
  12. #include <cstring>
  13. #include <iostream>
  14. #include <sstream>
  15. #include <vector>
  16.  
  17. int main(int argc, char *argv[])
  18. {
  19. int fd;
  20. if((fd = open("/dev/video0", O_RDWR)) < 0){
  21. perror("open");
  22. exit(1);
  23. }
  24.  
  25. struct v4l2_capability cap;
  26. if(ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0){
  27. perror("VIDIOC_QUERYCAP");
  28. exit(1);
  29. }
  30.  
  31. if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)){
  32. fprintf(stderr, "The device does not handle single-planar video capture.\n");
  33. exit(1);
  34. }
  35.  
  36. struct v4l2_format format;
  37. format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  38. format.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
  39. format.fmt.pix.width = 2592;
  40. format.fmt.pix.height = 1944;
  41.  
  42. if(ioctl(fd, VIDIOC_S_FMT, &format) < 0){
  43. perror("VIDIOC_S_FMT");
  44. exit(1);
  45. }
  46.  
  47. struct v4l2_requestbuffers bufrequest;
  48. bufrequest.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  49. bufrequest.memory = V4L2_MEMORY_MMAP;
  50. int old_count = bufrequest.count = 3;
  51.  
  52. if(ioctl(fd, VIDIOC_REQBUFS, &bufrequest) < 0){
  53. perror("VIDIOC_REQBUFS");
  54. exit(1);
  55. }
  56. std::cout << "old bufrequest.count = " << old_count
  57. << ", new bufrequest.count = " << bufrequest.count << std::endl;
  58.  
  59. struct buffer_t {
  60. struct v4l2_buffer info;
  61. void* start;
  62. };
  63. std::vector<struct buffer_t> buffers;
  64. for (int i = 0; i < bufrequest.count; i++) {
  65. struct v4l2_buffer bufferinfo;
  66. memset(&bufferinfo, 0, sizeof(bufferinfo));
  67. bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  68. bufferinfo.memory = V4L2_MEMORY_MMAP;
  69. bufferinfo.index = i;
  70. if(ioctl(fd, VIDIOC_QUERYBUF, &bufferinfo) < 0){
  71. perror("VIDIOC_QUERYBUF");
  72. exit(1);
  73. }
  74. void* buffer_start = mmap(
  75. NULL,
  76. bufferinfo.length,
  77. PROT_READ | PROT_WRITE,
  78. MAP_SHARED,
  79. fd,
  80. bufferinfo.m.offset
  81. );
  82. if(buffer_start == MAP_FAILED){
  83. perror("mmap");
  84. exit(1);
  85. }
  86. memset(buffer_start, 0, bufferinfo.length);
  87. // Put a buffer in the incoming queue.
  88. if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0){
  89. perror("VIDIOC_QBUF");
  90. exit(1);
  91. }
  92. buffers.emplace_back(buffer_t { bufferinfo, buffer_start });
  93. }
  94.  
  95. // Activate streaming
  96. int type = buffers[0].info.type;
  97. if(ioctl(fd, VIDIOC_STREAMON, &type) < 0){
  98. perror("VIDIOC_STREAMON");
  99. exit(1);
  100. }
  101.  
  102. /* Here is where you typically start two loops:
  103. * - One which runs for as long as you want to
  104. * capture frames (shoot the video).
  105. * - One which iterates over your buffers everytime. */
  106.  
  107. bool capture_is_running = true;
  108. int counter = 0;
  109. while(capture_is_running){
  110. for(int i = 0; i < bufrequest.count; i++){
  111. // The buffer's waiting in the outgoing queue.
  112. if(ioctl(fd, VIDIOC_DQBUF, &buffers[i].info) != 0){
  113. perror("VIDIOC_DQBUF");
  114. exit(1);
  115. }
  116.  
  117. int jpgfile;
  118. std::stringstream ss;
  119. ss << "somefile" << counter << ".jpg";
  120. if ((jpgfile = open(ss.str().c_str(), O_WRONLY | O_CREAT, 0660)) < 0) {
  121. perror("open");
  122. exit(1);
  123. }
  124. write(jpgfile, buffers[i].start, buffers[i].info.length);
  125. close(jpgfile);
  126. std::cout << "wrote file " << ss.str() << std::endl;
  127. if (++counter == 10) {
  128. capture_is_running = false;
  129. break;
  130. }
  131.  
  132. // Put a buffer in the incoming queue.
  133. if(ioctl(fd, VIDIOC_QBUF, &buffers[i].info) < 0){
  134. perror("VIDIOC_QBUF");
  135. exit(1);
  136. }
  137. }
  138.  
  139. }
  140.  
  141. // Deactivate streaming
  142. if(ioctl(fd, VIDIOC_STREAMOFF, &type) < 0){
  143. perror("VIDIOC_STREAMOFF");
  144. exit(1);
  145. }
  146.  
  147. close(fd);
  148. exit(0);
  149. }
Add Comment
Please, Sign In to add comment