From patchwork Mon Jun 23 16:35:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giacomo Cappellini X-Patchwork-Id: 23628 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id B84B5BDE6B for ; Mon, 23 Jun 2025 16:37:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F096968DCE; Mon, 23 Jun 2025 18:37:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ky+e6oQQ"; dkim-atps=neutral Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 78C9868DC9 for ; Mon, 23 Jun 2025 18:36:17 +0200 (CEST) Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-451dbe494d6so51166725e9.1 for ; Mon, 23 Jun 2025 09:36:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1750696577; x=1751301377; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=DeSwJG4qOuD1BDAxgVGlsVuUG9kDe3Lrl2ryCsF6GKw=; b=Ky+e6oQQ9EN7fEzAEuFcWD5OWZgQ/2NZD3iP1Ja8horqJaKtfJ02G3RjnxTGBh0e27 CC/73m6/cSnsbWNIO2KH2U1FF7faGkh5YIsztNHjsikmcqkHDSz61PpcKeV5dMnNrwmJ vvQfe6a9Hcr1YDULcoLkRXaA0tH9DAL28wBUUg66LNGPIy/0vsRv41QcNC3sg73wHfTR YEq20ZIxOB1OgyRwqwpdIoTM1Nc4T6Qe9nWCVcVHhf0QcDSCs5vi+02hFbfuHKOp4VQY SyK9BR33GM5IlhA4yfsqZaAEFbu+zSASgl/m+FbUtH0WF+g0NnO9Wx026TO6WZ/aHJW6 7HIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750696577; x=1751301377; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=DeSwJG4qOuD1BDAxgVGlsVuUG9kDe3Lrl2ryCsF6GKw=; b=rPaBFcEfHJ9UuRbyLYRAldT28mhEOjZRLlu+O4MJQHp61JyY7nqqC9K/La/sJA1suP 13DdZ+BVi6fRe7jGvT6tvuzRlKWRPDV+T5NFjyQkA1OkryW9RdC7luh67r+ZkM4csCzJ QsWe9ElBdBPUYS//5kpteQt+7MNbztxCjDVIcxjQVWKpdjdpLwgAasEKPx6EJdFlEwoW Eb79FQefZsfrQ47Htfd8Rb7Mta9mB5eqVsGg/o0TSSl3iq1ge7PCn+Znzc2i8qz/4f6i xEkRNHTcDd9hswf3iMrTY9NO8alHM7wS68XPx8qg08jTkFH2hyIgQVO8y2/3HPcHf7Bo BLLw== X-Gm-Message-State: AOJu0YwwVkJ+/dCX/ivRTnXj30wVrzqs6HLeCfFupjN2y0onDqLI6A9i 2PmX+iBS0HNtk7GbN8NmyOxKPyYZHOmD5dYOE6D5Tg2VOLHHuh9BTiY1f10Z7y2v X-Gm-Gg: ASbGncuSWBBqAbcVku/5scmwP9yO6QSHIs9r43fi6EH7M4jVLpxAD6ZQ00JhZMXE8wa aHQXXSBDKNvGDTFYapNuJucGAhm2v0MG6zRk/WByQ8RBSC/000UgihGaoUMsgyOtwW1RCszwwOr 19sglFuT+THDqmpIh54pgbioP2SXxdBpMUcfY6z9/iEzJ+34riQHkTI8L2rC7P11m/WaGvxAxgP 4c6PeLEZZzyc6wC3HhQFWh9gpc3jn+rAAi8TAD7jlskRjIVM+vsIVcvioRURu8GJgcPRJHQp8NE l+/uqiZiKhisvsrwy2Ng83wvKKJwSQYX6TRtXzprHn+YCN4xegIHOEk5Dvxnk8pTLqUkLahclqh hu32r9B+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 5b1f17b1804b1-4537a695f95mr15399685e9.30.1750696576557; Mon, 23 Jun 2025 09:36:16 -0700 (PDT) Received: from jasus.ad.servtec.it (host-95-251-230-143.retail.telecomitalia.it. [95.251.230.143]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-453646cb692sm116771725e9.2.2025.06.23.09.36.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Jun 2025 09:36:16 -0700 (PDT) From: Giacomo Cappellini To: libcamera-devel@lists.libcamera.org Cc: Giacomo Cappellini 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 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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" "orientation" parameter added to the libcamerasrc element to control the orientation of the camera feed. GST_PARAM_MUTABLE_READY allows the parameter to be changed only when pipeline is in the READY state The parameter is fed into the existing CameraConfiguration orientation property This allows users to specify the rotation of the video stream, enhancing flexibility in camera applications. --- src/gstreamer/gstlibcamerasrc.cpp | 72 +++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 51ba8b67..b07156af 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -146,6 +146,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; + Orientation orientation; std::atomic pending_eos; @@ -157,6 +158,7 @@ struct _GstLibcameraSrc { enum { PROP_0, PROP_CAMERA_NAME, + PROP_ORIENTATION, PROP_LAST }; @@ -616,6 +618,11 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self) gst_libcamera_get_framerate_from_caps(caps, element_caps); } + // print state->orientation for debugging purposes + GST_DEBUG_OBJECT(self, "Orientation: %d", (int)self->orientation); + /* Set the orientation control. */ + state->config_->orientation = self->orientation; + /* Validate the configuration. */ if (state->config_->validate() == CameraConfiguration::Invalid) return false; @@ -926,6 +933,9 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, g_free(self->camera_name); self->camera_name = g_value_dup_string(value); break; + case PROP_ORIENTATION: + self->orientation = (libcamera::Orientation)g_value_get_enum(value); + break; default: if (!state->controls_.setProperty(prop_id - PROP_LAST, value, pspec)) G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -945,6 +955,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, case PROP_CAMERA_NAME: g_value_set_string(value, self->camera_name); break; + case PROP_ORIENTATION: + g_value_set_enum(value, (gint)self->orientation); + break; default: if (!state->controls_.getProperty(prop_id - PROP_LAST, value, pspec)) G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -1120,6 +1133,53 @@ gst_libcamera_src_release_pad(GstElement *element, GstPad *pad) gst_element_remove_pad(element, pad); } +static GType +gst_libcamera_orientation_get_type() +{ + static GType type = 0; + static const GEnumValue values[] = { + { + static_cast(libcamera::Orientation::Rotate0), + "libcamera::Orientation::Rotate0", + "rotate-0", + }, { + static_cast(libcamera::Orientation::Rotate0Mirror), + "libcamera::Orientation::Rotate0Mirror", + "rotate-0-mirror", + }, { + static_cast(libcamera::Orientation::Rotate180), + "libcamera::Orientation::Rotate180", + "rotate-180", + }, { + static_cast(libcamera::Orientation::Rotate180Mirror), + "libcamera::Orientation::Rotate180Mirror", + "rotate-180-mirror", + }, { + static_cast(libcamera::Orientation::Rotate90Mirror), + "libcamera::Orientation::Rotate90Mirror", + "rotate-90-mirror", + }, { + static_cast(libcamera::Orientation::Rotate270), + "libcamera::Orientation::Rotate270", + "rotate-270", + }, { + static_cast(libcamera::Orientation::Rotate270Mirror), + "libcamera::Orientation::Rotate270Mirror", + "rotate-270-mirror", + }, { + static_cast(libcamera::Orientation::Rotate90), + "libcamera::Orientation::Rotate90", + "rotate-90", + }, + { 0, nullptr, nullptr } + }; + + if (!type) + type = g_enum_register_static("GstLibcameraOrientation", values); + + return type; +} + static void gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) { @@ -1154,6 +1214,18 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); + /* Register the orientation enum type. */ + GType orientation_type = gst_libcamera_orientation_get_type(); + spec = g_param_spec_enum("orientation", "Orientation", + "Select the orientation of the camera.", + orientation_type, + static_cast(libcamera::Orientation::Rotate0), + (GParamFlags)(GST_PARAM_MUTABLE_READY + | G_PARAM_CONSTRUCT + | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(object_class, PROP_ORIENTATION, spec); + GstCameraControls::installProperties(object_class, PROP_LAST); }