From patchwork Mon Aug 15 13:31:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rishikesh Donadkar X-Patchwork-Id: 17124 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 19A95BE173 for ; Mon, 15 Aug 2022 13:31:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CAC3D61FC3; Mon, 15 Aug 2022 15:31:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660570292; bh=c4HDZss6r6Z017pyvGPJh1FOWQpdILDMYB9Q6/vtoE8=; 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=ZUSdawBRtbilq5oBT7NGtZmEEj2VID7hJcPJ5Y+6RdG6pVIPMPlsJc/p6MCKlZ1Ln 7goFQN/jDC1e7sD+6lfkKzfhNEH5GUNYe8CmmzsJaZEzHf7KcC+8GwUAuu1hkFIG6n 5rOIzlm8K2k+a8zHMKauqcX8RwXCEc3iBdAQo1+I/VYhloBWvysQ6ReNVzYR2dLcb5 yBd8RXPGUt0+dsDBsDAzcZKhrFdqDYxyzLMFcXo33pVaj2+Qz54b6HauHIXyZTrx/d J0CYgsqAj9XFU+unjQwg3ZPfDEgAgq60azmy8T9f6SZFv6I/a4p/Xyhe3tfjybZUsO Ex4pdCWNyL9Ww== Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DFEB461FBC for ; Mon, 15 Aug 2022 15:31:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="C4Jn1coa"; dkim-atps=neutral Received: by mail-pj1-x102a.google.com with SMTP id c19-20020a17090ae11300b001f2f94ed5c6so11717881pjz.1 for ; Mon, 15 Aug 2022 06:31:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=81Vs4Wg2AgP5FQLrkdCpH+GBIE+AopgMo3UgBS5G8fM=; b=C4Jn1coaDqnBCYFFaOxLcSlzPA7Mhzn+EXqecLW4vkniBGpye/i2LHt/E0WcVAxffz 9rcaSz3HUguYLlD0M0+mIxWbqT72LiWOzhm7W2BZxJyW594iZKZ0Wgdf0tIrnbZS9GVx C0+MUwKAdWtRErTCdobim6bnhAMo3e/lhiVuhup/4NY8J0elB40d2weO8M/yyuWu+DyD sT9muAfw1+Fsw71N708Ux9MkuSOu2kpAWXNItnTAjeJ7PeKhur/f0TudNjrG+R9zPzTw J1wqogXNnWIbcHpthDpYzuRvMGL43NCnTwRLuAYZ+FlDR+16k1bdOL6U6FgbdN/gtVAR cBvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=81Vs4Wg2AgP5FQLrkdCpH+GBIE+AopgMo3UgBS5G8fM=; b=xbjV25iayRoLaqX3W33cUTu7V9oVFv46Eqd3zLkPUp/PuW2jwiano1yQMNvVtIXT5h pZ2307Fo4asO/YQUyADxgzFdTnA6CbcB08q8Y0Rg0EkWwbzFVvXAmRxIFMfIIFmFTn95 4dByGxreYH0Ur/rgamVQMZP8sw/V9rq6X5mgdaQ3kA7IsBfwboXK1kB+Xy8fLi+dmfts I/CutqwRbzvofNjxoySHtyvLF2XbhWLsPQyxIjS1DZtpDS7WMsw1HAx25ys1MU7JPF7z Yzvt5u8uGK0/Do9JWpWdcN/7J8LcILjsIQOeIOqulNMosfZsMxAuufNQ9IHbkXr7kcy8 fv7A== X-Gm-Message-State: ACgBeo031O7T1V9MzU41CEvBJGhx+C4XCq6Q5bYeUe7EebArQKB6pc/n gMh6UmgVJQY5Ve/lCntBImHDLmZI3YXD/A== X-Google-Smtp-Source: AA6agR4f1/gh894DxyVmC0irdAy6XJaAJ0UYkisPo7bv/y0494UnrDKrWdGuHStzO9ULKCwUFTlC6g== X-Received: by 2002:a17:902:ecc8:b0:16f:9355:c103 with SMTP id a8-20020a170902ecc800b0016f9355c103mr17345232plh.122.1660570290273; Mon, 15 Aug 2022 06:31:30 -0700 (PDT) Received: from localhost.localdomain ([49.36.101.94]) by smtp.googlemail.com with ESMTPSA id e3-20020aa798c3000000b00528bd940390sm6532068pfm.153.2022.08.15.06.31.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 15 Aug 2022 06:31:29 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 15 Aug 2022 19:01:05 +0530 Message-Id: <20220815133105.15025-2-rishikeshdonadkar@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220815133105.15025-1-rishikeshdonadkar@gmail.com> References: <20220815133105.15025-1-rishikeshdonadkar@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/1] gstreamer: Provide mulitple colorimetry support 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: Rishikesh Donadkar via libcamera-devel From: Rishikesh Donadkar Reply-To: Rishikesh Donadkar Cc: Rishikesh Donadkar , nicolas.dufresne@collabora.com, vedantparanjape160201@gmail.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Append copy of the structure with best suitable resolution into a fresh new caps and normalize the caps using gst_caps_normalize(). This will return caps where the colorimetry list is expanded. The ncaps will contain as many structures as the number of colorimetry specified in the GStreamer pipeline. Iterate over each structure in the ncaps, retrieve the colorimetry string, convert to colorspace using the function colorspace_from_colorimetry() and validate the camera configuration. Retrieve the colorspace after validation, convert to colorimetry and check if the it is same as the colorimetry requested. If none of the colorimetry requested is supported by the camera (i.e. not the same after validation) then set the stream_cfg to the previous configuration that was present before trying new colorimetry. Signed-off-by: Rishikesh Donadkar Signed-off-by: Umang Jain --- src/gstreamer/gstlibcamera-utils.cpp | 73 ++++++++++++++++++++-------- src/gstreamer/gstlibcamera-utils.h | 4 +- src/gstreamer/gstlibcamerasrc.cpp | 2 +- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index d895a67d..5dc3efcf 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -302,13 +302,36 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg return caps; } +static void +configure_colorspace_from_caps(StreamConfiguration &stream_cfg, + GstStructure *s) +{ + if (gst_structure_has_field(s, "colorimetry")) { + const gchar *colorimetry_str = gst_structure_get_string(s, "colorimetry"); + GstVideoColorimetry colorimetry; + + if (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str)) + g_critical("Invalid colorimetry %s", colorimetry_str); + + stream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry); + /* Check if colorimetry had any identifiers which did not map */ + if (colorimetry.primaries != GST_VIDEO_COLOR_PRIMARIES_UNKNOWN && + stream_cfg.colorSpace == ColorSpace::Raw) { + GST_ERROR("One or more identifiers could not be mapped for %s colorimetry", + colorimetry_str); + stream_cfg.colorSpace = std::nullopt; + } + } +} + void -gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg, +gst_libcamera_configure_stream_from_caps(std::unique_ptr &cam_cfg, + StreamConfiguration &stream_cfg, GstCaps *caps) { GstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat); guint i; - gint best_fixed = -1, best_in_range = -1; + gint best_fixed = -1, best_in_range = -1, colorimetry_index = -1; GstStructure *s; /* @@ -354,10 +377,13 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg, } /* Prefer reliable fixed value over ranges */ - if (best_fixed >= 0) + if (best_fixed >= 0) { s = gst_caps_get_structure(caps, best_fixed); - else + colorimetry_index = best_fixed; + } else { s = gst_caps_get_structure(caps, best_in_range); + colorimetry_index = best_in_range; + } if (gst_structure_has_name(s, "video/x-raw")) { const gchar *format = gst_video_format_to_string(gst_format); @@ -381,21 +407,30 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg, stream_cfg.size.width = width; stream_cfg.size.height = height; - /* Configure colorimetry */ - if (gst_structure_has_field(s, "colorimetry")) { - const gchar *colorimetry_str = gst_structure_get_string(s, "colorimetry"); - GstVideoColorimetry colorimetry; - - if (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str)) - g_critical("Invalid colorimetry %s", colorimetry_str); - - stream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry); - /* Check if colorimetry had any identifiers which did not map */ - if (colorimetry.primaries != GST_VIDEO_COLOR_PRIMARIES_UNKNOWN && - stream_cfg.colorSpace == ColorSpace::Raw) { - GST_ERROR("One or more identifiers could not be mapped for %s colorimetry", - colorimetry_str); - stream_cfg.colorSpace = std::nullopt; + /* Create new caps, copy the structure with best resolutions + * and normalize the caps. + */ + GstCaps *ncaps = gst_caps_copy_nth(caps, colorimetry_index); + ncaps = gst_caps_normalize(ncaps); + + /* Configure Colorimetry */ + StreamConfiguration pristine_stream_cfg = stream_cfg; + for (i = 0; i < gst_caps_get_size(ncaps); i++) { + GstStructure *ns = gst_caps_get_structure(ncaps, i); + GstVideoColorimetry colorimetry_old, colorimetry_new; + colorimetry_old = colorimetry_from_colorspace(stream_cfg.colorSpace.value()); + configure_colorspace_from_caps(stream_cfg, ns); + + /* Validate the configuration and check if the requested + * colorimetry can be applied to the sensor. + */ + if (cam_cfg->validate() != CameraConfiguration::Invalid) { + colorimetry_new = colorimetry_from_colorspace(stream_cfg.colorSpace.value()); + if (gst_video_colorimetry_is_equal(&colorimetry_old,&colorimetry_new)) { + g_print("Selected colorimetry %s\n", gst_video_colorimetry_to_string(&colorimetry_new)); + break; + } else + stream_cfg = pristine_stream_cfg; } } } diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h index 164189a2..7afad576 100644 --- a/src/gstreamer/gstlibcamera-utils.h +++ b/src/gstreamer/gstlibcamera-utils.h @@ -8,6 +8,7 @@ #pragma once +#include #include #include @@ -16,7 +17,8 @@ GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats); GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg); -void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg, +void gst_libcamera_configure_stream_from_caps(std::unique_ptr &cam_cfg, + libcamera::StreamConfiguration &stream_cfg, GstCaps *caps); #if !GST_CHECK_VERSION(1, 17, 1) gboolean gst_task_resume(GstTask *task); diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 16d70fea..25059914 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -503,7 +503,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, /* Fixate caps and configure the stream. */ caps = gst_caps_make_writable(caps); - gst_libcamera_configure_stream_from_caps(stream_cfg, caps); + gst_libcamera_configure_stream_from_caps(state->config_, stream_cfg, caps); } if (flow_ret != GST_FLOW_OK)