Patch Detail
Show a patch.
GET /api/patches/15392/?format=api
{ "id": 15392, "url": "https://patchwork.libcamera.org/api/patches/15392/?format=api", "web_url": "https://patchwork.libcamera.org/patch/15392/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/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": "<20220225144507.69550-1-galof.nejc@gmail.com>", "date": "2022-02-25T14:45:07", "name": "[libcamera-devel,v3] v4l2: Support setting frame rate in the V4L2 Adaptation layer", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "49d72815e9537c2c49c8a57918d945b073bcc219", "submitter": { "id": 113, "url": "https://patchwork.libcamera.org/api/people/113/?format=api", "name": "Nejc Galof", "email": "galof.nejc@gmail.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/15392/mbox/", "series": [ { "id": 2943, "url": "https://patchwork.libcamera.org/api/series/2943/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2943", "date": "2022-02-25T14:45:07", "name": "[libcamera-devel,v3] v4l2: Support setting frame rate in the V4L2 Adaptation layer", "version": 3, "mbox": "https://patchwork.libcamera.org/series/2943/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/15392/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/15392/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 20F63BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 25 Feb 2022 14:45:18 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6C0BB6116E;\n\tFri, 25 Feb 2022 15:45:17 +0100 (CET)", "from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com\n\t[IPv6:2a00:1450:4864:20::42c])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C745561166\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Feb 2022 15:45:15 +0100 (CET)", "by mail-wr1-x42c.google.com with SMTP id d3so4912698wrf.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 25 Feb 2022 06:45:15 -0800 (PST)", "from e28887faee29.8.8.8.8 ([91.224.238.83])\n\tby smtp.gmail.com with ESMTPSA id\n\tm10-20020adfe94a000000b001ef57f562ccsm2441597wrn.51.2022.02.25.06.45.14\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 25 Feb 2022 06:45:15 -0800 (PST)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"c0iY+hvq\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=from:to:cc:subject:date:message-id;\n\tbh=ZDjDID+wtBprRlhnvPY2FiUBNOe3Fb8fuuRlnpahR+8=;\n\tb=c0iY+hvqDUHPn97QFJ49SO7L8F9qkgHwOE5P7oIMvEfodfKUwsqkClsOpxz5NHYhgZ\n\tfpOgqrzQ4M6LH192Rq3RHFYhstF7da00rKqA2SCOrbchDLjvFBWyZS9LTrH7nq/JQ6IN\n\tjC4s7dzdhoBKWzrE2OYXEnDQT4CA2DGEZYrMC0w3wrYTgYtoT0w8Sixumv1HbW2lh59Y\n\tc09o0GHl0KGcbAz3f/SIduG9rnZJvXYJe/GhLZcE04JRUYwjCSmoGfSemj7xstdyWIuy\n\tl8MtU3m2D5yt3K+W2cF4cvGxbVRuB5KpT0c3j+rU0RSfJZpMIg7484H0M0nQ6HFtMTrV\n\t+iEA==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id;\n\tbh=ZDjDID+wtBprRlhnvPY2FiUBNOe3Fb8fuuRlnpahR+8=;\n\tb=gNyoXQxjN5UHBqKxufG9mITSwUQ6mLKvQMAQJyt2eSG2rGdQzdOTYdgiqkmIEXuKat\n\tAj29XKyRGZoyK99pp4lWmk61l2FBUDMOcuZGz1MvQW43SmeWIj4GOl0zsI6JlC3g8S22\n\tVKaYw6XOwB+i1Yw2w59L5sE9al8BLNDpwNgiYPPyiZOm6/dmWZVsWkc5XDXWxwwBde71\n\tBVcTB4hSm1xcoaYOHPYckm+sKz+3RmsPNJdtlHrdg7XzruySqVGrY72OCkvMDESFMs12\n\trH+QeklXf7lC0tajJVavABFyuQlHTj0O1wBvexbydBWQfBQmmPPVhVvUvZ9FJ4yrLK2y\n\t4DDw==", "X-Gm-Message-State": "AOAM532MB/QHL4UvrZW1d/5LksfW07ZJdDooSn6nU0i6RPcpcAL5am3z\n\tZiWqjDpxLTcEe4r/smWUuT+SYmAT+x4HZw==", "X-Google-Smtp-Source": "ABdhPJym4jjLMEt35D+Npci//f4NKS7hT+aPBl/bbgiqB0J6fCJ6x61hhqLCGu+WC9AEUieuKXuXAg==", "X-Received": "by 2002:a05:6000:2c2:b0:1ea:9ab5:174f with SMTP id\n\to2-20020a05600002c200b001ea9ab5174fmr6200325wry.274.1645800315438; \n\tFri, 25 Feb 2022 06:45:15 -0800 (PST)", "From": "Nejc Galof <galof.nejc@gmail.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Fri, 25 Feb 2022 15:45:07 +0100", "Message-Id": "<20220225144507.69550-1-galof.nejc@gmail.com>", "X-Mailer": "git-send-email 2.17.1", "Subject": "[libcamera-devel] [PATCH v3] v4l2: Support setting frame rate in\n\tthe V4L2 Adaptation layer", "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": "The 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>\nSigned-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\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 e922b9e6..e4eb3a2b 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@@ -203,10 +205,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@@ -266,6 +270,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 03e74118..4c203e31 100644\n--- a/src/v4l2/v4l2_camera.h\n+++ b/src/v4l2/v4l2_camera.h\n@@ -15,6 +15,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@@ -49,6 +50,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@@ -69,6 +72,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 74bd54ce..493c41c0 100644\n--- a/src/v4l2/v4l2_camera_proxy.cpp\n+++ b/src/v4l2/v4l2_camera_proxy.cpp\n@@ -18,6 +18,8 @@\n #include <unistd.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/base/log.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 request, void *arg)\n@@ -852,6 +873,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar\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 76ca2d8a..c1aeaff9 100644\n--- a/src/v4l2/v4l2_camera_proxy.h\n+++ b/src/v4l2/v4l2_camera_proxy.h\n@@ -65,6 +65,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": [ "libcamera-devel", "v3" ] }