Patch Detail
Show a patch.
GET /api/patches/15365/?format=api
{ "id": 15365, "url": "https://patchwork.libcamera.org/api/patches/15365/?format=api", "web_url": "https://patchwork.libcamera.org/patch/15365/", "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": "<20220215114222.115790-1-galof.nejc@gmail.com>", "date": "2022-02-15T11:42:22", "name": "[libcamera-devel] v4l2: Support setting frame rate in the V4L2 Adaptation layer", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "c44a517f2efc954584f2e43e0d98bc4c0f994461", "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/15365/mbox/", "series": [ { "id": 2932, "url": "https://patchwork.libcamera.org/api/series/2932/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2932", "date": "2022-02-15T11:42:22", "name": "[libcamera-devel] v4l2: Support setting frame rate in the V4L2 Adaptation layer", "version": 1, "mbox": "https://patchwork.libcamera.org/series/2932/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/15365/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/15365/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 96F29BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 15 Feb 2022 11:42:43 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id ED277610F8;\n\tTue, 15 Feb 2022 12:42:42 +0100 (CET)", "from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com\n\t[IPv6:2a00:1450:4864:20::62d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 61FA7601FF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 15 Feb 2022 12:42:41 +0100 (CET)", "by mail-ej1-x62d.google.com with SMTP id qx21so3833319ejb.13\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 15 Feb 2022 03:42:41 -0800 (PST)", "from e28887faee29.8.8.8.8 ([91.224.238.83])\n\tby smtp.gmail.com with ESMTPSA id\n\tel5sm456373edb.71.2022.02.15.03.42.40\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 15 Feb 2022 03:42:40 -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=\"GBFrWPJK\"; 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=Dr/TnI7lbtnce8QM/N35GI2psSFhqIJ0kZbJbHgOaTg=;\n\tb=GBFrWPJK1YaaUl5rSCA+4ONC6sFss7qXFUa90csBVlSGImMkSW2Orhde8g2JDud12S\n\tOo5cyuUZ9nO8Mvk/7/d1wdcTkOX+xdNmHSUy+A3i4hIqySFdm2z+TYzyikE91G0ro9+V\n\tmDu0nAFkK2ErK+wg7X3IqjfWOD7eKrLuGlHsuqElI1CEMxiIyrhfx4MFpPF8z4o19LYV\n\trVsozoDFXM7/dIWFGiEJqMTrYfALa/lxsKQm0gzvupbv2QSYbmYGynSpq18AwyXuWoov\n\tJ4mOD5dgds4POzuj+nRNVFJ5z89mCrBmDgGdMeqh4Pwgfcd/oAzhkOouFTzr59VnUayV\n\tVFWg==", "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=Dr/TnI7lbtnce8QM/N35GI2psSFhqIJ0kZbJbHgOaTg=;\n\tb=vrEL27PuVczxSZL7YKiBpPtoIYOsr0tFm4uAAezeFmHcscg9v6VKPBODDSExp65A15\n\t7w3DMsjjEYIF//w1XXQbKHgkU2dGCAUQ9MyqTXaE4Dau38gEvwjhm/FnKUPVbRS32RiH\n\tTJD3DfoOEE8TvLC16smn5TSqnVAoLvuMAbF3BNH0uWMLgdm0T/W2J83kYjMLEz441zF3\n\tYy1Gtik1/IziUkOYWtIW/QaV1gtSxKvWFT0QqpKW/eK9U/0t2JyHdAUop9Z6yFndenoH\n\tAJXXfkiRtFfW860LJYtdS9YAss3UrbK8xLKC12u7NLlhdYauMsrbVXBR8ygXakzDEiD5\n\tzRIg==", "X-Gm-Message-State": "AOAM530Iswp4h+2lH1VjDaIdf1qbrJPfSVGq2AzxsWDBjpYOY64tHAek\n\tdf0zlQCFjj6l8Alwo4S5KQTjhOZlGM1hsA==", "X-Google-Smtp-Source": "ABdhPJxufzPX3tZ5c37/Bar62DZqW1utzJAcbpq/5E9aQI+WVvnb4GIL9n0BiQuXpydozppNMwQMuA==", "X-Received": "by 2002:a17:907:1c87:: with SMTP id\n\tnb7mr2633330ejc.279.1644925360917; \n\tTue, 15 Feb 2022 03:42:40 -0800 (PST)", "From": "Nejc Galof <galof.nejc@gmail.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Tue, 15 Feb 2022 12:42:22 +0100", "Message-Id": "<20220215114222.115790-1-galof.nejc@gmail.com>", "X-Mailer": "git-send-email 2.17.1", "Subject": "[libcamera-devel] [PATCH] v4l2: Support setting frame rate in the\n\tV4L2 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>\n---\n src/v4l2/v4l2_camera.cpp | 12 +++++++++---\n src/v4l2/v4l2_camera.h | 7 +++++++\n src/v4l2/v4l2_camera_proxy.cpp | 25 +++++++++++++++++++++++++\n src/v4l2/v4l2_camera_proxy.h | 1 +\n 4 files changed, 42 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..9e6c895a 100644\n--- a/src/v4l2/v4l2_camera.h\n+++ b/src/v4l2/v4l2_camera.h\n@@ -10,11 +10,14 @@\n #include <deque>\n #include <utility>\n \n+#include <linux/videodev2.h>\n+\n #include <libcamera/base/mutex.h>\n #include <libcamera/base/semaphore.h>\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 +52,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 +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 e114d09f..f005b21c 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,24 @@ int V4L2CameraProxy::vidioc_streamoff(V4L2CameraFile *file, int *arg)\n \treturn ret;\n }\n \n+int V4L2CameraProxy::vidioc_s_param(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 = 1s * (static_cast<double>(timeperframe->numerator) /\n+\t\t\t\t\t static_cast<double>(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 +796,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 +874,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_param(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..30a3f492 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_param(V4L2CameraFile *file, struct v4l2_streamparm *arg);\n \n \tbool hasOwnership(V4L2CameraFile *file);\n \tint acquire(V4L2CameraFile *file);\n", "prefixes": [ "libcamera-devel" ] }