v4l2-helpers.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. Copyright (C) 2014 by Leonhard Oelke <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <sys/mman.h>
  15. #include <util/bmem.h>
  16. #include "v4l2-helpers.h"
  17. #define blog(level, msg, ...) blog(level, "v4l2-helpers: " msg, ##__VA_ARGS__)
  18. int_fast32_t v4l2_start_capture(int_fast32_t dev, struct v4l2_buffer_data *buf)
  19. {
  20. enum v4l2_buf_type type;
  21. struct v4l2_buffer enq;
  22. memset(&enq, 0, sizeof(enq));
  23. enq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  24. enq.memory = V4L2_MEMORY_MMAP;
  25. for (enq.index = 0; enq.index < buf->count; ++enq.index) {
  26. if (v4l2_ioctl(dev, VIDIOC_QBUF, &enq) < 0) {
  27. blog(LOG_ERROR, "unable to queue buffer");
  28. return -1;
  29. }
  30. }
  31. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  32. if (v4l2_ioctl(dev, VIDIOC_STREAMON, &type) < 0) {
  33. blog(LOG_ERROR, "unable to start stream");
  34. return -1;
  35. }
  36. return 0;
  37. }
  38. int_fast32_t v4l2_stop_capture(int_fast32_t dev)
  39. {
  40. enum v4l2_buf_type type;
  41. type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  42. if (v4l2_ioctl(dev, VIDIOC_STREAMOFF, &type) < 0) {
  43. blog(LOG_ERROR, "unable to stop stream");
  44. return -1;
  45. }
  46. return 0;
  47. }
  48. int_fast32_t v4l2_create_mmap(int_fast32_t dev, struct v4l2_buffer_data *buf)
  49. {
  50. struct v4l2_requestbuffers req;
  51. struct v4l2_buffer map;
  52. memset(&req, 0, sizeof(req));
  53. req.count = 4;
  54. req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  55. req.memory = V4L2_MEMORY_MMAP;
  56. if (v4l2_ioctl(dev, VIDIOC_REQBUFS, &req) < 0) {
  57. blog(LOG_ERROR, "Request for buffers failed !");
  58. return -1;
  59. }
  60. if (req.count < 2) {
  61. blog(LOG_ERROR, "Device returned less than 2 buffers");
  62. return -1;
  63. }
  64. buf->count = req.count;
  65. buf->info = bzalloc(req.count * sizeof(struct v4l2_mmap_info));
  66. memset(&map, 0, sizeof(map));
  67. map.type = req.type;
  68. map.memory = req.memory;
  69. for (map.index = 0; map.index < req.count; ++map.index) {
  70. if (v4l2_ioctl(dev, VIDIOC_QUERYBUF, &map) < 0) {
  71. blog(LOG_ERROR, "Failed to query buffer details");
  72. return -1;
  73. }
  74. buf->info[map.index].length = map.length;
  75. buf->info[map.index].start = v4l2_mmap(NULL, map.length,
  76. PROT_READ | PROT_WRITE, MAP_SHARED,
  77. dev, map.m.offset);
  78. if (buf->info[map.index].start == MAP_FAILED) {
  79. blog(LOG_ERROR, "mmap for buffer failed");
  80. return -1;
  81. }
  82. }
  83. return 0;
  84. }
  85. int_fast32_t v4l2_destroy_mmap(struct v4l2_buffer_data *buf)
  86. {
  87. for(uint_fast32_t i = 0; i < buf->count; ++i) {
  88. if (buf->info[i].start != MAP_FAILED && buf->info[i].start != 0)
  89. v4l2_munmap(buf->info[i].start, buf->info[i].length);
  90. }
  91. if (buf->count) {
  92. bfree(buf->info);
  93. buf->count = 0;
  94. }
  95. return 0;
  96. }
  97. int_fast32_t v4l2_set_input(int_fast32_t dev, int *input)
  98. {
  99. if (!dev || !input)
  100. return -1;
  101. return (*input == -1)
  102. ? v4l2_ioctl(dev, VIDIOC_G_INPUT, input)
  103. : v4l2_ioctl(dev, VIDIOC_S_INPUT, input);
  104. }