Patch Detail
Show a patch.
GET /api/patches/23628/?format=api
{ "id": 23628, "url": "https://patchwork.libcamera.org/api/patches/23628/?format=api", "web_url": "https://patchwork.libcamera.org/patch/23628/", "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": "<20250623163540.1787972-1-giacomo.cappellini.87@gmail.com>", "date": "2025-06-23T16:35:40", "name": "gstreamer: Adding property to control orientation", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "38ef150f96a272dba205e1e45ae13c0d3b572b74", "submitter": { "id": 231, "url": "https://patchwork.libcamera.org/api/people/231/?format=api", "name": "Giacomo Cappellini", "email": "giacomo.cappellini.87@gmail.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/23628/mbox/", "series": [ { "id": 5242, "url": "https://patchwork.libcamera.org/api/series/5242/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5242", "date": "2025-06-23T16:35:40", "name": "gstreamer: Adding property to control orientation", "version": 1, "mbox": "https://patchwork.libcamera.org/series/5242/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/23628/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/23628/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 B84B5BDE6B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Jun 2025 16:37:41 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F096968DCE;\n\tMon, 23 Jun 2025 18:37:40 +0200 (CEST)", "from mail-wm1-x331.google.com (mail-wm1-x331.google.com\n\t[IPv6:2a00:1450:4864:20::331])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 78C9868DC9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Jun 2025 18:36:17 +0200 (CEST)", "by mail-wm1-x331.google.com with SMTP id\n\t5b1f17b1804b1-451dbe494d6so51166725e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Jun 2025 09:36:17 -0700 (PDT)", "from jasus.ad.servtec.it\n\t(host-95-251-230-143.retail.telecomitalia.it. [95.251.230.143])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-453646cb692sm116771725e9.2.2025.06.23.09.36.15\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 23 Jun 2025 09:36:16 -0700 (PDT)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"Ky+e6oQQ\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=gmail.com; s=20230601; t=1750696577; x=1751301377;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:message-id:date:subject:cc\n\t:to:from:from:to:cc:subject:date:message-id:reply-to;\n\tbh=DeSwJG4qOuD1BDAxgVGlsVuUG9kDe3Lrl2ryCsF6GKw=;\n\tb=Ky+e6oQQ9EN7fEzAEuFcWD5OWZgQ/2NZD3iP1Ja8horqJaKtfJ02G3RjnxTGBh0e27\n\tCC/73m6/cSnsbWNIO2KH2U1FF7faGkh5YIsztNHjsikmcqkHDSz61PpcKeV5dMnNrwmJ\n\tvvQfe6a9Hcr1YDULcoLkRXaA0tH9DAL28wBUUg66LNGPIy/0vsRv41QcNC3sg73wHfTR\n\tYEq20ZIxOB1OgyRwqwpdIoTM1Nc4T6Qe9nWCVcVHhf0QcDSCs5vi+02hFbfuHKOp4VQY\n\tSyK9BR33GM5IlhA4yfsqZaAEFbu+zSASgl/m+FbUtH0WF+g0NnO9Wx026TO6WZ/aHJW6\n\t7HIQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1750696577; x=1751301377;\n\th=content-transfer-encoding:mime-version:message-id:date:subject:cc\n\t:to:from:x-gm-message-state:from:to:cc:subject:date:message-id\n\t:reply-to;\n\tbh=DeSwJG4qOuD1BDAxgVGlsVuUG9kDe3Lrl2ryCsF6GKw=;\n\tb=rPaBFcEfHJ9UuRbyLYRAldT28mhEOjZRLlu+O4MJQHp61JyY7nqqC9K/La/sJA1suP\n\t13DdZ+BVi6fRe7jGvT6tvuzRlKWRPDV+T5NFjyQkA1OkryW9RdC7luh67r+ZkM4csCzJ\n\tQsWe9ElBdBPUYS//5kpteQt+7MNbztxCjDVIcxjQVWKpdjdpLwgAasEKPx6EJdFlEwoW\n\tEb79FQefZsfrQ47Htfd8Rb7Mta9mB5eqVsGg/o0TSSl3iq1ge7PCn+Znzc2i8qz/4f6i\n\txEkRNHTcDd9hswf3iMrTY9NO8alHM7wS68XPx8qg08jTkFH2hyIgQVO8y2/3HPcHf7Bo\n\tBLLw==", "X-Gm-Message-State": "AOJu0YwwVkJ+/dCX/ivRTnXj30wVrzqs6HLeCfFupjN2y0onDqLI6A9i\n\t2PmX+iBS0HNtk7GbN8NmyOxKPyYZHOmD5dYOE6D5Tg2VOLHHuh9BTiY1f10Z7y2v", "X-Gm-Gg": "ASbGncuSWBBqAbcVku/5scmwP9yO6QSHIs9r43fi6EH7M4jVLpxAD6ZQ00JhZMXE8wa\n\taHQXXSBDKNvGDTFYapNuJucGAhm2v0MG6zRk/WByQ8RBSC/000UgihGaoUMsgyOtwW1RCszwwOr\n\t19sglFuT+THDqmpIh54pgbioP2SXxdBpMUcfY6z9/iEzJ+34riQHkTI8L2rC7P11m/WaGvxAxgP\n\t4c6PeLEZZzyc6wC3HhQFWh9gpc3jn+rAAi8TAD7jlskRjIVM+vsIVcvioRURu8GJgcPRJHQp8NE\n\tl+/uqiZiKhisvsrwy2Ng83wvKKJwSQYX6TRtXzprHn+YCN4xegIHOEk5Dvxnk8pTLqUkLahclqh\n\thu32r9B+Q/MbzYQDIyINm06dKeB7r79i9Q8txZ8MFJgOmV5M47X8/ZyVNCDDcRw==", "X-Google-Smtp-Source": "AGHT+IFFgbTdjuOWxxy61py02egKABoUkXsnMjP8IwdCp5CsGTaz5Sx7Hcs/QYqNs1j4QP5Mh+8EJg==", "X-Received": "by 2002:a05:600c:a0a:b0:43c:fe5e:f03b with SMTP id\n\t5b1f17b1804b1-4537a695f95mr15399685e9.30.1750696576557; \n\tMon, 23 Jun 2025 09:36:16 -0700 (PDT)", "From": "Giacomo Cappellini <giacomo.cappellini.87@gmail.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Giacomo Cappellini <giacomo.cappellini.87@gmail.com>", "Subject": "[PATCH] gstreamer: Adding property to control orientation", "Date": "Mon, 23 Jun 2025 18:35:40 +0200", "Message-ID": "<20250623163540.1787972-1-giacomo.cappellini.87@gmail.com>", "X-Mailer": "git-send-email 2.43.0", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Mailman-Approved-At": "Mon, 23 Jun 2025 18:37:40 +0200", "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": "\"orientation\" parameter added to the libcamerasrc\nelement to control the orientation of the camera feed.\n\nGST_PARAM_MUTABLE_READY allows the parameter to be changed\nonly when pipeline is in the READY state\n\nThe parameter is fed into the existing\nCameraConfiguration orientation property\n\nThis allows users to specify the rotation of the video stream,\nenhancing flexibility in camera applications.\n---\n src/gstreamer/gstlibcamerasrc.cpp | 72 +++++++++++++++++++++++++++++++\n 1 file changed, 72 insertions(+)", "diff": "diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\nindex 51ba8b67..b07156af 100644\n--- a/src/gstreamer/gstlibcamerasrc.cpp\n+++ b/src/gstreamer/gstlibcamerasrc.cpp\n@@ -146,6 +146,7 @@ struct _GstLibcameraSrc {\n \tGstTask *task;\n \n \tgchar *camera_name;\n+\tOrientation orientation;\n \n \tstd::atomic<GstEvent *> pending_eos;\n \n@@ -157,6 +158,7 @@ struct _GstLibcameraSrc {\n enum {\n \tPROP_0,\n \tPROP_CAMERA_NAME,\n+\tPROP_ORIENTATION,\n \tPROP_LAST\n };\n \n@@ -616,6 +618,11 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self)\n \t\tgst_libcamera_get_framerate_from_caps(caps, element_caps);\n \t}\n \n+\t// print state->orientation for debugging purposes\n+\tGST_DEBUG_OBJECT(self, \"Orientation: %d\", (int)self->orientation);\n+\t/* Set the orientation control. */\n+\tstate->config_->orientation = self->orientation;\n+\n \t/* Validate the configuration. */\n \tif (state->config_->validate() == CameraConfiguration::Invalid)\n \t\treturn false;\n@@ -926,6 +933,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id,\n \t\tg_free(self->camera_name);\n \t\tself->camera_name = g_value_dup_string(value);\n \t\tbreak;\n+\tcase PROP_ORIENTATION:\n+\t\tself->orientation = (libcamera::Orientation)g_value_get_enum(value);\n+\t\tbreak;\n \tdefault:\n \t\tif (!state->controls_.setProperty(prop_id - PROP_LAST, value, pspec))\n \t\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);\n@@ -945,6 +955,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value,\n \tcase PROP_CAMERA_NAME:\n \t\tg_value_set_string(value, self->camera_name);\n \t\tbreak;\n+\tcase PROP_ORIENTATION:\n+\t\tg_value_set_enum(value, (gint)self->orientation);\n+\t\tbreak;\n \tdefault:\n \t\tif (!state->controls_.getProperty(prop_id - PROP_LAST, value, pspec))\n \t\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);\n@@ -1120,6 +1133,53 @@ gst_libcamera_src_release_pad(GstElement *element, GstPad *pad)\n \tgst_element_remove_pad(element, pad);\n }\n \n+static GType\n+gst_libcamera_orientation_get_type()\n+{\n+\tstatic GType type = 0;\n+\tstatic const GEnumValue values[] = {\n+\t\t{\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate0),\n+\t\t\t\"libcamera::Orientation::Rotate0\",\n+\t\t\t\"rotate-0\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate0Mirror),\n+\t\t\t\"libcamera::Orientation::Rotate0Mirror\",\n+\t\t\t\"rotate-0-mirror\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate180),\n+\t\t\t\"libcamera::Orientation::Rotate180\",\n+\t\t\t\"rotate-180\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate180Mirror),\n+\t\t\t\"libcamera::Orientation::Rotate180Mirror\",\n+\t\t\t\"rotate-180-mirror\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate90Mirror),\n+\t\t\t\"libcamera::Orientation::Rotate90Mirror\",\n+\t\t\t\"rotate-90-mirror\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate270),\n+\t\t\t\"libcamera::Orientation::Rotate270\",\n+\t\t\t\"rotate-270\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate270Mirror),\n+\t\t\t\"libcamera::Orientation::Rotate270Mirror\",\n+\t\t\t\"rotate-270-mirror\",\n+\t\t}, {\n+\t\t\tstatic_cast<gint>(libcamera::Orientation::Rotate90),\n+\t\t\t\"libcamera::Orientation::Rotate90\",\n+\t\t\t\"rotate-90\",\n+\t\t},\n+\t\t{ 0, nullptr, nullptr }\n+\t};\n+\n+\tif (!type)\n+\t\ttype = g_enum_register_static(\"GstLibcameraOrientation\", values);\n+\n+\treturn type;\n+}\n+\n static void\n gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)\n {\n@@ -1154,6 +1214,18 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)\n \t\t\t\t\t\t\t | G_PARAM_STATIC_STRINGS));\n \tg_object_class_install_property(object_class, PROP_CAMERA_NAME, spec);\n \n+\t/* Register the orientation enum type. */\n+\tGType orientation_type = gst_libcamera_orientation_get_type();\n+\tspec = g_param_spec_enum(\"orientation\", \"Orientation\",\n+\t\t\t\t\t \"Select the orientation of the camera.\",\n+\t\t\t\t\t orientation_type,\n+\t\t\t\t\t static_cast<gint>(libcamera::Orientation::Rotate0),\n+\t\t\t\t\t (GParamFlags)(GST_PARAM_MUTABLE_READY\n+\t\t\t\t\t\t\t | G_PARAM_CONSTRUCT\n+\t\t\t\t\t\t\t | G_PARAM_READWRITE\n+\t\t\t\t\t\t\t | G_PARAM_STATIC_STRINGS));\n+\tg_object_class_install_property(object_class, PROP_ORIENTATION, spec);\n+\n \tGstCameraControls::installProperties(object_class, PROP_LAST);\n }\n \n", "prefixes": [] }