Patch Detail
Show a patch.
GET /api/1.1/patches/21215/?format=api
{ "id": 21215, "url": "https://patchwork.libcamera.org/api/1.1/patches/21215/?format=api", "web_url": "https://patchwork.libcamera.org/patch/21215/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20240910173327.49377-1-kieran.bingham@ideasonboard.com>", "date": "2024-09-10T17:33:27", "name": "[v4] v4l2: Support setting frame rate in the V4L2 Adaptation layer", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "61b1fdcca625b6d2fca3d9daf1fec0d3355f194c", "submitter": { "id": 4, "url": "https://patchwork.libcamera.org/api/1.1/people/4/?format=api", "name": "Kieran Bingham", "email": "kieran.bingham@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/21215/mbox/", "series": [ { "id": 4574, "url": "https://patchwork.libcamera.org/api/1.1/series/4574/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4574", "date": "2024-09-10T17:33:27", "name": "[v4] v4l2: Support setting frame rate in the V4L2 Adaptation layer", "version": 4, "mbox": "https://patchwork.libcamera.org/series/4574/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/21215/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/21215/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 74CC8BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 10 Sep 2024 17:33:33 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 16F73634FC;\n\tTue, 10 Sep 2024 19:33:33 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 24FA7634E4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 10 Sep 2024 19:33:31 +0200 (CEST)", "from charm.tail69b4.ts.net (213-229-8-243.static.upcbusiness.at\n\t[213.229.8.243])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 25BFCFF1;\n\tTue, 10 Sep 2024 19:32:14 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Iz5WZEHj\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1725989534;\n\tbh=1fGMJ66Tc26JmVii3IbU7/7CITBAfGZdTIJveCJaW70=;\n\th=From:To:Cc:Subject:Date:From;\n\tb=Iz5WZEHjaYbN8Z8u1eX/xlddJf+c2hIoFOPFgL2tepzfmUbX5/y5x0uypdpH7QYKp\n\trUsyiU26zApVT91Ss91jWlqR966gCJRDpSJhbL6KB6L4oywZAIcc2D6l1h2WRXpIJN\n\t4anWkFuVlkmYXy4l4zdjNz7BiUUSAO684jNW7+os=", "From": "Kieran Bingham <kieran.bingham@ideasonboard.com>", "To": "libcamera devel <libcamera-devel@lists.libcamera.org>", "Cc": "Nejc Galof <galof.nejc@gmail.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>", "Subject": "[PATCH v4] v4l2: Support setting frame rate in the V4L2 Adaptation\n\tlayer", "Date": "Tue, 10 Sep 2024 19:33:27 +0200", "Message-ID": "<20240910173327.49377-1-kieran.bingham@ideasonboard.com>", "X-Mailer": "git-send-email 2.46.0", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "From: Nejc Galof <galof.nejc@gmail.com>\n\nThe V4L2 adaptation layer can already support streaming with components\nsuch as OpenCV, however it is not accepting, or handling any requests to\nconfigure the frame rate.\n\nIn V4L2 the frame rate is set by configuring the timeperframe component\nof the v4l2_streamparm structure through the VIDIOC_S_PARM ioctl.\n\nExtend the V4L2 compatibility layer to accept the VIDIOC_S_PARM ioctls\nand provide an interface for setting controls on the V4L2Camera class to\nset the requested rate when starting the camera.\n\nSigned-off-by: Nejc Galof <galof.nejc@gmail.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nSigned-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n\nv4: Handle rebase conflicts only.\n\n src/v4l2/v4l2_camera.cpp | 12 +++++++++---\n src/v4l2/v4l2_camera.h | 5 +++++\n src/v4l2/v4l2_camera_proxy.cpp | 24 ++++++++++++++++++++++++\n src/v4l2/v4l2_camera_proxy.h | 1 +\n 4 files changed, 39 insertions(+), 3 deletions(-)", "diff": "diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp\nindex 0f3b862f5bc3..94d138cd5710 100644\n--- a/src/v4l2/v4l2_camera.cpp\n+++ b/src/v4l2/v4l2_camera.cpp\n@@ -12,13 +12,15 @@\n \n #include <libcamera/base/log.h>\n \n+#include <libcamera/control_ids.h>\n+\n using namespace libcamera;\n \n LOG_DECLARE_CATEGORY(V4L2Compat)\n \n V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)\n-\t: camera_(camera), isRunning_(false), bufferAllocator_(nullptr),\n-\t efd_(-1), bufferAvailableCount_(0)\n+\t: camera_(camera), controls_(controls::controls), isRunning_(false),\n+\t bufferAllocator_(nullptr), efd_(-1), bufferAvailableCount_(0)\n {\n \tcamera_->requestCompleted.connect(this, &V4L2Camera::requestComplete);\n }\n@@ -202,10 +204,12 @@ int V4L2Camera::streamOn()\n \tif (isRunning_)\n \t\treturn 0;\n \n-\tint ret = camera_->start();\n+\tint ret = camera_->start(&controls_);\n \tif (ret < 0)\n \t\treturn ret == -EACCES ? -EBUSY : ret;\n \n+\tcontrols_.clear();\n+\n \tisRunning_ = true;\n \n \tfor (Request *req : pendingRequests_) {\n@@ -265,6 +269,8 @@ int V4L2Camera::qbuf(unsigned int index)\n \t\treturn 0;\n \t}\n \n+\trequest->controls().merge(std::move(controls_));\n+\n \tret = camera_->queueRequest(request);\n \tif (ret < 0) {\n \t\tLOG(V4L2Compat, Error) << \"Can't queue request\";\ndiff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\nindex 9a0b04551c9d..e54371fb4e00 100644\n--- a/src/v4l2/v4l2_camera.h\n+++ b/src/v4l2/v4l2_camera.h\n@@ -16,6 +16,7 @@\n #include <libcamera/base/shared_fd.h>\n \n #include <libcamera/camera.h>\n+#include <libcamera/controls.h>\n #include <libcamera/framebuffer.h>\n #include <libcamera/framebuffer_allocator.h>\n \n@@ -50,6 +51,8 @@ public:\n \t\t\t\t const libcamera::Size &size,\n \t\t\t\t libcamera::StreamConfiguration *streamConfigOut);\n \n+\tlibcamera::ControlList &controls() { return controls_; }\n+\n \tint allocBuffers(unsigned int count);\n \tvoid freeBuffers();\n \tint getBufferFd(unsigned int index);\n@@ -71,6 +74,8 @@ private:\n \tstd::shared_ptr<libcamera::Camera> camera_;\n \tstd::unique_ptr<libcamera::CameraConfiguration> config_;\n \n+\tlibcamera::ControlList controls_;\n+\n \tbool isRunning_;\n \n \tlibcamera::Mutex bufferLock_;\ndiff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp\nindex da1170536a8f..00ba9ed360eb 100644\n--- a/src/v4l2/v4l2_camera_proxy.cpp\n+++ b/src/v4l2/v4l2_camera_proxy.cpp\n@@ -22,6 +22,8 @@\n #include <libcamera/base/utils.h>\n \n #include <libcamera/camera.h>\n+#include <libcamera/controls.h>\n+#include <libcamera/control_ids.h>\n #include <libcamera/formats.h>\n \n #include \"libcamera/internal/v4l2_pixelformat.h\"\n@@ -33,6 +35,7 @@\n #define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))\n \n using namespace libcamera;\n+using namespace std::literals::chrono_literals;\n \n LOG_DECLARE_CATEGORY(V4L2Compat)\n \n@@ -755,6 +758,23 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)\n \treturn ret;\n }\n \n+int V4L2CameraProxy::vidioc_s_parm(V4L2CameraFile *file, struct v4l2_streamparm *arg)\n+{\n+\tLOG(V4L2Compat, Debug)\n+\t\t<< \"[\" << file->description() << \"] \" << __func__ << \"()\";\n+\n+\tif (!validateBufferType(arg->type))\n+\t\treturn -EINVAL;\n+\n+\tstruct v4l2_fract *timeperframe = &arg->parm.capture.timeperframe;\n+\tutils::Duration frameDuration = 1.0s * timeperframe->numerator / timeperframe->denominator;\n+\n+\tint64_t uDuration = frameDuration.get<std::micro>();\n+\tvcam_->controls().set(controls::FrameDurationLimits, { uDuration, uDuration });\n+\n+\treturn 0;\n+}\n+\n const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {\n \tVIDIOC_QUERYCAP,\n \tVIDIOC_ENUM_FRAMESIZES,\n@@ -775,6 +795,7 @@ const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {\n \tVIDIOC_EXPBUF,\n \tVIDIOC_STREAMON,\n \tVIDIOC_STREAMOFF,\n+\tVIDIOC_S_PARM,\n };\n \n int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long longRequest, void *arg)\n@@ -862,6 +883,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long longRequest, void\n \tcase VIDIOC_STREAMOFF:\n \t\tret = vidioc_streamoff(file, static_cast<int *>(arg));\n \t\tbreak;\n+\tcase VIDIOC_S_PARM:\n+\t\tret = vidioc_s_parm(file, static_cast<struct v4l2_streamparm *>(arg));\n+\t\tbreak;\n \tdefault:\n \t\tret = -ENOTTY;\n \t\tbreak;\ndiff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h\nindex 3d8784dfdbf1..c957db5349cc 100644\n--- a/src/v4l2/v4l2_camera_proxy.h\n+++ b/src/v4l2/v4l2_camera_proxy.h\n@@ -67,6 +67,7 @@ private:\n \tint vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg);\n \tint vidioc_streamon(V4L2CameraFile *file, int *arg);\n \tint vidioc_streamoff(V4L2CameraFile *file, int *arg);\n+\tint vidioc_s_parm(V4L2CameraFile *file, struct v4l2_streamparm *arg);\n \n \tbool hasOwnership(V4L2CameraFile *file);\n \tint acquire(V4L2CameraFile *file);\n", "prefixes": [ "v4" ] }