test_v4l2.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. // Reference: https://www.kernel.org/doc/html/v4.8/media/v4l-drivers/vivid.html
  5. // create 1 virtual device of type CAP (0x1) at /dev/video10
  6. // sudo modprobe vivid ndevs=1 node_types=0x1 vid_cap_nr=10
  7. // make sure user have read/write access (e.g. via group 'video')
  8. // $ ls -l /dev/video10
  9. // crw-rw----+ 1 root video ... /dev/video10
  10. // set environment variable:
  11. // export OPENCV_TEST_V4L2_VIVID_DEVICE=/dev/video10
  12. // run v4l2 tests:
  13. // opencv_test_videoio --gtest_filter=*videoio_v4l2*
  14. #ifdef HAVE_CAMV4L2
  15. // #define DUMP_CAMERA_FRAME
  16. #include "test_precomp.hpp"
  17. #include <opencv2/core/utils/configuration.private.hpp>
  18. #include <linux/videodev2.h>
  19. // workarounds for older versions
  20. #ifndef v4l2_fourcc_be
  21. #define v4l2_fourcc_be(a, b, c, d) (v4l2_fourcc(a, b, c, d) | (1U << 31))
  22. #endif
  23. #ifndef V4L2_PIX_FMT_Y10
  24. #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ')
  25. #endif
  26. #ifndef V4L2_PIX_FMT_Y12
  27. #define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ')
  28. #endif
  29. #ifndef V4L2_PIX_FMT_ABGR32
  30. #define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4')
  31. #endif
  32. #ifndef V4L2_PIX_FMT_XBGR32
  33. #define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4')
  34. #endif
  35. #ifndef V4L2_PIX_FMT_Y16
  36. #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ')
  37. #endif
  38. #ifndef V4L2_PIX_FMT_Y16_BE
  39. #define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ')
  40. #endif
  41. using namespace cv;
  42. namespace opencv_test { namespace {
  43. struct Format_Channels_Depth
  44. {
  45. uint32_t pixel_format;
  46. uint8_t channels;
  47. uint8_t depth;
  48. float mul_width;
  49. float mul_height;
  50. };
  51. typedef testing::TestWithParam<Format_Channels_Depth> videoio_v4l2;
  52. TEST_P(videoio_v4l2, formats)
  53. {
  54. utils::Paths devs = utils::getConfigurationParameterPaths("OPENCV_TEST_V4L2_VIVID_DEVICE");
  55. if (devs.size() != 1)
  56. {
  57. throw SkipTestException("OPENCV_TEST_V4L2_VIVID_DEVICE is not set");
  58. }
  59. const string device = devs[0];
  60. const Size sz(640, 480);
  61. const Format_Channels_Depth params = GetParam();
  62. const Size esz(sz.width * params.mul_width, sz.height * params.mul_height);
  63. {
  64. // Case with RAW output
  65. VideoCapture cap;
  66. ASSERT_TRUE(cap.open(device, CAP_V4L2));
  67. // VideoCapture will set device's format automatically, vivid device will accept it
  68. ASSERT_TRUE(cap.set(CAP_PROP_FOURCC, params.pixel_format));
  69. ASSERT_TRUE(cap.set(CAP_PROP_CONVERT_RGB, false));
  70. for (size_t idx = 0; idx < 3; ++idx)
  71. {
  72. Mat img;
  73. EXPECT_TRUE(cap.grab());
  74. EXPECT_TRUE(cap.retrieve(img));
  75. if (params.pixel_format == V4L2_PIX_FMT_SRGGB8 ||
  76. params.pixel_format == V4L2_PIX_FMT_SBGGR8 ||
  77. params.pixel_format == V4L2_PIX_FMT_SGBRG8 ||
  78. params.pixel_format == V4L2_PIX_FMT_SGRBG8)
  79. {
  80. EXPECT_EQ((size_t)esz.area(), img.total());
  81. }
  82. else
  83. {
  84. EXPECT_EQ(esz, img.size());
  85. }
  86. EXPECT_EQ(params.channels, img.channels());
  87. EXPECT_EQ(params.depth, img.depth());
  88. }
  89. }
  90. {
  91. // case with BGR output
  92. VideoCapture cap;
  93. ASSERT_TRUE(cap.open(device, CAP_V4L2));
  94. // VideoCapture will set device's format automatically, vivid device will accept it
  95. ASSERT_TRUE(cap.set(CAP_PROP_FOURCC, params.pixel_format));
  96. for (size_t idx = 0; idx < 3; ++idx)
  97. {
  98. Mat img;
  99. EXPECT_TRUE(cap.grab());
  100. EXPECT_TRUE(cap.retrieve(img));
  101. EXPECT_EQ(sz, img.size());
  102. EXPECT_EQ(3, img.channels());
  103. EXPECT_EQ(CV_8U, img.depth());
  104. #ifdef DUMP_CAMERA_FRAME
  105. std::string img_name = "frame_" + fourccToStringSafe(params.pixel_format);
  106. // V4L2 flag for big-endian formats
  107. if(params.pixel_format & (1 << 31))
  108. img_name += "-BE";
  109. cv::imwrite(img_name + ".png", img);
  110. #endif
  111. }
  112. }
  113. }
  114. vector<Format_Channels_Depth> all_params = {
  115. { V4L2_PIX_FMT_YVU420, 1, CV_8U, 1.f, 1.5f },
  116. { V4L2_PIX_FMT_YUV420, 1, CV_8U, 1.f, 1.5f },
  117. { V4L2_PIX_FMT_NV12, 1, CV_8U, 1.f, 1.5f },
  118. { V4L2_PIX_FMT_NV21, 1, CV_8U, 1.f, 1.5f },
  119. { V4L2_PIX_FMT_YUV411P, 3, CV_8U, 1.f, 1.f },
  120. // { V4L2_PIX_FMT_MJPEG, 1, CV_8U, 1.f, 1.f },
  121. // { V4L2_PIX_FMT_JPEG, 1, CV_8U, 1.f, 1.f },
  122. { V4L2_PIX_FMT_YUYV, 2, CV_8U, 1.f, 1.f },
  123. { V4L2_PIX_FMT_UYVY, 2, CV_8U, 1.f, 1.f },
  124. { V4L2_PIX_FMT_SN9C10X, 3, CV_8U, 1.f, 1.f },
  125. { V4L2_PIX_FMT_SRGGB8, 1, CV_8U, 1.f, 1.f },
  126. { V4L2_PIX_FMT_SBGGR8, 1, CV_8U, 1.f, 1.f },
  127. { V4L2_PIX_FMT_SGBRG8, 1, CV_8U, 1.f, 1.f },
  128. { V4L2_PIX_FMT_SGRBG8, 1, CV_8U, 1.f, 1.f },
  129. { V4L2_PIX_FMT_RGB24, 3, CV_8U, 1.f, 1.f },
  130. { V4L2_PIX_FMT_Y16, 1, CV_16U, 1.f, 1.f },
  131. { V4L2_PIX_FMT_Y16_BE, 1, CV_16U, 1.f, 1.f },
  132. { V4L2_PIX_FMT_Y10, 1, CV_16U, 1.f, 1.f },
  133. { V4L2_PIX_FMT_GREY, 1, CV_8U, 1.f, 1.f },
  134. { V4L2_PIX_FMT_BGR24, 3, CV_8U, 1.f, 1.f },
  135. { V4L2_PIX_FMT_XBGR32, 4, CV_8U, 1.f, 1.f },
  136. { V4L2_PIX_FMT_ABGR32, 4, CV_8U, 1.f, 1.f },
  137. };
  138. inline static std::string param_printer(const testing::TestParamInfo<videoio_v4l2::ParamType>& info)
  139. {
  140. return fourccToStringSafe(info.param.pixel_format);
  141. }
  142. INSTANTIATE_TEST_CASE_P(/*videoio_v4l2*/, videoio_v4l2, ValuesIn(all_params), param_printer);
  143. TEST(videoio_ffmpeg, camera_index)
  144. {
  145. utils::Paths devs = utils::getConfigurationParameterPaths("OPENCV_TEST_V4L2_VIVID_DEVICE");
  146. if (devs.size() != 1)
  147. {
  148. throw SkipTestException("OPENCV_TEST_V4L2_VIVID_DEVICE is not set");
  149. }
  150. VideoCapture cap;
  151. ASSERT_TRUE(cap.open(0, CAP_FFMPEG));
  152. Mat frame;
  153. ASSERT_TRUE(cap.read(frame));
  154. ASSERT_FALSE(frame.empty());
  155. }
  156. }} // opencv_test::<anonymous>::
  157. #endif // HAVE_CAMV4L2