From patchwork Tue Jun 13 10:34:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Mader X-Patchwork-Id: 18732 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 C190BBD78E for ; Tue, 13 Jun 2023 10:36:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 73F8961E4B; Tue, 13 Jun 2023 12:36:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1686652590; bh=DBfbRsuTJYHqdtuxUT8g4xq8oUEVgXRv/1XZBOdEXNs=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=1Eck84S9jfp3xw1b8FUTr4AvvIEVT70DZi+skr2W7OKdMbrA28Mi5T9Q0T+s5WO2C F0c2vLMByqi4JonP+1rCmy5zaJu3jhOXja791ldGLzqLM8PXAaCXY7JSiQpFWmmrMb ghBA5RC8dLB6VgeU24rxgQcg7tWQNjRxBrWx+jCivywJexJEUp+psqCqILb/ZBb5BK LdkGVOQjoOFpONz89us0UTJqfPFLLdpAiIQ4X/z9YDHXLVu3i9HfCK3q9E9BRz8Ag8 KBkhQ2arYgn1juBDyYs9+GJs43APo5uqfeamfPYf4fq8VhPNgBSTz3KzvXuBYFuTLr UTfpTjjfnAmcg== Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2B8AE61E49 for ; Tue, 13 Jun 2023 12:36:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=collabora.com header.i=@collabora.com header.b="kwoBlEfX"; dkim-atps=neutral Received: from thinkpad-t460p.fritz.box (unknown [IPv6:2001:4090:a243:8015:93c:83c3:533:d433]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: rmader) by madras.collabora.co.uk (Postfix) with ESMTPSA id C0C326606EFD; Tue, 13 Jun 2023 11:36:28 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1686652588; bh=DBfbRsuTJYHqdtuxUT8g4xq8oUEVgXRv/1XZBOdEXNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kwoBlEfXrM8r5ai+bUCS4sTy2D3VOPtlxAEsQfEEhxVFuE2JuTRq+wodlwosgnAwd OqhuLB7z9/rPzlzwlwZvBoOblOasiQGRDOdADXC9p1ONIvwssJ10eUO7Hj5yLSEE39 4qTXmHN2Qf3p4Bt8hALQvoB8sqYHjiy5oPhr9yNV/RSdl4xavJ3QnMx4LLiLXGatJB gn2fu8AgH4ZTnU0qHsCazRxi16jJ69USTvzQx/u5fLa6f+UupEInM1fJaagQh4c7HR 7aQLT4YUDj4HxKSlRvryDW45CV/JO8Woor5mfr7jCgFYUNdgNakyp51d73PTpno9xt VC4OBcwtSbUvg== To: libcamera-devel@lists.libcamera.org Date: Tue, 13 Jun 2023 12:34:49 +0200 Message-ID: <20230613103519.91370-2-robert.mader@collabora.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230613103519.91370-1-robert.mader@collabora.com> References: <20230613103519.91370-1-robert.mader@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/2] gstreamer: src: Style change 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: , X-Patchwork-Original-From: Robert Mader via libcamera-devel From: Robert Mader Reply-To: Robert Mader Cc: Robert Mader Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Get rid of a variable and use a more common style in Gstreamer in preparation for more properties. Signed-off-by: Robert Mader Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain --- src/gstreamer/gstlibcamerasrc.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index a10cbd4f..721b35c2 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -837,11 +837,12 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) &request_src_template, GST_TYPE_LIBCAMERA_PAD); - GParamSpec *spec = g_param_spec_string("camera-name", "Camera Name", - "Select by name which camera to use.", nullptr, - (GParamFlags)(GST_PARAM_MUTABLE_READY - | G_PARAM_CONSTRUCT - | G_PARAM_READWRITE - | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); + g_object_class_install_property(object_class, PROP_CAMERA_NAME, + g_param_spec_string("camera-name", "Camera Name", + "Select by name which camera to use.", + nullptr, + (GParamFlags)(GST_PARAM_MUTABLE_READY + | G_PARAM_CONSTRUCT + | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS))); } From patchwork Tue Jun 13 10:34:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Mader X-Patchwork-Id: 18733 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 9D6E5C3226 for ; Tue, 13 Jun 2023 10:36:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F18E461E59; Tue, 13 Jun 2023 12:36:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1686652591; bh=GUNI6TWGFRgy73Jg68alWddqXmN0nn6soGClbbcehZY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=o1ZuIxXHZdcrW+gyWCfb9SS1KUy5J7vmbRDxlYDGPhRytd7DvNM++87mOp8PFj9jc EpfF+5yEhzNhO/Qwesg3HeWOu2OO+xDRPDu090a6OZY+iQxdmrLbJTC3xBdcZvEhIq p82y39k22+kASv+sW50PdEtJ9LCpVTCp3QqL8odElQmzZoT2schax0BGkrIwCdh5Nt R3eZABqVr57i9kh/fPomhDHPvrG0hvnBBIUU5STJsw+GGK9o7swThRc1pKTRh1Kmtp LAk0gzTzo4jotYHZBhkd6uIduSDwYMCy6karo4oahGfm6xr+8jup5mIiY58hN6tvi0 RnRDjdCmdHC8A== Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 732AF61E4E for ; Tue, 13 Jun 2023 12:36:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=collabora.com header.i=@collabora.com header.b="Fq48OVOE"; dkim-atps=neutral Received: from thinkpad-t460p.fritz.box (unknown [IPv6:2001:4090:a243:8015:93c:83c3:533:d433]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: rmader) by madras.collabora.co.uk (Postfix) with ESMTPSA id 1D7A16606F02; Tue, 13 Jun 2023 11:36:29 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1686652589; bh=GUNI6TWGFRgy73Jg68alWddqXmN0nn6soGClbbcehZY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Fq48OVOEmYc0FnV71vHC4RiRo2esYAiMGKi15rN0oXBBGm8Oom/YOAB2i5ROgkuAc BH6YQLjEK9TDTYDK5exhDs4jneZM/jnT4xP5XvXOp5giy00oNVY369hFs6XYRzZVxH aI79bFyqX0Ya7EJMRCRmR1CMYEmtJKO8KDoZdmroavi0TXhVRRrbACy+XMw8QQAyKc PHj7QZHRxeEbey5NhfjL/K0OufhpIiUaNGBexJJi2C0l8ZLTS1wQA2KMR/ay/OTK7T 8VCBOWsdtJGHYEjh/B5VLjQ+b+IyNo3F2g8AA+VkzAo5B6DaJrTzPfHHLAYYrrhgt1 rdNdWPdZJnRsw== To: libcamera-devel@lists.libcamera.org Date: Tue, 13 Jun 2023 12:34:50 +0200 Message-ID: <20230613103519.91370-3-robert.mader@collabora.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230613103519.91370-1-robert.mader@collabora.com> References: <20230613103519.91370-1-robert.mader@collabora.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] gstreamer: src: Add transform property 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: , X-Patchwork-Original-From: Robert Mader via libcamera-devel From: Robert Mader Reply-To: Robert Mader Cc: Robert Mader Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This allows users to request a transform using the Gstreamer equivalent. If the combined transform of the requested one and a possible rotation from the camera properties is not fully supported by the sensor, the remaining transform will be passed down to downstream elements as tag. The later is common for 90/270 degree rotations. Thus, a side effect of this feature is that libcamerasrc now behaves similar to pipewiresrc in regards to rotated cameras in e.g. phones, allowing apps to compensate accordingly. Signed-off-by: Robert Mader --- src/gstreamer/gstlibcamera-utils.cpp | 72 ++++++++++++++++++++++++++++ src/gstreamer/gstlibcamera-utils.h | 5 ++ src/gstreamer/gstlibcamerasrc.cpp | 41 +++++++++++++++- 3 files changed, 117 insertions(+), 1 deletion(-) diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index 750ec351..43ce75cb 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -553,3 +553,75 @@ gst_libcamera_get_camera_manager(int &ret) return cm; } + +libcamera::Transform +gst_libcamera_orientation_to_transform(GstVideoOrientationMethod orientation) +{ + switch (orientation) { + case GST_VIDEO_ORIENTATION_90R: + return Transform::Rot90; + case GST_VIDEO_ORIENTATION_180: + return Transform::Rot180; + case GST_VIDEO_ORIENTATION_90L: + return Transform::Rot270; + case GST_VIDEO_ORIENTATION_HORIZ: + return Transform::HFlip; + case GST_VIDEO_ORIENTATION_VERT: + return Transform::VFlip; + case GST_VIDEO_ORIENTATION_UL_LR: + return Transform::Transpose; + case GST_VIDEO_ORIENTATION_UR_LL: + return Transform::Rot180Transpose; + case GST_VIDEO_ORIENTATION_IDENTITY: + default: + return Transform::Identity; + } +} + +GstVideoOrientationMethod +gst_libcamera_transform_to_orientation(libcamera::Transform transform) +{ + switch (transform) { + case Transform::Rot90: + return GST_VIDEO_ORIENTATION_90R; + case Transform::Rot180: + return GST_VIDEO_ORIENTATION_180; + case Transform::Rot270: + return GST_VIDEO_ORIENTATION_90L; + case Transform::HFlip: + return GST_VIDEO_ORIENTATION_HORIZ; + case Transform::VFlip: + return GST_VIDEO_ORIENTATION_VERT; + case Transform::Transpose: + return GST_VIDEO_ORIENTATION_UL_LR; + case Transform::Rot180Transpose: + return GST_VIDEO_ORIENTATION_UR_LL; + case Transform::Identity: + default: + return GST_VIDEO_ORIENTATION_IDENTITY; + } +} + +const char * +gst_libcamera_transform_to_tag_string(libcamera::Transform transform) +{ + switch (transform) { + case Transform::Rot90: + return "rotate-90"; + case Transform::Rot180: + return "rotate-180"; + case Transform::Rot270: + return "rotate-270"; + case Transform::HFlip: + return "flip-rotate-0"; + case Transform::VFlip: + return "flip-rotate-180"; + case Transform::Transpose: + return "flip-rotate-270"; + case Transform::Rot180Transpose: + return "flip-rotate-90"; + case Transform::Identity: + default: + return "rotate-0"; + } +} diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h index fd304a8b..84d26c47 100644 --- a/src/gstreamer/gstlibcamera-utils.h +++ b/src/gstreamer/gstlibcamera-utils.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,10 @@ gboolean gst_task_resume(GstTask *task); #endif std::shared_ptr gst_libcamera_get_camera_manager(int &ret); +libcamera::Transform gst_libcamera_orientation_to_transform(GstVideoOrientationMethod orientation); +GstVideoOrientationMethod gst_libcamera_transform_to_orientation(libcamera::Transform transform); +const char *gst_libcamera_transform_to_tag_string(libcamera::Transform transform); + /** * \class GLibLocker * \brief A simple scoped mutex locker for GMutex diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 721b35c2..9d9437d0 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -147,6 +147,8 @@ struct _GstLibcameraSrc { gchar *camera_name; + GstVideoOrientationMethod transform; + GstLibcameraSrcState *state; GstLibcameraAllocator *allocator; GstFlowCombiner *flow_combiner; @@ -154,7 +156,9 @@ struct _GstLibcameraSrc { enum { PROP_0, - PROP_CAMERA_NAME + PROP_CAMERA_NAME, + PROP_TRANSFORM, + PROP_LAST }; G_DEFINE_TYPE_WITH_CODE(GstLibcameraSrc, gst_libcamera_src, GST_TYPE_ELEMENT, @@ -461,6 +465,8 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, GLibRecLocker lock(&self->stream_lock); GstLibcameraSrcState *state = self->state; GstFlowReturn flow_ret = GST_FLOW_OK; + libcamera::Transform tag_transform; + const char* tag_string; gint ret; g_autoptr(GstStructure) element_caps = gst_structure_new_empty("caps"); @@ -513,12 +519,27 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, if (flow_ret != GST_FLOW_OK) goto done; + state->config_->transform = + gst_libcamera_orientation_to_transform (self->transform); + /* Validate the configuration. */ if (state->config_->validate() == CameraConfiguration::Invalid) { flow_ret = GST_FLOW_NOT_NEGOTIATED; goto done; } + tag_transform = (gst_libcamera_orientation_to_transform (self->transform) ^ + state->config_->transform); + tag_string = gst_libcamera_transform_to_tag_string(tag_transform); + for (gsize i = 0; i < state->srcpads_.size(); i++) { + GstPad *srcpad = state->srcpads_[i]; + GstEvent *tag_event; + + tag_event = gst_event_new_tag(gst_tag_list_new(GST_TAG_IMAGE_ORIENTATION, + tag_string, NULL)); + gst_pad_push_event (srcpad, tag_event); + } + ret = state->cam_->configure(state->config_.get()); if (ret) { GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, @@ -659,6 +680,11 @@ 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_TRANSFORM: + self->transform = + static_cast( + g_value_get_enum(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -676,6 +702,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_TRANSFORM: + g_value_set_enum(value, self->transform); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -845,4 +874,14 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) | G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_TRANSFORM, + g_param_spec_enum ("transform", "Transform", + "Request a transform (rotation and/or flip).", + GST_TYPE_VIDEO_ORIENTATION_METHOD, + GST_VIDEO_ORIENTATION_IDENTITY, + (GParamFlags)(GST_PARAM_MUTABLE_READY + | G_PARAM_CONSTRUCT + | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS))); }