diff options
| author | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2023-02-24 15:37:10 +0200 |
|---|---|---|
| committer | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2023-02-24 18:10:42 +0200 |
| commit | db5e57cdba31439ab2ae0e85c0ffc0c200ac3082 (patch) | |
| tree | 2861117f96faf0cad3ffd562034cc81e37b7e541 /v4l2++/src | |
| parent | 2bd85abc108e0688384f42b0ec83dcd5a622d50d (diff) | |
Drop v4l2
Drop (hacky) v4l2 support from kms++, and move it to a new, separate,
library.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Diffstat (limited to 'v4l2++/src')
| -rw-r--r-- | v4l2++/src/helpers.cpp | 16 | ||||
| -rw-r--r-- | v4l2++/src/pixelformats.cpp | 314 | ||||
| -rw-r--r-- | v4l2++/src/videodevice.cpp | 660 |
3 files changed, 0 insertions, 990 deletions
diff --git a/v4l2++/src/helpers.cpp b/v4l2++/src/helpers.cpp deleted file mode 100644 index d24c4f8..0000000 --- a/v4l2++/src/helpers.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include <v4l2++/helpers.h> - -void __my_throw(const char* file, int line, const char* funcname, const char* cond, fmt::string_view format, fmt::format_args args) -{ - std::string str = fmt::vformat(format, args); - - fmt::print(stderr, "{}:{}: {}:\n{}", file, line, funcname, str); - if (cond) - fmt::print(stderr, " ({})\n", cond); - else - fmt::print("\n"); - - fflush(stderr); - - throw std::runtime_error(str); -} diff --git a/v4l2++/src/pixelformats.cpp b/v4l2++/src/pixelformats.cpp deleted file mode 100644 index f892c97..0000000 --- a/v4l2++/src/pixelformats.cpp +++ /dev/null @@ -1,314 +0,0 @@ -#include <map> - -#include <v4l2++/pixelformats.h> - -using namespace std; - -namespace v4l2 -{ -static const map<PixelFormat, PixelFormatInfo> format_info_array = { - /* YUV packed */ - { PixelFormat::UYVY, { - PixelColorType::YUV, - 1, - { { 16, 2, 1 } }, - } }, - { PixelFormat::YUYV, { - PixelColorType::YUV, - 1, - { { 16, 2, 1 } }, - } }, - { PixelFormat::YVYU, { - PixelColorType::YUV, - 1, - { { 16, 2, 1 } }, - } }, - { PixelFormat::VYUY, { - PixelColorType::YUV, - 1, - { { 16, 2, 1 } }, - } }, - /* YUV semi-planar */ - { PixelFormat::NV12, { - PixelColorType::YUV, - 2, - { { - 8, - 1, - 1, - }, - { 8, 2, 2 } }, - } }, - { PixelFormat::NV21, { - PixelColorType::YUV, - 2, - { { - 8, - 1, - 1, - }, - { 8, 2, 2 } }, - } }, - { PixelFormat::NV16, { - PixelColorType::YUV, - 2, - { { - 8, - 1, - 1, - }, - { 8, 2, 1 } }, - } }, - { PixelFormat::NV61, { - PixelColorType::YUV, - 2, - { { - 8, - 1, - 1, - }, - { 8, 2, 1 } }, - } }, - /* YUV planar */ - { PixelFormat::YUV420, { - PixelColorType::YUV, - 3, - { { - 8, - 1, - 1, - }, - { 8, 2, 2 }, - { 8, 2, 2 } }, - } }, - { PixelFormat::YVU420, { - PixelColorType::YUV, - 3, - { { - 8, - 1, - 1, - }, - { 8, 2, 2 }, - { 8, 2, 2 } }, - } }, - { PixelFormat::YUV422, { - PixelColorType::YUV, - 3, - { { - 8, - 1, - 1, - }, - { 8, 2, 1 }, - { 8, 2, 1 } }, - } }, - { PixelFormat::YVU422, { - PixelColorType::YUV, - 3, - { { - 8, - 1, - 1, - }, - { 8, 2, 1 }, - { 8, 2, 1 } }, - } }, - { PixelFormat::YUV444, { - PixelColorType::YUV, - 3, - { { - 8, - 1, - 1, - }, - { 8, 1, 1 }, - { 8, 1, 1 } }, - } }, - { PixelFormat::YVU444, { - PixelColorType::YUV, - 3, - { { - 8, - 1, - 1, - }, - { 8, 1, 1 }, - { 8, 1, 1 } }, - } }, - /* RGB8 */ - { PixelFormat::RGB332, { - PixelColorType::RGB, - 1, - { { 8, 1, 1 } }, - } }, - /* RGB16 */ - { PixelFormat::RGB565, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::BGR565, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::XRGB4444, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::XRGB1555, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::ARGB4444, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::ARGB1555, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, - /* RGB24 */ - { PixelFormat::RGB888, { - PixelColorType::RGB, - 1, - { { 24, 1, 1 } }, - } }, - { PixelFormat::BGR888, { - PixelColorType::RGB, - 1, - { { 24, 1, 1 } }, - } }, - /* RGB32 */ - { PixelFormat::XRGB8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::XBGR8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::RGBX8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::BGRX8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - - { PixelFormat::ARGB8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::ABGR8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::RGBA8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::BGRA8888, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - - { PixelFormat::XRGB2101010, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::XBGR2101010, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::RGBX1010102, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::BGRX1010102, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - - { PixelFormat::ARGB2101010, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::ABGR2101010, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::RGBA1010102, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::BGRA1010102, { - PixelColorType::RGB, - 1, - { { 32, 1, 1 } }, - } }, - { PixelFormat::SBGGR12, { - PixelColorType::RAW, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::SRGGB12, { - PixelColorType::RAW, - 1, - { { 16, 1, 1 } }, - } }, - { PixelFormat::META_8, { - PixelColorType::RGB, - 1, - { { 8, 1, 1 } }, - } }, - { PixelFormat::META_16, { - PixelColorType::RGB, - 1, - { { 16, 1, 1 } }, - } }, -}; - -PixelFormat DRMFourCCToPixelFormat(const std::string& fourcc) -{ - // Handle the formats which differ between DRM and V4L2 - if (fourcc == "RG16") - return PixelFormat::RGB565; - if (fourcc == "XR24") - return PixelFormat::XRGB8888; - if (fourcc == "RG24") - return PixelFormat::RGB888; - - return FourCCToPixelFormat(fourcc); -} - -const struct PixelFormatInfo& get_pixel_format_info(PixelFormat format) -{ - if (!format_info_array.count(format)) - throw invalid_argument("v4l2: get_pixel_format_info: Unsupported pixelformat"); - - return format_info_array.at(format); -} - -} // namespace v4l2 diff --git a/v4l2++/src/videodevice.cpp b/v4l2++/src/videodevice.cpp deleted file mode 100644 index 909cb1b..0000000 --- a/v4l2++/src/videodevice.cpp +++ /dev/null @@ -1,660 +0,0 @@ -#include <string> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <linux/videodev2.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <system_error> - -#include <v4l2++/videodevice.h> -#include <v4l2++/helpers.h> - -using namespace std; -using namespace v4l2; - -/* - * V4L2 and DRM differ in their interpretation of YUV420::NV12 - * - * V4L2 NV12 is a Y and UV co-located planes in a single plane buffer. - * DRM NV12 is a Y and UV planes presented as dual plane buffer, - * which is known as NM12 in V4L2. - * - * Since here we have hybrid DRM/V4L2 user space helper functions - * we need to translate DRM::NV12 to V4L2:NM12 pixel format back - * and forth to keep the data view consistent. - */ - -static v4l2_memory get_mem_type(VideoMemoryType type) -{ - switch (type) { - case VideoMemoryType::MMAP: - return V4L2_MEMORY_MMAP; - case VideoMemoryType::DMABUF: - return V4L2_MEMORY_DMABUF; - default: - FAIL("Bad VideoMemoryType"); - } -} - -/* V4L2 helper funcs */ -static vector<PixelFormat> v4l2_get_formats(int fd, uint32_t buf_type) -{ - vector<PixelFormat> v; - - v4l2_fmtdesc desc{}; - desc.type = buf_type; - - while (ioctl(fd, VIDIOC_ENUM_FMT, &desc) == 0) { - if (desc.pixelformat == V4L2_PIX_FMT_NV12M) - v.push_back(PixelFormat::NV12); - else if (desc.pixelformat != V4L2_PIX_FMT_NV12) - v.push_back((PixelFormat)desc.pixelformat); - - desc.index++; - } - - return v; -} - -static int v4l2_get_format(int fd, uint32_t buf_type, PixelFormat& fmt, uint32_t& width, uint32_t& height) -{ - int r; - - v4l2_format v4lfmt{}; - - v4lfmt.type = buf_type; - r = ioctl(fd, VIDIOC_G_FMT, &v4lfmt); - ASSERT(r == 0); - - bool mplane = buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - FAIL_IF(mplane, "mplane not supported"); - - fmt = (PixelFormat)v4lfmt.fmt.pix.pixelformat; - width = v4lfmt.fmt.pix.width; - height = v4lfmt.fmt.pix.height; - - return 0; -} - -static void v4l2_set_format(int fd, PixelFormat fmt, uint32_t width, uint32_t height, uint32_t buf_type) -{ - int r; - - v4l2_format v4lfmt{}; - - v4lfmt.type = buf_type; - r = ioctl(fd, VIDIOC_G_FMT, &v4lfmt); - ASSERT(r == 0); - - const PixelFormatInfo& pfi = get_pixel_format_info(fmt); - - bool mplane = buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - if (mplane) { - v4l2_pix_format_mplane& mp = v4lfmt.fmt.pix_mp; - uint32_t used_fmt; - - if (fmt == PixelFormat::NV12) - used_fmt = V4L2_PIX_FMT_NV12M; - else - used_fmt = (uint32_t)fmt; - - mp.pixelformat = used_fmt; - mp.width = width; - mp.height = height; - - mp.num_planes = pfi.num_planes; - - for (unsigned i = 0; i < pfi.num_planes; ++i) { - const PixelFormatPlaneInfo& pfpi = pfi.planes[i]; - v4l2_plane_pix_format& p = mp.plane_fmt[i]; - - p.bytesperline = width * pfpi.bitspp / 8; - p.sizeimage = p.bytesperline * height / pfpi.ysub; - } - - r = ioctl(fd, VIDIOC_S_FMT, &v4lfmt); - ASSERT(r == 0); - - ASSERT(mp.pixelformat == used_fmt); - ASSERT(mp.width == width); - ASSERT(mp.height == height); - - ASSERT(mp.num_planes == pfi.num_planes); - - for (unsigned i = 0; i < pfi.num_planes; ++i) { - const PixelFormatPlaneInfo& pfpi = pfi.planes[i]; - v4l2_plane_pix_format& p = mp.plane_fmt[i]; - - ASSERT(p.bytesperline == width * pfpi.bitspp / 8); - ASSERT(p.sizeimage == p.bytesperline * height / pfpi.ysub); - } - } else { - v4lfmt.fmt.pix.pixelformat = (uint32_t)fmt; - v4lfmt.fmt.pix.width = width; - v4lfmt.fmt.pix.height = height; - v4lfmt.fmt.pix.bytesperline = width * pfi.planes[0].bitspp / 8; - v4lfmt.fmt.pix.field = V4L2_FIELD_NONE; - - r = ioctl(fd, VIDIOC_S_FMT, &v4lfmt); - ASSERT(r == 0); - - ASSERT(v4lfmt.fmt.pix.pixelformat == (uint32_t)fmt); - ASSERT(v4lfmt.fmt.pix.width == width); - ASSERT(v4lfmt.fmt.pix.height == height); - ASSERT(v4lfmt.fmt.pix.bytesperline == width * pfi.planes[0].bitspp / 8); - } -} - -static void v4l2_get_selection(int fd, uint32_t& left, uint32_t& top, uint32_t& width, uint32_t& height, uint32_t buf_type) -{ - int r; - struct v4l2_selection selection; - - if (buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT || - buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - selection.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - selection.target = V4L2_SEL_TGT_CROP; - } else if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - selection.target = V4L2_SEL_TGT_COMPOSE; - } else { - FAIL("buf_type (%d) is not valid\n", buf_type); - } - - r = ioctl(fd, VIDIOC_G_SELECTION, &selection); - ASSERT(r == 0); - - left = selection.r.left; - top = selection.r.top; - width = selection.r.width; - height = selection.r.height; -} - -static void v4l2_set_selection(int fd, uint32_t& left, uint32_t& top, uint32_t& width, uint32_t& height, uint32_t buf_type) -{ - int r; - struct v4l2_selection selection; - - if (buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT || - buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - selection.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - selection.target = V4L2_SEL_TGT_CROP; - } else if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - selection.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - selection.target = V4L2_SEL_TGT_COMPOSE; - } else { - FAIL("buf_type (%d) is not valid\n", buf_type); - } - - selection.r.left = left; - selection.r.top = top; - selection.r.width = width; - selection.r.height = height; - - r = ioctl(fd, VIDIOC_S_SELECTION, &selection); - ASSERT(r == 0); - - left = selection.r.left; - top = selection.r.top; - width = selection.r.width; - height = selection.r.height; -} - -static void v4l2_request_bufs(int fd, uint32_t queue_size, uint32_t buf_type, uint32_t mem_type) -{ - v4l2_requestbuffers v4lreqbuf{}; - v4lreqbuf.type = buf_type; - v4lreqbuf.memory = mem_type; - v4lreqbuf.count = queue_size; - int r = ioctl(fd, VIDIOC_REQBUFS, &v4lreqbuf); - FAIL_IF(r != 0, "VIDIOC_REQBUFS failed: %d", errno); - ASSERT(v4lreqbuf.count == queue_size); -} - -static void v4l2_queue(int fd, VideoBuffer& fb, uint32_t buf_type) -{ - v4l2_buffer buf{}; - buf.type = buf_type; - buf.memory = get_mem_type(fb.m_mem_type); - buf.index = fb.m_index; - - bool mplane = buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || buf_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - - if (mplane) { - ASSERT(false); - /* - const PixelFormatInfo& pfi = get_pixel_format_info(fb->m_format); - - buf.length = pfi.num_planes; - - v4l2_plane planes[4]{}; - buf.m.planes = planes; - - for (unsigned i = 0; i < pfi.num_planes; ++i) { - planes[i].m.fd = fb->prime_fd(i); - planes[i].bytesused = fb->size(i); - planes[i].length = fb->size(i); - } - - int r = ioctl(fd, VIDIOC_QBUF, &buf); - ASSERT(r == 0); - */ - } else { - if (fb.m_mem_type == VideoMemoryType::DMABUF) - buf.m.fd = fb.m_fd; - - int r = ioctl(fd, VIDIOC_QBUF, &buf); - ASSERT(r == 0); - } -} - -static uint32_t v4l2_dequeue(int fd, VideoBuffer& fb, uint32_t buf_type) -{ - v4l2_buffer buf{}; - buf.type = buf_type; - buf.memory = get_mem_type(fb.m_mem_type); - - // V4L2 crashes if planes are not set - v4l2_plane planes[4]{}; - buf.m.planes = planes; - buf.length = 4; - - int r = ioctl(fd, VIDIOC_DQBUF, &buf); - if (r) - throw system_error(errno, generic_category()); - - fb.m_index = buf.index; - fb.m_length = buf.length; - - if (fb.m_mem_type == VideoMemoryType::DMABUF) - fb.m_fd = buf.m.fd; - else - fb.m_offset = buf.m.offset; - - return buf.index; -} - -VideoDevice::VideoDevice(const string& dev) - : VideoDevice(::open(dev.c_str(), O_RDWR | O_NONBLOCK)) -{ -} - -VideoDevice::VideoDevice(int fd) - : m_fd(fd) -{ - if (fd < 0) - throw runtime_error("bad fd"); - - struct v4l2_capability cap = {}; - int r = ioctl(fd, VIDIOC_QUERYCAP, &cap); - ASSERT(r == 0); - - if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) { - m_has_capture = true; - m_has_mplane_capture = true; - } else if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { - m_has_capture = true; - m_has_mplane_capture = false; - } - - if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE) { - m_has_output = true; - m_has_mplane_output = true; - } else if (cap.capabilities & V4L2_CAP_VIDEO_OUTPUT) { - m_has_output = true; - m_has_mplane_output = false; - } - - if (cap.capabilities & V4L2_CAP_VIDEO_M2M_MPLANE) { - m_has_m2m = true; - m_has_capture = true; - m_has_output = true; - m_has_mplane_m2m = true; - m_has_mplane_capture = true; - m_has_mplane_output = true; - } else if (cap.capabilities & V4L2_CAP_VIDEO_M2M) { - m_has_m2m = true; - m_has_capture = true; - m_has_output = true; - m_has_mplane_m2m = false; - m_has_mplane_capture = false; - m_has_mplane_output = false; - } - - if (cap.capabilities & V4L2_CAP_META_CAPTURE) { - m_has_meta_capture = true; - } -} - -VideoDevice::~VideoDevice() -{ - ::close(m_fd); -} - -VideoStreamer* VideoDevice::get_capture_streamer() -{ - ASSERT(m_has_capture); - - if (!m_capture_streamer) { - auto type = m_has_mplane_capture ? VideoStreamer::StreamerType::CaptureMulti : VideoStreamer::StreamerType::CaptureSingle; - m_capture_streamer = std::unique_ptr<VideoStreamer>(new VideoStreamer(m_fd, type)); - } - - return m_capture_streamer.get(); -} - -VideoStreamer* VideoDevice::get_output_streamer() -{ - ASSERT(m_has_output); - - if (!m_output_streamer) { - auto type = m_has_mplane_output ? VideoStreamer::StreamerType::OutputMulti : VideoStreamer::StreamerType::OutputSingle; - m_output_streamer = std::unique_ptr<VideoStreamer>(new VideoStreamer(m_fd, type)); - } - - return m_output_streamer.get(); -} - -MetaStreamer* VideoDevice::get_meta_capture_streamer() -{ - ASSERT(m_has_meta_capture); - - if (!m_meta_capture_streamer) - m_meta_capture_streamer = make_unique<MetaStreamer>(m_fd, MetaStreamer::StreamerType::CaptureMeta); - - return m_meta_capture_streamer.get(); -} - -vector<tuple<uint32_t, uint32_t>> VideoDevice::get_discrete_frame_sizes(PixelFormat fmt) -{ - vector<tuple<uint32_t, uint32_t>> v; - - v4l2_frmsizeenum v4lfrms{}; - v4lfrms.pixel_format = (uint32_t)fmt; - - int r = ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms); - ASSERT(r); - - FAIL_IF(v4lfrms.type != V4L2_FRMSIZE_TYPE_DISCRETE, "No discrete frame sizes"); - - while (ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms) == 0) { - v.emplace_back(v4lfrms.discrete.width, v4lfrms.discrete.height); - v4lfrms.index++; - }; - - return v; -} - -VideoDevice::VideoFrameSize VideoDevice::get_frame_sizes(PixelFormat fmt) -{ - v4l2_frmsizeenum v4lfrms{}; - v4lfrms.pixel_format = (uint32_t)fmt; - - int r = ioctl(m_fd, VIDIOC_ENUM_FRAMESIZES, &v4lfrms); - ASSERT(r); - - FAIL_IF(v4lfrms.type == V4L2_FRMSIZE_TYPE_DISCRETE, "No continuous frame sizes"); - - VideoFrameSize s; - - s.min_w = v4lfrms.stepwise.min_width; - s.max_w = v4lfrms.stepwise.max_width; - s.step_w = v4lfrms.stepwise.step_width; - - s.min_h = v4lfrms.stepwise.min_height; - s.max_h = v4lfrms.stepwise.max_height; - s.step_h = v4lfrms.stepwise.step_height; - - return s; -} - -vector<string> VideoDevice::get_capture_devices() -{ - vector<string> v; - - for (int i = 0; i < 20; ++i) { - string name = "/dev/video" + to_string(i); - - struct stat buffer; - if (stat(name.c_str(), &buffer) != 0) - continue; - - try { - VideoDevice vid(name); - - if (vid.has_capture() && !vid.has_m2m()) - v.push_back(name); - } catch (...) { - } - } - - return v; -} - -vector<string> VideoDevice::get_m2m_devices() -{ - vector<string> v; - - for (int i = 0; i < 20; ++i) { - string name = "/dev/video" + to_string(i); - - struct stat buffer; - if (stat(name.c_str(), &buffer) != 0) - continue; - - try { - VideoDevice vid(name); - - if (vid.has_m2m()) - v.push_back(name); - } catch (...) { - } - } - - return v; -} - -VideoStreamer::VideoStreamer(int fd, StreamerType type) - : m_fd(fd), m_type(type) -{ -} - -std::vector<string> VideoStreamer::get_ports() -{ - vector<string> v; - - switch (m_type) { - case StreamerType::CaptureSingle: - case StreamerType::CaptureMulti: { - struct v4l2_input input { - }; - - while (ioctl(m_fd, VIDIOC_ENUMINPUT, &input) == 0) { - v.push_back(string((char*)&input.name)); - input.index++; - } - - break; - } - - case StreamerType::OutputSingle: - case StreamerType::OutputMulti: { - struct v4l2_output output { - }; - - while (ioctl(m_fd, VIDIOC_ENUMOUTPUT, &output) == 0) { - v.push_back(string((char*)&output.name)); - output.index++; - } - - break; - } - - default: - FAIL("Bad StreamerType"); - } - - return v; -} - -void VideoStreamer::set_port(uint32_t index) -{ - unsigned long req; - - switch (m_type) { - case StreamerType::CaptureSingle: - case StreamerType::CaptureMulti: - req = VIDIOC_S_INPUT; - break; - - case StreamerType::OutputSingle: - case StreamerType::OutputMulti: - req = VIDIOC_S_OUTPUT; - break; - - default: - FAIL("Bad StreamerType"); - } - - int r = ioctl(m_fd, req, &index); - ASSERT(r == 0); -} - -static v4l2_buf_type get_buf_type(VideoStreamer::StreamerType type) -{ - switch (type) { - case VideoStreamer::StreamerType::CaptureSingle: - return V4L2_BUF_TYPE_VIDEO_CAPTURE; - case VideoStreamer::StreamerType::CaptureMulti: - return V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - case VideoStreamer::StreamerType::OutputSingle: - return V4L2_BUF_TYPE_VIDEO_OUTPUT; - case VideoStreamer::StreamerType::OutputMulti: - return V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - case MetaStreamer::StreamerType::CaptureMeta: - return V4L2_BUF_TYPE_META_CAPTURE; - case MetaStreamer::StreamerType::OutputMeta: - return (v4l2_buf_type)14; // XXX V4L2_BUF_TYPE_META_OUTPUT; - default: - FAIL("Bad StreamerType"); - } -} - -std::vector<PixelFormat> VideoStreamer::get_formats() -{ - return v4l2_get_formats(m_fd, get_buf_type(m_type)); -} - -int VideoStreamer::get_format(PixelFormat& fmt, uint32_t& width, uint32_t& height) -{ - return v4l2_get_format(m_fd, get_buf_type(m_type), fmt, width, height); -} - -void VideoStreamer::set_format(PixelFormat fmt, uint32_t width, uint32_t height) -{ - v4l2_set_format(m_fd, fmt, width, height, get_buf_type(m_type)); -} - -void VideoStreamer::get_selection(uint32_t& left, uint32_t& top, uint32_t& width, uint32_t& height) -{ - v4l2_get_selection(m_fd, left, top, width, height, get_buf_type(m_type)); -} - -void VideoStreamer::set_selection(uint32_t& left, uint32_t& top, uint32_t& width, uint32_t& height) -{ - v4l2_set_selection(m_fd, left, top, width, height, get_buf_type(m_type)); -} - -void VideoStreamer::set_queue_size(uint32_t queue_size, VideoMemoryType mem_type) -{ - m_mem_type = mem_type; - - v4l2_request_bufs(m_fd, queue_size, get_buf_type(m_type), get_mem_type(m_mem_type)); - - m_fbs.resize(queue_size); -} - -void VideoStreamer::queue(VideoBuffer& fb) -{ - uint32_t idx; - - for (idx = 0; idx < m_fbs.size(); ++idx) { - if (m_fbs[idx] == false) - break; - } - - FAIL_IF(idx == m_fbs.size(), "queue full"); - - fb.m_index = idx; - - m_fbs[idx] = true; - - v4l2_queue(m_fd, fb, get_buf_type(m_type)); -} - -VideoBuffer VideoStreamer::dequeue() -{ - VideoBuffer fb{}; - fb.m_mem_type = m_mem_type; - - uint32_t idx = v4l2_dequeue(m_fd, fb, get_buf_type(m_type)); - - m_fbs[idx] = false; - - return fb; -} - -void VideoStreamer::stream_on() -{ - uint32_t buf_type = get_buf_type(m_type); - int r = ioctl(m_fd, VIDIOC_STREAMON, &buf_type); - FAIL_IF(r, "Failed to enable stream: %d", r); -} - -void VideoStreamer::stream_off() -{ - uint32_t buf_type = get_buf_type(m_type); - int r = ioctl(m_fd, VIDIOC_STREAMOFF, &buf_type); - FAIL_IF(r, "Failed to disable stream: %d", r); -} - -int VideoStreamer::export_buffer(uint32_t index) -{ - struct v4l2_exportbuffer expbuf; - - memset(&expbuf, 0, sizeof(expbuf)); - expbuf.type = get_buf_type(m_type); - expbuf.index = index; - int r = ioctl(m_fd, VIDIOC_EXPBUF, &expbuf); - FAIL_IF(r, "VIDIOC_EXPBUF failed: %d", r); - - return expbuf.fd; -} - -MetaStreamer::MetaStreamer(int fd, StreamerType type) - : VideoStreamer(fd, type) -{ -} - -void MetaStreamer::set_format(PixelFormat fmt, uint32_t size) -{ - int r; - - v4l2_format v4lfmt{}; - - v4lfmt.type = get_buf_type(m_type); - //r = ioctl(m_fd, VIDIOC_G_FMT, &v4lfmt); - //ASSERT(r == 0); - - v4lfmt.fmt.meta.dataformat = (uint32_t)fmt; - v4lfmt.fmt.meta.buffersize = size; - - r = ioctl(m_fd, VIDIOC_S_FMT, &v4lfmt); - ASSERT(r == 0); -} |
