Patch Detail
Show a patch.
GET /api/1.1/patches/17216/?format=api
{ "id": 17216, "url": "https://patchwork.libcamera.org/api/1.1/patches/17216/?format=api", "web_url": "https://patchwork.libcamera.org/patch/17216/", "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": "<20220828145630.51618-1-rishikeshdonadkar@gmail.com>", "date": "2022-08-28T14:56:30", "name": "[libcamera-devel,v1] gstreamer: Provide framerate support for libcamerasrc.", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "82df1db92875d43a23a3fdc10f25c1c99b506922", "submitter": { "id": 118, "url": "https://patchwork.libcamera.org/api/1.1/people/118/?format=api", "name": "Rishikesh Donadkar", "email": "rishikeshdonadkar@gmail.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/17216/mbox/", "series": [ { "id": 3441, "url": "https://patchwork.libcamera.org/api/1.1/series/3441/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3441", "date": "2022-08-28T14:56:30", "name": "[libcamera-devel,v1] gstreamer: Provide framerate support for libcamerasrc.", "version": 1, "mbox": "https://patchwork.libcamera.org/series/3441/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/17216/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/17216/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 2C244C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 28 Aug 2022 14:56:52 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7472761FC0;\n\tSun, 28 Aug 2022 16:56:51 +0200 (CEST)", "from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com\n\t[IPv6:2607:f8b0:4864:20::42e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 305BB61FBD\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 28 Aug 2022 16:56:49 +0200 (CEST)", "by mail-pf1-x42e.google.com with SMTP id 76so5984072pfy.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 28 Aug 2022 07:56:49 -0700 (PDT)", "from localhost.localdomain ([49.36.103.8])\n\tby smtp.googlemail.com with ESMTPSA id\n\tp63-20020a622942000000b005321340753fsm5356002pfp.103.2022.08.28.07.56.44\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSun, 28 Aug 2022 07:56:46 -0700 (PDT)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1661698611;\n\tbh=FN53VUar5tGP6AqTXgv+rSzxWCTgO92p7kxc0OVHA/s=;\n\th=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post:\n\tList-Help:List-Subscribe:From:Reply-To:Cc:From;\n\tb=2M+NhmGRx685vFNcXMQuIdTc65AMCvSpzU/JStbnpdgC276gLoNrAU14QF7mgPBkz\n\tAox6Ctuj9jLLVb7TZvz7nY6p5UfSFyv4kY40Vsx46l6CcCe2CoKCjL3Ufcf/FbcZKT\n\t8atY4pfgyWr7cS5idIZSE7K1ddBc+HvwmKHRIeTHYCoWPy7XwUlMY7YGJYxvZG7v2c\n\tHi1l/KOqhKRhfCQ8ILvbtnDtKTMA1qFlCXiFXShtH/P3mXZpatC2VN4XTEnd9BCIOx\n\t8ZJXrP2zbNmTEkTqn+tPthVDk1akUH6TITOZ6ToGFH73YYEsl6K2RPOAlV5QNHZ1lv\n\tS1mC6CzhQuMYg==", "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;\n\th=content-transfer-encoding:mime-version:message-id:date:subject:cc\n\t:to:from:from:to:cc;\n\tbh=Ysbi09SuQEm5ulPFfNHN/3SE38w9Vw1FikBdUGpOivM=;\n\tb=Gssls2sSheotNRpk5a5ai9X+C1Q87jXnzNmbmYxkMpmm0XEbh8UKkwO+/ALX+IHn0C\n\t6nPDgGslZraNAaLubIySQcHgN6+voSGzBWpKVsEUCrK6stLuWvoYAiiZBqPTlU0w+z+s\n\tRcK/XxqqKKPIBe3yNT5DnLUwSdgrKpN7wv6VI/mPwnLU/xReM6qb5nZHoJoz+fEwvm1e\n\tQokpSHdeFUJKMcmtYuarOdJ7v1Fj6+GZ/S3W2I//RCQ/5PdhB02Hmo+npq25BOrKNPAE\n\t1qacJA1tR2kd+2LrS4y1XeZciqhOzs9nKAFA91biZsPx58NVwp76Gsm8JSZwwziMLRXf\n\tQ5EQ==" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"Gssls2sS\"; dkim-atps=neutral", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=content-transfer-encoding:mime-version:message-id:date:subject:cc\n\t:to:from:x-gm-message-state:from:to:cc;\n\tbh=Ysbi09SuQEm5ulPFfNHN/3SE38w9Vw1FikBdUGpOivM=;\n\tb=7eR/thh6N6+22jrWtLOMjH5e8Xi2zNTQpOGFZzC7cVBfnED8Mvn03vM6MqtnAOBr9L\n\tTh9Pukd0HjIDI+lfzizLO1zaouKTILlYQEsrWu72hlsAEgBdsBFb/cpT1t+xZp/qmdej\n\toq1krwa2U1YeYUEu8L/xK5XtSfXSD1rc/T0Ag9doeoUcevfBwHKwMgG2gJYcycYX/KM2\n\t31ctRxTGoE01Jw0ATi/096qfmLymRwLEV4NfXhEE9iXEFKtkYDiStUgZ60NWjGhE4w44\n\tx5bRDNgP3IqsIzCzvpKjod4SFjG+ddMxHRJ8/cvsqXGfUIUwXzHJWicSUcgcXwZK1Tcu\n\tnjNA==", "X-Gm-Message-State": "ACgBeo3walv+CRbJBVzf/21rWgHK5zBTAujVmxG6OLLMoQIwvOs0wphG\n\t9s52p8ieGde2a6Ji5GVB4KIBCLrqH08KQY9O", "X-Google-Smtp-Source": "AA6agR67iwirdfvl61M1aZ13ON8wtThzPSZquaWcHkfm4GqVum6koHZZmGvwEU59RBgR0Ox67inI7w==", "X-Received": "by 2002:a63:5418:0:b0:42a:d773:cbd6 with SMTP id\n\ti24-20020a635418000000b0042ad773cbd6mr10656617pgb.106.1661698607186; \n\tSun, 28 Aug 2022 07:56:47 -0700 (PDT)", "To": "libcamera-devel@lists.libcamera.org", "Date": "Sun, 28 Aug 2022 20:26:30 +0530", "Message-Id": "<20220828145630.51618-1-rishikeshdonadkar@gmail.com>", "X-Mailer": "git-send-email 2.25.1", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v1] gstreamer: Provide framerate support\n\tfor libcamerasrc.", "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>", "From": "Rishikesh Donadkar via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>", "Reply-To": "Rishikesh Donadkar <rishikeshdonadkar@gmail.com>", "Cc": "Rishikesh Donadkar <rishikeshdonadkar@gmail.com>,\n\tnicolas.dufresne@collabora.com, vedantparanjape160201@gmail.com", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "This patch aims to add framerate support to libcamerasrc in the \ndirection gstreamer->libcamera.\n\nAdd a field of the type ControlList to GstLibcameraSrcState.\nGet the framerate from the caps and convert it to FrameDuration.\nSet the FrameDurationLimits control in the initControls_ and pass\nthe initControls_ at the time of starting camera.\n\nSigned-off-by: Umang Jain <umang.jain@ideasonboard.com>\nSigned-off-by: Rishikesh Donadkar <rishikeshdonadkar@gmail.com>\n\n---\nTested the patch with 3 different framerates with the help of the\nfpsdisplaysink element.\n\nhttps://paste.debian.net/1251951/\n\nhttps://paste.debian.net/1251952/\n\nhttps://paste.debian.net/1251953/\n---\n src/gstreamer/gstlibcamera-utils.cpp | 18 ++++++++++++++++++\n src/gstreamer/gstlibcamera-utils.h | 3 +++\n src/gstreamer/gstlibcamerasrc.cpp | 7 ++++++-\n 3 files changed, 27 insertions(+), 1 deletion(-)", "diff": "diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp\nindex 5a21a391..7d8519da 100644\n--- a/src/gstreamer/gstlibcamera-utils.cpp\n+++ b/src/gstreamer/gstlibcamera-utils.cpp\n@@ -8,6 +8,7 @@\n \n #include \"gstlibcamera-utils.h\"\n \n+#include <libcamera/control_ids.h>\n #include <libcamera/formats.h>\n \n using namespace libcamera;\n@@ -236,6 +237,23 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,\n \tstream_cfg.size.height = height;\n }\n \n+void\n+gst_libcamera_configure_controls_from_caps(ControlList &controls, [[maybe_unused]] GstCaps *caps)\n+{\n+\t/* read framerate from caps - convert to integer and set to frame_time. */\n+\tGstStructure *s = gst_caps_get_structure(caps, 0);\n+\tgint fps_n = -1, fps_d = -1;\n+\tif (gst_structure_has_field(s, \"framerate\"))\n+\t\tgst_structure_get_fraction(s, \"framerate\", &fps_n, &fps_d);\n+\n+\tif (fps_n < 0 || fps_d < 0)\n+\t\treturn;\n+\n+\tgdouble frame_duration = static_cast<double>(fps_d) / static_cast<double>(fps_n) * 1000000.0;\n+\tcontrols.set(controls::FrameDurationLimits,\n+\t\t Span<const int64_t, 2>({ static_cast<int64_t>(frame_duration), static_cast<int64_t>(frame_duration) }));\n+}\n+\n #if !GST_CHECK_VERSION(1, 17, 1)\n gboolean\n gst_task_resume(GstTask *task)\ndiff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h\nindex 164189a2..1f737e84 100644\n--- a/src/gstreamer/gstlibcamera-utils.h\n+++ b/src/gstreamer/gstlibcamera-utils.h\n@@ -9,6 +9,7 @@\n #pragma once\n \n #include <libcamera/camera_manager.h>\n+#include <libcamera/controls.h>\n #include <libcamera/stream.h>\n \n #include <gst/gst.h>\n@@ -18,6 +19,8 @@ GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &fo\n GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);\n void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,\n \t\t\t\t\t GstCaps *caps);\n+void gst_libcamera_configure_controls_from_caps(libcamera::ControlList &controls, GstCaps *caps);\n+\n #if !GST_CHECK_VERSION(1, 17, 1)\n gboolean gst_task_resume(GstTask *task);\n #endif\ndiff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\nindex 16d70fea..d1080271 100644\n--- a/src/gstreamer/gstlibcamerasrc.cpp\n+++ b/src/gstreamer/gstlibcamerasrc.cpp\n@@ -131,6 +131,7 @@ struct GstLibcameraSrcState {\n \tstd::queue<std::unique_ptr<RequestWrap>> completedRequests_\n \t\tLIBCAMERA_TSA_GUARDED_BY(lock_);\n \n+\tControlList initControls_;\n \tguint group_id_;\n \n \tint queueRequest();\n@@ -496,6 +497,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n \t\t/* Retrieve the supported caps. */\n \t\tg_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());\n \t\tg_autoptr(GstCaps) caps = gst_pad_peer_query_caps(srcpad, filter);\n+\n \t\tif (gst_caps_is_empty(caps)) {\n \t\t\tflow_ret = GST_FLOW_NOT_NEGOTIATED;\n \t\t\tbreak;\n@@ -504,6 +506,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n \t\t/* Fixate caps and configure the stream. */\n \t\tcaps = gst_caps_make_writable(caps);\n \t\tgst_libcamera_configure_stream_from_caps(stream_cfg, caps);\n+\t\tgst_libcamera_configure_controls_from_caps(state->initControls_, caps);\n \t}\n \n \tif (flow_ret != GST_FLOW_OK)\n@@ -524,6 +527,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n \t\tconst StreamConfiguration &stream_cfg = state->config_->at(i);\n \n \t\tg_autoptr(GstCaps) caps = gst_libcamera_stream_configuration_to_caps(stream_cfg);\n+\n \t\tif (!gst_pad_push_event(srcpad, gst_event_new_caps(caps))) {\n \t\t\tflow_ret = GST_FLOW_NOT_NEGOTIATED;\n \t\t\tbreak;\n@@ -566,7 +570,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n \t\tgst_flow_combiner_add_pad(self->flow_combiner, srcpad);\n \t}\n \n-\tret = state->cam_->start();\n+\tret = state->cam_->start(&state->initControls_);\n \tif (ret) {\n \t\tGST_ELEMENT_ERROR(self, RESOURCE, SETTINGS,\n \t\t\t\t (\"Failed to start the camera: %s\", g_strerror(-ret)),\n@@ -576,6 +580,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n \t}\n \n done:\n+\tstate->initControls_.clear();\n \tswitch (flow_ret) {\n \tcase GST_FLOW_NOT_NEGOTIATED:\n \t\tGST_ELEMENT_FLOW_ERROR(self, flow_ret);\n", "prefixes": [ "libcamera-devel", "v1" ] }