From 4097a83c68b89a70179244da01db0691a6c7c269 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Mon, 29 Oct 2018 12:15:09 -0500 Subject: videodevice: Add selection API support Add selection API support to the VideoSteamer class. Signed-off-by: Benoit Parrot --- kms++util/inc/kms++util/videodevice.h | 2 ++ kms++util/src/videodevice.cpp | 67 +++++++++++++++++++++++++++++++++++ py/pykms/pyvid.cpp | 9 +++++ 3 files changed, 78 insertions(+) diff --git a/kms++util/inc/kms++util/videodevice.h b/kms++util/inc/kms++util/videodevice.h index 68e2b01..e089bcd 100644 --- a/kms++util/inc/kms++util/videodevice.h +++ b/kms++util/inc/kms++util/videodevice.h @@ -71,6 +71,8 @@ public: std::vector get_formats(); void set_format(kms::PixelFormat fmt, uint32_t width, uint32_t height); + void get_selection(uint32_t& left, uint32_t& top, uint32_t& width, uint32_t& height); + void set_selection(uint32_t& left, uint32_t& top, uint32_t& width, uint32_t& height); void set_queue_size(uint32_t queue_size); void queue(kms::DumbFramebuffer* fb); kms::DumbFramebuffer* dequeue(); diff --git a/kms++util/src/videodevice.cpp b/kms++util/src/videodevice.cpp index efe1678..cc11357 100644 --- a/kms++util/src/videodevice.cpp +++ b/kms++util/src/videodevice.cpp @@ -96,6 +96,63 @@ static void v4l2_set_format(int fd, PixelFormat fmt, uint32_t width, uint32_t he } } +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) { v4l2_requestbuffers v4lreqbuf { }; @@ -414,6 +471,16 @@ 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) { v4l2_request_bufs(m_fd, queue_size, get_buf_type(m_type)); diff --git a/py/pykms/pyvid.cpp b/py/pykms/pyvid.cpp index 92006c4..8b0450a 100644 --- a/py/pykms/pyvid.cpp +++ b/py/pykms/pyvid.cpp @@ -30,6 +30,15 @@ void init_pyvid(py::module &m) .def("set_port", &VideoStreamer::set_port) .def_property_readonly("formats", &VideoStreamer::get_formats) .def("set_format", &VideoStreamer::set_format) + .def("get_selection", [](VideoStreamer *self) { + uint32_t left, top, width, height; + self->get_selection(left, top, width, height); + return make_tuple(left, top, width, height); + } ) + .def("set_selection", [](VideoStreamer *self, uint32_t left, uint32_t top, uint32_t width, uint32_t height) { + self->set_selection(left, top, width, height); + return make_tuple(left, top, width, height); + } ) .def("set_queue_size", &VideoStreamer::set_queue_size) .def("queue", &VideoStreamer::queue) .def("dequeue", &VideoStreamer::dequeue) -- cgit v1.2.3