[PATCH/RFC 11/32] libcamera: v4l2_subdevice: Update to the new kernel routing API
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Fri Mar 1 22:21:00 CET 2024
The subdev embedded data support series includes a change to the
VIDIOC_SUBDEV_G_ROUTING and VIDIOC_SUBDEV_S_ROUTING ioctls that impacts
the userspace API.
Update to the new API. Backward compatibility can't be easily preserved
as the ioctl structure size has changed. This is not a major issue, as
the routing API isn't enabled in any upstream kernel.
Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
src/libcamera/v4l2_subdevice.cpp | 43 ++++++++++++++++++++++++++------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp
index 3653f57a7d10..d5d400cdfd58 100644
--- a/src/libcamera/v4l2_subdevice.cpp
+++ b/src/libcamera/v4l2_subdevice.cpp
@@ -1332,19 +1332,23 @@ int V4L2Subdevice::getRouting(Routing *routing, Whence whence)
rt.which = whence;
int ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt);
- if (ret == 0 || ret == -ENOTTY)
- return ret;
-
- if (ret != -ENOSPC) {
- LOG(V4L2, Error)
- << "Failed to retrieve number of routes: "
- << strerror(-ret);
+ if (ret) {
+ if (ret != -ENOTTY)
+ LOG(V4L2, Error)
+ << "Failed to retrieve number of routes: "
+ << strerror(-ret);
return ret;
}
+ if (!rt.num_routes)
+ return 0;
+
std::vector<struct v4l2_subdev_route> routes{ rt.num_routes };
rt.routes = reinterpret_cast<uintptr_t>(routes.data());
+ rt.len_routes = rt.num_routes;
+ rt.num_routes = 0;
+
ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt);
if (ret) {
LOG(V4L2, Error)
@@ -1391,6 +1395,7 @@ int V4L2Subdevice::setRouting(Routing *routing, Whence whence)
struct v4l2_subdev_routing rt = {};
rt.which = whence;
+ rt.len_routes = routes.size();
rt.num_routes = routes.size();
rt.routes = reinterpret_cast<uintptr_t>(routes.data());
@@ -1400,7 +1405,29 @@ int V4L2Subdevice::setRouting(Routing *routing, Whence whence)
return ret;
}
- routes.resize(rt.num_routes);
+ /*
+ * The kernel wants to return more routes than we have space for. We
+ * need to issue a VIDIOC_SUBDEV_G_ROUTING call.
+ */
+ if (rt.num_routes > routes.size()) {
+ routes.resize(rt.num_routes);
+
+ rt.len_routes = rt.num_routes;
+ rt.num_routes = 0;
+
+ ret = ioctl(VIDIOC_SUBDEV_G_ROUTING, &rt);
+ if (ret) {
+ LOG(V4L2, Error)
+ << "Failed to retrieve routes: " << strerror(-ret);
+ return ret;
+ }
+ }
+
+ if (rt.num_routes != routes.size()) {
+ LOG(V4L2, Error) << "Invalid number of routes";
+ return -EINVAL;
+ }
+
routing->resize(rt.num_routes);
for (const auto &[i, route] : utils::enumerate(routes))
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list