From patchwork Fri Jun 27 11:34:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23672 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 2EBE9BDCBF for ; Fri, 27 Jun 2025 11:35:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E9ABF68E04; Fri, 27 Jun 2025 13:35:03 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="NyBy/CCW"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2769668DE5 for ; Fri, 27 Jun 2025 13:35:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024101; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DcptFM68nRdu1Ny+Lz6jUbxawGYaZYvEj4bQrvKafs8=; b=NyBy/CCW5g/clAkRT352PSEjOjEQqxbkZaZyVUqdAKmLxUqYmQZZ2XgQoQrzBmdgi5Grte mFa3fHEkhga6qfCCWbojPpMSaXXM3vcYplX7uYfsLttLCATTaph75Z73HhgOR4gJwxCQ2h D0ARNo04Lvulif3pvHH7tnv6H01ZebU= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-137-KIKksOJTMXiYp5w7-QLIww-1; Fri, 27 Jun 2025 07:34:59 -0400 X-MC-Unique: KIKksOJTMXiYp5w7-QLIww-1 X-Mimecast-MFC-AGG-ID: KIKksOJTMXiYp5w7-QLIww_1751024098 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 33119180028F; Fri, 27 Jun 2025 11:34:58 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9C7E730001BC; Fri, 27 Jun 2025 11:34:55 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 01/12] libcamera: software_isp: Assign colour spaces in configurations Date: Fri, 27 Jun 2025 13:34:36 +0200 Message-ID: <20250627113449.23106-2-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: -CPUHAeox0iODySr8o4AXxfulU232bjFaWCXvfjbOIo_1751024098 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" StreamConfiguration's should have colorSpace set. This is not the case in the simple pipeline. Let's set it there. This also fixes a crash in `cam' due to accessing an unset colorSpace. The colour space is assigned as follows: - If raw role is requested, then the colour space must be raw. - Otherwise, if software ISP is used, the default colour space is set to Srgb (YcbcrEncoding::None, Range::Full). - Otherwise, if a converter is used, the default colour space is left unset. - Then in configuration validation, if the pixel format is changed, the colour space is set according to the new pixel format. - If the colour space is still unset, it is set according to the resulting pixel format. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index efb07051b..a008b13d1 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include "libcamera/internal/converter.h" #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/formats.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/software_isp/software_isp.h" @@ -1206,8 +1208,24 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() if (cfg.pixelFormat != pixelFormat) { LOG(SimplePipeline, Debug) << "Adjusting pixel format"; cfg.pixelFormat = pixelFormat; + if (cfg.colorSpace && cfg.colorSpace != ColorSpace::Raw) + cfg.colorSpace->adjust(pixelFormat); status = Adjusted; } + if (!cfg.colorSpace) { + const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); + switch (info.colourEncoding) { + case PixelFormatInfo::ColourEncodingRGB: + cfg.colorSpace = ColorSpace::Srgb; + break; + case libcamera::PixelFormatInfo::ColourEncodingYUV: + cfg.colorSpace = ColorSpace::Sycc; + break; + default: + cfg.colorSpace = ColorSpace::Raw; + } + cfg.colorSpace->adjust(pixelFormat); + } if (!pipeConfig_->outputSizes.contains(cfg.size)) { Size adjustedSize = pipeConfig_->captureSize; @@ -1314,11 +1332,16 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Spanfirst; cfg.size = formats.begin()->second[0].max; + if (role == StreamRole::Raw) + cfg.colorSpace = ColorSpace::Raw; + else if (data->swIsp_) + cfg.colorSpace = ColorSpace::Srgb; + config->addConfiguration(cfg); } From patchwork Fri Jun 27 11:34:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23674 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 54E0BBDCBF for ; Fri, 27 Jun 2025 11:35:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C599B68E08; Fri, 27 Jun 2025 13:35:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Eqw9ys5u"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6A64268DFD for ; Fri, 27 Jun 2025 13:35:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024105; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ioaBcIZBrVWBOSCAPaTw6GdzIxBw2RXBhvsoEtUcrpE=; b=Eqw9ys5uJBuXMIDUBYuWwJs3JRZ5X0j8/8BkNVGzP1BLkT5RSKkaavrG5SveMc4SUbzKSv 5WkERSVdXv4Khs10c04om8NF8f+Q1lR1nH+eDu5iWYORwrST5NUA+7ktrMjHOlm8A00vOn lqidA7dr3zd6PrCMaZCdtUVIZ63nmNk= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-369-2qBOK2fUN9ia6hQsAPqecA-1; Fri, 27 Jun 2025 07:35:01 -0400 X-MC-Unique: 2qBOK2fUN9ia6hQsAPqecA-1 X-Mimecast-MFC-AGG-ID: 2qBOK2fUN9ia6hQsAPqecA_1751024100 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C184C1955ECA; Fri, 27 Jun 2025 11:35:00 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B7A2C30001BC; Fri, 27 Jun 2025 11:34:58 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 02/12] libcamera: simple: Set the number of software ISP streams to 2 Date: Fri, 27 Jun 2025 13:34:37 +0200 Message-ID: <20250627113449.23106-3-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: NmMTBUCGEIYhQeV5BhqpX06AKIzfk5RnNroRbEg3tfI_1751024100 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" When software ISP is enabled, we want to be able to provide a raw stream in addition to the processed stream. For this purpose, we need two streams. If only the processed stream is requested, it doesn't harm to allocate two. This is a hack for the lack of a better easy option. The number of streams is determined as a camera property in the pipeline matching. The actual number of streams needed (one or two) is determined only when examining roles in SimplePipelineHandler::generateConfiguration. In theory, software ISP could produce multiple processed streams but this is out of scope of this patch series. Hence two streams are sufficient at the moment. When software ISP is not enabled, the camera won't be able to produce multiple streams (assuming there's no hardware converter) and only single stream should be allocated as before. The simple pipeline handler assumes there's a linear pipeline from the camera sensor to a video capture device, and only supports a single stream. Branches in the hardware pipeline that would allow capturing multiple streams from the same camera sensor are not supported. We have no plan to change that, as a device that can produce multiple streams will likely be better supported by a dedicated pipeline handler. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index a008b13d1..ab19149e4 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1710,7 +1710,16 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) } } - swIspEnabled_ = info->swIspEnabled; + if (info->swIspEnabled) { + /* + * When the software ISP is enabled, the simple pipeline handler + * exposes the raw stream, giving a total of two streams. This + * is mutally exclusive with the presence of a converter. + */ + ASSERT(!converter_); + numStreams = 2; + swIspEnabled_ = true; + } /* Locate the sensors. */ std::vector sensors = locateSensors(media); From patchwork Fri Jun 27 11:34:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23675 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 827E3BDCBF for ; Fri, 27 Jun 2025 11:35:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 346B468E0D; Fri, 27 Jun 2025 13:35:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="NOHt7zse"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 65BAF68E0A for ; Fri, 27 Jun 2025 13:35:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024108; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JxxMmNy4a4CkCas6P7X+AchZGD7v1+4LUxqdV7wjy0U=; b=NOHt7zse4kSCZzAPaLNtkIyTwq6GP3muFQqp09yV+GbfC3r6lc81sM04Wd3M2V/GoT9SUe 6CNAS2M87p1clRswp6hTptzchG6wC7w7I4TcH2bwRhnkmI3DQMG49M4ZqVSvjPt0XKK7Kd GTAORbIoQjokgEY3koDHEUKNHdYcXXA= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-534-sVhoC1H-PhqsR5TEV2lXSA-1; Fri, 27 Jun 2025 07:35:04 -0400 X-MC-Unique: sVhoC1H-PhqsR5TEV2lXSA-1 X-Mimecast-MFC-AGG-ID: sVhoC1H-PhqsR5TEV2lXSA_1751024103 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 914811955ED4; Fri, 27 Jun 2025 11:35:03 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 645A430001BC; Fri, 27 Jun 2025 11:35:01 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 03/12] libcamera: formats: Add a helper to check for a raw pixel format Date: Fri, 27 Jun 2025 13:34:38 +0200 Message-ID: <20250627113449.23106-4-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 6HshWs13LNn0fW9OZJtzz1_kCK2ZJNoGKlKXXacMW0w_1751024103 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" There are several places with the same pattern to check whether a given pixel format is a raw format: return libcamera::PixelFormatInfo::info(pixFmt).colourEncoding == libcamera::PixelFormatInfo::ColourEncodingRAW; Let's move the corresponding isFormatRaw helper from mali-c55.cpp to formats.cpp and use it where applicable. This also avoids a need to introduce the same helper (or the same pattern) in the followup patches. Signed-off-by: Milan Zamazal --- include/libcamera/internal/formats.h | 2 ++ src/libcamera/formats.cpp | 11 +++++++++++ src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 4 ++-- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 10 ---------- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 7 ++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/libcamera/internal/formats.h b/include/libcamera/internal/formats.h index 6a3e9c16a..bc4417d05 100644 --- a/include/libcamera/internal/formats.h +++ b/include/libcamera/internal/formats.h @@ -62,4 +62,6 @@ public: std::array planes; }; +bool isFormatRaw(const libcamera::PixelFormat &pixFmt); + } /* namespace libcamera */ diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index bfcdfc089..c6e0a2620 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -1215,4 +1215,15 @@ unsigned int PixelFormatInfo::numPlanes() const return count; } +/** + * \brief Return whether the given pixel format is a raw format + * \param[in] pixFmt The pixel format to examine + * \return True iff the given format is a raw format + */ +bool isFormatRaw(const libcamera::PixelFormat &pixFmt) +{ + return libcamera::PixelFormatInfo::info(pixFmt).colourEncoding == + libcamera::PixelFormatInfo::ColourEncodingRAW; +} + } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index f4014b95d..c9f56af02 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -24,6 +24,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/formats.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/v4l2_subdevice.h" @@ -312,8 +313,7 @@ unsigned int ISICameraData::getYuvMediaBusFormat(const PixelFormat &pixelFormat) unsigned int ISICameraData::getMediaBusFormat(PixelFormat *pixelFormat) const { - if (PixelFormatInfo::info(*pixelFormat).colourEncoding == - PixelFormatInfo::ColourEncodingRAW) + if (isFormatRaw(*pixelFormat)) return getRawMediaBusFormat(pixelFormat); return getYuvMediaBusFormat(*pixelFormat); diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 4acc091bd..8d9b1e380 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -42,16 +42,6 @@ #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" -namespace { - -bool isFormatRaw(const libcamera::PixelFormat &pixFmt) -{ - return libcamera::PixelFormatInfo::info(pixFmt).colourEncoding == - libcamera::PixelFormatInfo::ColourEncodingRAW; -} - -} /* namespace */ - namespace libcamera { LOG_DEFINE_CATEGORY(MaliC55) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 675f0a749..50c83fb72 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -538,8 +538,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() */ if (config_.size() > 1) { for (const auto &cfg : config_) { - if (PixelFormatInfo::info(cfg.pixelFormat).colourEncoding == - PixelFormatInfo::ColourEncodingRAW) { + if (isFormatRaw(cfg.pixelFormat)) { config_.resize(1); status = Adjusted; break; @@ -553,9 +552,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() * Platforms with dewarper support, such as i.MX8MP, support * only a single stream. We can inspect config_[0] only here. */ - bool isRaw = PixelFormatInfo::info(config_[0].pixelFormat).colourEncoding == - PixelFormatInfo::ColourEncodingRAW; - if (!isRaw) + if (!isFormatRaw(config_[0].pixelFormat)) useDewarper = true; } From patchwork Fri Jun 27 11:34:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23676 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 100E3BDCBF for ; Fri, 27 Jun 2025 11:35:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 760DF68E0A; Fri, 27 Jun 2025 13:35:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="g3v+YJ3+"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9630068DFD for ; Fri, 27 Jun 2025 13:35:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024110; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=soUfJXaDR+wU0GsG/WvnXKBnUeh/fIwyGCIli0b4ing=; b=g3v+YJ3+/r9nPmF257huNSgSImOUFtRsQlvdUy3dWwZzERq2oysLAJbmTt0++/lZ4nWUCL K6S7YDGz/ScnpAPcVDEcaOJPPu4gISAi4OgCX0yvHC5xLZYinV0KNIN6phRdd57uS0yf1+ Eo2cCgxXEWtmqlgtYbovVPcKzaRwDL4= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-16-e1Bix66AP6aBwlT753ItBw-1; Fri, 27 Jun 2025 07:35:07 -0400 X-MC-Unique: e1Bix66AP6aBwlT753ItBw-1 X-Mimecast-MFC-AGG-ID: e1Bix66AP6aBwlT753ItBw_1751024106 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4FE141800290; Fri, 27 Jun 2025 11:35:06 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1F68C30001BC; Fri, 27 Jun 2025 11:35:03 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 04/12] libcamera: formats: Add a helper to check for a raw pixel info Date: Fri, 27 Jun 2025 13:34:39 +0200 Message-ID: <20250627113449.23106-5-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: pDTudQQX7pPNZbhtEtAuLddjK0opyX9_hXPAwsCPdL8_1751024106 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" There is another common pattern checking for raw colour encoding, present in multiple places: pixelFormatInfo.colourEncoding == PixelFormatInfo::ColourEncodingRAW Let's extract it into a helper too. Signed-off-by: Milan Zamazal --- include/libcamera/internal/formats.h | 1 + src/libcamera/formats.cpp | 9 +++++++-- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 7 +++---- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++-- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 7 +++---- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/libcamera/internal/formats.h b/include/libcamera/internal/formats.h index bc4417d05..dd81a8889 100644 --- a/include/libcamera/internal/formats.h +++ b/include/libcamera/internal/formats.h @@ -32,6 +32,7 @@ public: }; bool isValid() const { return format.isValid(); } + bool isRaw() const { return colourEncoding == ColourEncodingRAW; } static const PixelFormatInfo &info(const PixelFormat &format); static const PixelFormatInfo &info(const V4L2PixelFormat &format); diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp index c6e0a2620..02888acf2 100644 --- a/src/libcamera/formats.cpp +++ b/src/libcamera/formats.cpp @@ -993,6 +993,12 @@ const std::map pixelFormatInfo{ * \return True if the pixel format info is valid, false otherwise */ +/** + * \fn bool PixelFormatInfo::isRaw() const + * \brief Check if the colour encoding is raw + * \return True if the colour encoding is raw, false otherwise + */ + /** * \brief Retrieve information about a pixel format * \param[in] format The pixel format @@ -1222,8 +1228,7 @@ unsigned int PixelFormatInfo::numPlanes() const */ bool isFormatRaw(const libcamera::PixelFormat &pixFmt) { - return libcamera::PixelFormatInfo::info(pixFmt).colourEncoding == - libcamera::PixelFormatInfo::ColourEncodingRAW; + return libcamera::PixelFormatInfo::info(pixFmt).isRaw(); } } /* namespace libcamera */ diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index c9f56af02..cfee5f820 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -452,9 +452,8 @@ ISICameraConfiguration::validateYuv(std::set &availableStreams, /* If the stream is RAW or not supported default it to YUYV. */ const PixelFormatInfo &cfgInfo = PixelFormatInfo::info(cfg.pixelFormat); - if (cfgInfo.colourEncoding == PixelFormatInfo::ColourEncodingRAW || - !formatsMap_.count(cfg.pixelFormat)) { + if (cfgInfo.isRaw() || !formatsMap_.count(cfg.pixelFormat)) { LOG(ISI, Debug) << "Stream " << i << " format: " << cfg.pixelFormat << " adjusted to YUYV"; @@ -523,7 +522,7 @@ CameraConfiguration::Status ISICameraConfiguration::validate() const PixelFormatInfo info = PixelFormatInfo::info(config_[0].pixelFormat); Status validationStatus; - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + if (info.isRaw()) validationStatus = validateRaw(availableStreams, maxResolution); else validationStatus = validateYuv(availableStreams, maxResolution); @@ -651,7 +650,7 @@ StreamConfiguration PipelineHandlerISI::generateYUVConfiguration(Camera *camera, for (const auto &[pixFmt, pipeFmt] : ISICameraConfiguration::formatsMap_) { const PixelFormatInfo &info = PixelFormatInfo::info(pixFmt); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + if (info.isRaw()) continue; streamFormats[pixFmt] = { { kMinISISize, sensorSize } }; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index e31e3879d..6d10ed7f9 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -218,7 +218,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() for (const StreamConfiguration &cfg : config_) { const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { + if (info.isRaw()) { rawCount++; rawSize = std::max(rawSize, cfg.size); } else { @@ -286,7 +286,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() LOG(IPU3, Debug) << "Validating stream: " << config_[i].toString(); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { + if (info.isRaw()) { /* Initialize the RAW stream with the CIO2 configuration. */ cfg->size = cio2Configuration_.size; cfg->pixelFormat = cio2Configuration_.pixelFormat; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 50c83fb72..4c6be9b75 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -651,7 +651,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() for (const StreamConfiguration &cfg : config_) { const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + if (info.isRaw()) rawFormat = cfg.pixelFormat; maxSize = std::max(maxSize, cfg.size); @@ -842,7 +842,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) Rectangle outputCrop = inputCrop; const PixelFormat &streamFormat = config->at(0).pixelFormat; const PixelFormatInfo &info = PixelFormatInfo::info(streamFormat); - isRaw_ = info.colourEncoding == PixelFormatInfo::ColourEncodingRAW; + isRaw_ = info.isRaw(); useDewarper_ = dewarper_ && !isRaw_; /* YUYV8_2X8 is required on the ISP source path pad for YUV output. */ diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 64018dc5b..3e437b0c2 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -188,7 +188,7 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size, const PixelFormatInfo &info = PixelFormatInfo::info(format); /* Populate stream formats for non-RAW configurations. */ - if (info.colourEncoding != PixelFormatInfo::ColourEncodingRAW) { + if (!info.isRaw()) { if (role == StreamRole::Raw) continue; @@ -279,7 +279,7 @@ RkISP1Path::validate(const CameraSensor *sensor, for (const auto &format : streamFormats_) { const PixelFormatInfo &info = PixelFormatInfo::info(format); - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { + if (info.isRaw()) { /* Skip raw formats not supported by the sensor. */ uint32_t mbusCode = formatToMediaBus.at(format); if (std::find(mbusCodes.begin(), mbusCodes.end(), mbusCode) == @@ -310,8 +310,7 @@ RkISP1Path::validate(const CameraSensor *sensor, if (sensorConfig && !rawFormat.isValid()) return CameraConfiguration::Invalid; - bool isRaw = PixelFormatInfo::info(cfg->pixelFormat).colourEncoding == - PixelFormatInfo::ColourEncodingRAW; + bool isRaw = PixelFormatInfo::info(cfg->pixelFormat).isRaw(); /* * If no raw format supported by the sensor has been found, use a From patchwork Fri Jun 27 11:34:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23677 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 0C583BDCBF for ; Fri, 27 Jun 2025 11:35:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B31E668E11; Fri, 27 Jun 2025 13:35:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="hEl8aKZs"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2CD7B68DFC for ; Fri, 27 Jun 2025 13:35:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024115; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+OPkc3eTDuz3Q9IitVmLmeHUMc6rADfF6TVg1BXZ03c=; b=hEl8aKZsfi+HM8K12Z1VK0zjKLLktWZRzt8/FFxVaJLs0sxv1hh9uEGf2DqOh5ZFhKjnv7 evy7taUyLtHhR2Fs//vbeOoTHPsdZLBe/Pj/N2G6JGHeULoyWx/Az8mpu1BnefreQk+VJm Xawls8Ig6e/15/yYzA7PZmcWRFAUjHY= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-154-p9HqDZy2PwKNEQBGnZBbrg-1; Fri, 27 Jun 2025 07:35:10 -0400 X-MC-Unique: p9HqDZy2PwKNEQBGnZBbrg-1 X-Mimecast-MFC-AGG-ID: p9HqDZy2PwKNEQBGnZBbrg_1751024109 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 5EA35180029F; Fri, 27 Jun 2025 11:35:09 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CE09730001BC; Fri, 27 Jun 2025 11:35:06 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 05/12] libcamera: simple: Don't use raw output formats with conversions Date: Fri, 27 Jun 2025 13:34:40 +0200 Message-ID: <20250627113449.23106-6-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: lbzQYiTWEhAYbSKDxCmuLmtueZ6nSpuIyp2HZ5d4vIU_1751024109 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" In order to support raw streams, we need to add raw formats to software ISP configurations. In this preparatory patch, the raw formats are excluded from output configurations for conversions. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index ab19149e4..60b7e1b15 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1411,7 +1412,7 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) cfg.setStream(&data->streams_[i]); - if (data->useConversion_) + if (data->useConversion_ && !isFormatRaw(cfg.pixelFormat)) outputCfgs.push_back(cfg); } From patchwork Fri Jun 27 11:34:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23678 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 B65A6BDCBF for ; Fri, 27 Jun 2025 11:35:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6156B68E0D; Fri, 27 Jun 2025 13:35:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="SRVm+Hng"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6E39468DFC for ; Fri, 27 Jun 2025 13:35:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024118; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4B/BkBa3QmIXAXf+RPKWXwmbIOeQOcXkgoqe9fdBrgI=; b=SRVm+HngY9QjWE08CymsgPOAaREFonYy+scX4rZSJpZ5w9QFPujWFA7/kGzN6TTm2kZJW1 1rkbGc6nmrh14vCEQ+GFdNOxI7Z5Tv6dpeGlAKS/ruFTQIgqnRDMh/CUdHORKaQDIHNpHP FcCrmpQmQHW8bp2Y9uiDOOV6EBOQnwM= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-332-qpTpp52CPquRfQBdDIRt8w-1; Fri, 27 Jun 2025 07:35:15 -0400 X-MC-Unique: qpTpp52CPquRfQBdDIRt8w-1 X-Mimecast-MFC-AGG-ID: qpTpp52CPquRfQBdDIRt8w_1751024112 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 4862B19373D8; Fri, 27 Jun 2025 11:35:12 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EF05B30001BC; Fri, 27 Jun 2025 11:35:09 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 06/12] libcamera: simple: Add plain output configurations Date: Fri, 27 Jun 2025 13:34:41 +0200 Message-ID: <20250627113449.23106-7-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: R4vUPsfMwnl-0GXFO4yhqPyGf8U_zcrTI4n_7PNARYQ_1751024112 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" Output configurations in simple pipeline are added depending on whether a converter, software ISP or none of them are used. If a converter or software ISP is used, no raw output configurations are added. Unless only raw configurations are available, in which case we add them to avoid ... In order to support raw output at least with software ISP, let's always add raw output configurations. A flag is added to SimpleCameraData::Configuration indicating whether it's for a raw or a converted output. We later filter formats and output sizes for particular stream configurations according to the new configuration flag. This is just preparation and raw output is still not supported. At the moment, we simply filter out raw configurations unconditionally to keep the current code working; this will be changed in followup patches. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 60b7e1b15..d0f44c7d1 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -319,6 +319,7 @@ public: Size captureSize; std::vector outputFormats; SizeRange outputSizes; + bool raw; }; std::vector streams_; @@ -708,27 +709,33 @@ void SimpleCameraData::tryPipeline(unsigned int code, const Size &size) continue; Configuration config; + + /* Raw configuration */ config.code = code; config.sensorSize = size; config.captureFormat = pixelFormat; config.captureSize = format.size; + config.outputFormats = { pixelFormat }; + config.outputSizes = config.captureSize; + config.raw = true; + configs_.push_back(config); + /* Modified, non-raw, configuration */ + config.raw = false; if (converter_) { config.outputFormats = converter_->formats(pixelFormat); config.outputSizes = converter_->sizes(format.size); } else if (swIsp_) { - config.outputFormats = swIsp_->formats(pixelFormat); - config.outputSizes = swIsp_->sizes(pixelFormat, format.size); - if (config.outputFormats.empty()) { + std::vector outputFormats = swIsp_->formats(pixelFormat); + if (outputFormats.empty()) { /* Do not use swIsp for unsupported pixelFormat's. */ - config.outputFormats = { pixelFormat }; - config.outputSizes = config.captureSize; + continue; } + config.outputFormats = outputFormats; + config.outputSizes = swIsp_->sizes(pixelFormat, format.size); } else { - config.outputFormats = { pixelFormat }; - config.outputSizes = config.captureSize; + continue; } - configs_.push_back(config); } } @@ -1301,10 +1308,13 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span> formats; - for (const SimpleCameraData::Configuration &cfg : data->configs_) { - for (PixelFormat format : cfg.outputFormats) - formats[format].push_back(cfg.outputSizes); - } + const bool rawOnly = std::all_of(data->configs_.cbegin(), + data->configs_.cend(), + [](const auto &c) { return c.raw; }); + for (const SimpleCameraData::Configuration &cfg : data->configs_) + if (!cfg.raw || rawOnly) + for (PixelFormat format : cfg.outputFormats) + formats[format].push_back(cfg.outputSizes); /* Sort the sizes and merge any consecutive overlapping ranges. */ for (auto &[format, sizes] : formats) { From patchwork Fri Jun 27 11:34:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23679 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 EB784BDCBF for ; Fri, 27 Jun 2025 11:35:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6918068E11; Fri, 27 Jun 2025 13:35:24 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="GtRu0B5s"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 940B268E08 for ; Fri, 27 Jun 2025 13:35:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024119; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=6xHkiODqX5LnaQ0d2g1Fn0ljHGyKlVo3QKZfReG+rpw=; b=GtRu0B5sXa02kGRZAKWniRD1t3yiypE9rVuvaTGq8p6eLmM2TofuhUF6jzU772eNKVW6dP vXZyVpF2VLJ4r3An9OHETGKlRvVoflx8PscHIed+PfM8XT0Lkn1XlZIjcBF9l4/9DTC79c mHWJP3FZ3seDeVyWugVWsYftRlGyKB4= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-605-PzWesp1FO0aXSK5ePtYXKg-1; Fri, 27 Jun 2025 07:35:16 -0400 X-MC-Unique: PzWesp1FO0aXSK5ePtYXKg-1 X-Mimecast-MFC-AGG-ID: PzWesp1FO0aXSK5ePtYXKg_1751024115 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E89871955ECA; Fri, 27 Jun 2025 11:35:14 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CE24030001BC; Fri, 27 Jun 2025 11:35:12 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 07/12] libcamera: simple: Identify requested stream roles Date: Fri, 27 Jun 2025 13:34:42 +0200 Message-ID: <20250627113449.23106-8-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: sdMHGpfhkGRiN8ZGyPPZBg7FQi1YGXvZv14aJb1EX54_1751024115 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" Currently, raw streams don't work in the simple pipeline and the requested stream roles are ignored. In order to support raw streams, we now track in SimpleCameraConfiguration whether raw and/or processed streams are requested. We also check that at most one raw stream is requested, there is no reason to have more. That information will be used in the followup patches. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index d0f44c7d1..0219a3931 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -378,6 +378,9 @@ public: bool needConversion() const { return needConversion_; } const Transform &combinedTransform() const { return combinedTransform_; } + bool processedRequested_; + bool rawRequested_; + private: /* * The SimpleCameraData instance is guaranteed to be valid as long as @@ -1299,12 +1302,27 @@ std::unique_ptr SimplePipelineHandler::generateConfiguration(Camera *camera, Span roles) { SimpleCameraData *data = cameraData(camera); - std::unique_ptr config = + std::unique_ptr config = std::make_unique(camera, data); + config->processedRequested_ = false; + config->rawRequested_ = false; + if (roles.empty()) return config; + for (const auto &role : roles) + if (role == StreamRole::Raw) { + if (config->rawRequested_) { + LOG(SimplePipeline, Error) + << "Can't capture multiple raw streams"; + return nullptr; + } + config->rawRequested_ = true; + } else { + config->processedRequested_ = true; + } + /* Create the formats map. */ std::map> formats; From patchwork Fri Jun 27 11:34:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23680 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 CE0FBBDCBF for ; Fri, 27 Jun 2025 11:35:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7B34968E17; Fri, 27 Jun 2025 13:35:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="TCK6a2bF"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C7EEC68DE5 for ; Fri, 27 Jun 2025 13:35:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4oUhyjTQpfDgWhmFtZBYlsSkKRNcih5lThge7RTJPkw=; b=TCK6a2bFZhQjRI/mlrhSVULpiSfaPfZJiXlO+7lQzF0nEEXXTo0ta8bz02OJQA6WzF7chU oeN+khOnphvswDNW1emWaPnOJTuQbYD/oLKv6K/u59QwTkgGE7ipZpkD81F+zrHeBxQdM6 4GRHfVUTKjkrcCQTRrPd4Y86m4+BlTU= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-186-8jKDv4R-PI2RtWJxurJ0zA-1; Fri, 27 Jun 2025 07:35:18 -0400 X-MC-Unique: 8jKDv4R-PI2RtWJxurJ0zA-1 X-Mimecast-MFC-AGG-ID: 8jKDv4R-PI2RtWJxurJ0zA_1751024117 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 846241944A83; Fri, 27 Jun 2025 11:35:17 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6A0E330001BC; Fri, 27 Jun 2025 11:35:15 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 08/12] libcamera: simple: Consider raw output configurations Date: Fri, 27 Jun 2025 13:34:43 +0200 Message-ID: <20250627113449.23106-9-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: D5O6rBvYuL3iABTn6RXsPy2zbENfRb5ioOxcxKWK5uY_1751024117 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" When generating simple pipeline configuration, raw output configurations are generated but later filtered out. Let's include processed and/or raw output configurations depending on the requested stream roles. Raw and processed formats are handled separately. The intention is that in case both raw and processed formats are requested then the raw formats should be left intact to the extent possible and not be influenced by the processed formats (implying that raw parameters compatible with the processed output requirements must be requested by the application). Raw output configurations are identified by colorSpace being set to ColorSpace::Raw. This is another preparatory patch without making raw outputs working. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 71 ++++++++++++++---------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 0219a3931..91fd43237 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1323,37 +1323,50 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, SpanprocessedRequested_ = true; } - /* Create the formats map. */ - std::map> formats; + /* Create the formats maps. */ + std::map> processedFormats; + std::map> rawFormats; - const bool rawOnly = std::all_of(data->configs_.cbegin(), - data->configs_.cend(), - [](const auto &c) { return c.raw; }); for (const SimpleCameraData::Configuration &cfg : data->configs_) - if (!cfg.raw || rawOnly) - for (PixelFormat format : cfg.outputFormats) - formats[format].push_back(cfg.outputSizes); - - /* Sort the sizes and merge any consecutive overlapping ranges. */ - for (auto &[format, sizes] : formats) { - std::sort(sizes.begin(), sizes.end(), - [](SizeRange &a, SizeRange &b) { - return a.min < b.min; - }); - - auto cur = sizes.begin(); - auto next = cur; - - while (++next != sizes.end()) { - if (cur->max.width >= next->min.width && - cur->max.height >= next->min.height) - cur->max = next->max; - else if (++cur != next) - *cur = *next; - } + for (PixelFormat format : cfg.outputFormats) + (cfg.raw ? rawFormats : processedFormats)[format].push_back(cfg.outputSizes); - sizes.erase(++cur, sizes.end()); + if (config->processedRequested_ && processedFormats.empty()) { + LOG(SimplePipeline, Error) + << "Processed stream requsted but no corresponding output configuration found"; + return nullptr; } + if (config->rawRequested_ && rawFormats.empty()) { + LOG(SimplePipeline, Error) + << "Raw stream requsted but no corresponding output configuration found"; + return nullptr; + } + + auto setUpFormatSizes = [](std::map> &formats) { + /* Sort the sizes and merge any consecutive overlapping ranges. */ + + for (auto &[format, sizes] : formats) { + std::sort(sizes.begin(), sizes.end(), + [](SizeRange &a, SizeRange &b) { + return a.min < b.min; + }); + + auto cur = sizes.begin(); + auto next = cur; + + while (++next != sizes.end()) { + if (cur->max.width >= next->min.width && + cur->max.height >= next->min.height) + cur->max = next->max; + else if (++cur != next) + *cur = *next; + } + + sizes.erase(++cur, sizes.end()); + } + }; + setUpFormatSizes(processedFormats); + setUpFormatSizes(rawFormats); /* * Create the stream configurations. Take the first entry in the formats @@ -1362,11 +1375,13 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Spanfirst; cfg.size = formats.begin()->second[0].max; - if (role == StreamRole::Raw) + if (raw) cfg.colorSpace = ColorSpace::Raw; else if (data->swIsp_) cfg.colorSpace = ColorSpace::Srgb; From patchwork Fri Jun 27 11:34:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23681 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 29E87BDCBF for ; Fri, 27 Jun 2025 11:35:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A101668E08; Fri, 27 Jun 2025 13:35:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="RqyPJaah"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C571768DE5 for ; Fri, 27 Jun 2025 13:35:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024122; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pceOLDF9eb7pHJCObRLsTK0gcmyKvFSUQJh7qlHExOg=; b=RqyPJaahg+pcpQN0C0SjbBAx2UeiQogR8ybCQ/VndaigrSvQpvTqZZGzJv0x4h+W+W59pM fUXv7vVlAod/amuObKgf57JNmUcPduSYnTZwivAbaub7CyFsuUeSvISp8W7yuDphtozw3D nz8uQR3x4Ici/x1dfCn2R27TzTPf7aI= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-388-87afLQ5eNzGxBKV3uI5EEw-1; Fri, 27 Jun 2025 07:35:21 -0400 X-MC-Unique: 87afLQ5eNzGxBKV3uI5EEw-1 X-Mimecast-MFC-AGG-ID: 87afLQ5eNzGxBKV3uI5EEw_1751024120 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 46B5A1944A8C; Fri, 27 Jun 2025 11:35:20 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1CDBE30001BC; Fri, 27 Jun 2025 11:35:17 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 09/12] libcamera: simple: Validate raw stream configurations Date: Fri, 27 Jun 2025 13:34:44 +0200 Message-ID: <20250627113449.23106-10-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: vIxiG5R0UTgey-q6gsciR56_YS_gL9oQR9Y57qGbSBs_1751024120 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" SimpleCameraConfiguration::validate() looks for the best configuration. As part of enabling raw stream support, the method must consider raw streams in addition to the processed streams. If only a processed stream is requested, nothing changes. If only a raw stream is requested, the pixel format and output size may not be adjusted. The patch adds checks for this. If both processed and raw streams are requested, things get more complicated. The raw stream is expected to be passed through intact and all the adjustments are made for the processed streams. We select a pipe configuration for the processed streams. Note that with both processed and raw streams, the requested sizes must be mutually matching, including resizing due to debayer requirements. For example, the following `cam' setup is valid for imx219 cam -s role=viewfinder,width=1920,height=1080 \ -s role=raw,width=3280,height=2464 rather than cam -s role=viewfinder,width=1920,height=1080 \ -s role=raw,width=1920,height=1080 due to the resolution of 1924x1080 actually selected for debayering to 1920x1080. It is the application responsibility to select the right parameters for the raw stream. Setting up the right configurations is still not enough to make the raw streams working. Buffer handling must be changed in the simple pipeline, which is addressed in followup patches. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 115 +++++++++++++++++------ 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 91fd43237..f914c2713 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1167,6 +1168,9 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() pipeConfig_ = nullptr; for (const SimpleCameraData::Configuration *pipeConfig : *configs) { + if (processedRequested_ && pipeConfig->raw) + continue; + const Size &size = pipeConfig->captureSize; if (size.width >= maxStreamSize.width && @@ -1190,6 +1194,18 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() << "-" << pipeConfig_->captureFormat << " for max stream size " << maxStreamSize; + /* + * Update raw/processed flags. If e.g. an application calls + * generateConfiguration() with an empty list of roles and adds + * configurations by calling addConfiguration(), the flags must be updated + * according to those configurations. + */ + for (const auto &cfg : config_) + if (cfg.colorSpace == ColorSpace::Raw) + rawRequested_ = true; + else + processedRequested_ = true; + /* * Adjust the requested streams. * @@ -1208,37 +1224,60 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() for (unsigned int i = 0; i < config_.size(); ++i) { StreamConfiguration &cfg = config_[i]; + /* + * If both processed and raw streams are requested, the pipe + * configuration is set up for the processed stream. The raw + * configuration needs to be compared against the capture format and + * size in such a case. + */ + const bool rawStream = cfg.colorSpace == ColorSpace::Raw; + const bool sideRawStream = rawStream && processedRequested_; + /* Adjust the pixel format and size. */ - auto it = std::find(pipeConfig_->outputFormats.begin(), - pipeConfig_->outputFormats.end(), - cfg.pixelFormat); - if (it == pipeConfig_->outputFormats.end()) - it = pipeConfig_->outputFormats.begin(); - - PixelFormat pixelFormat = *it; - if (cfg.pixelFormat != pixelFormat) { - LOG(SimplePipeline, Debug) << "Adjusting pixel format"; - cfg.pixelFormat = pixelFormat; - if (cfg.colorSpace && cfg.colorSpace != ColorSpace::Raw) + + if (!sideRawStream) { + auto it = std::find(pipeConfig_->outputFormats.begin(), + pipeConfig_->outputFormats.end(), + cfg.pixelFormat); + if (it == pipeConfig_->outputFormats.end()) + it = pipeConfig_->outputFormats.begin(); + + PixelFormat pixelFormat = *it; + + if (cfg.pixelFormat != pixelFormat) { + if (rawStream) { + LOG(SimplePipeline, Info) + << "Raw pixel format " + << cfg.pixelFormat + << " doesn't match any of the pipe output formats"; + return Invalid; + } + LOG(SimplePipeline, Debug) + << "Adjusting pixel format from " << cfg.pixelFormat + << " to " << pixelFormat; + cfg.pixelFormat = pixelFormat; + if (cfg.colorSpace && cfg.colorSpace != ColorSpace::Raw) + cfg.colorSpace->adjust(pixelFormat); + status = Adjusted; + } + + if (!cfg.colorSpace) { + const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); + switch (info.colourEncoding) { + case PixelFormatInfo::ColourEncodingRGB: + cfg.colorSpace = ColorSpace::Srgb; + break; + case libcamera::PixelFormatInfo::ColourEncodingYUV: + cfg.colorSpace = ColorSpace::Sycc; + break; + default: + cfg.colorSpace = ColorSpace::Raw; + } cfg.colorSpace->adjust(pixelFormat); - status = Adjusted; - } - if (!cfg.colorSpace) { - const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); - switch (info.colourEncoding) { - case PixelFormatInfo::ColourEncodingRGB: - cfg.colorSpace = ColorSpace::Srgb; - break; - case libcamera::PixelFormatInfo::ColourEncodingYUV: - cfg.colorSpace = ColorSpace::Sycc; - break; - default: - cfg.colorSpace = ColorSpace::Raw; } - cfg.colorSpace->adjust(pixelFormat); } - if (!pipeConfig_->outputSizes.contains(cfg.size)) { + if (!sideRawStream && !pipeConfig_->outputSizes.contains(cfg.size)) { Size adjustedSize = pipeConfig_->captureSize; /* * The converter (when present) may not be able to output @@ -1246,8 +1285,17 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() * not guaranteed to be a valid output size. In such cases, use * the smaller valid output size closest to the requested. */ - if (!pipeConfig_->outputSizes.contains(adjustedSize)) + if (!pipeConfig_->outputSizes.contains(adjustedSize)) { + if (rawStream) { + LOG(SimplePipeline, Info) + << "Raw output size " + << cfg.size + << " doesn't match any of the pipe output sizes: " + << pipeConfig_->outputSizes; + return Invalid; + } adjustedSize = adjustSize(cfg.size, pipeConfig_->outputSizes); + } LOG(SimplePipeline, Debug) << "Adjusting size from " << cfg.size << " to " << adjustedSize; @@ -1257,11 +1305,20 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() /* \todo Create a libcamera core class to group format and size */ if (cfg.pixelFormat != pipeConfig_->captureFormat || - cfg.size != pipeConfig_->captureSize) + cfg.size != pipeConfig_->captureSize) { + if (rawStream) { + LOG(SimplePipeline, Info) + << "Raw output format " << cfg.pixelFormat + << " and size " << cfg.size + << " not matching pipe format " << pipeConfig_->captureFormat + << " and size " << pipeConfig_->captureSize; + return Invalid; + } needConversion_ = true; + } /* Set the stride, frameSize and bufferCount. */ - if (needConversion_) { + if (needConversion_ && !rawStream) { std::tie(cfg.stride, cfg.frameSize) = data_->converter_ ? data_->converter_->strideAndFrameSize(cfg.pixelFormat, From patchwork Fri Jun 27 11:34:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23682 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 EFF70BDCBF for ; Fri, 27 Jun 2025 11:35:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9F7C068E1B; Fri, 27 Jun 2025 13:35:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="f/ytfjPb"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 527B168E0C for ; Fri, 27 Jun 2025 13:35:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024127; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=V6ckGWGr2FUBodFejvmtPPbWYI6MbXs1t5PLP/NFAJc=; b=f/ytfjPbBEBqUIUfzbsN+wiT9inkBCyoXCJYoAZW6cebMghf8Vz6qmSdxpDnQJX77IGbmS 0dy42/pQHrRAnt7iA+dzRFDGfO3T9Hmfu/JS9BYET8QGnrRJfg2jT0LJiYOJ02KFe8Q3JS 2YdQnOx+KpP9cYMimY7XPCd7z2XVBug= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-439-kPVnnqcxMeG3ilWJWK_8EQ-1; Fri, 27 Jun 2025 07:35:24 -0400 X-MC-Unique: kPVnnqcxMeG3ilWJWK_8EQ-1 X-Mimecast-MFC-AGG-ID: kPVnnqcxMeG3ilWJWK_8EQ_1751024123 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E681719560B9; Fri, 27 Jun 2025 11:35:22 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id BB12430001BC; Fri, 27 Jun 2025 11:35:20 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 10/12] libcamera: simple: Don't enforce conversion with an added raw stream Date: Fri, 27 Jun 2025 13:34:45 +0200 Message-ID: <20250627113449.23106-11-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: H1n3o74KDGs6AEIpneFmEYXMBEQvKjcD14uXIoyJw2U_1751024123 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" When a raw stream is requested, either alone or together with a processed stream, it can be produced without conversion. Let's amend the corresponding check on the number of configurations, so that the mere presence of a raw stream doesn't enforce conversion. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index f914c2713..92953cf1c 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1219,7 +1219,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() * require any conversion, similar to raw capture use cases). This is * left as a future improvement. */ - needConversion_ = config_.size() > 1; + needConversion_ = config_.size() > 1 + (rawRequested_ ? 1 : 0); for (unsigned int i = 0; i < config_.size(); ++i) { StreamConfiguration &cfg = config_[i]; From patchwork Fri Jun 27 11:34:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23684 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 691ECBDCBF for ; Fri, 27 Jun 2025 11:35:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1215668E11; Fri, 27 Jun 2025 13:35:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="cpCZDYEt"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E5CE68E0A for ; Fri, 27 Jun 2025 13:35:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024133; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZM/dsCZVMGGEqj9hP+axiWwIZPsqAqWDdK/R4lQ8dyo=; b=cpCZDYEt3P5GWCxrq3bVOOF2RQCHOFtY1XaQHtrZ2KzyszsA/lkUFL2Z9sCVvEqs89zYeP 68CvcVuyDOVCO3DDlDhKlmLMR2KAmzoIHretuGEz+gmxFQ+RStOJDW7dgVU1deUNIk5Tke qKMjqD5UUT5W54bpTaBboMZKKnz21RI= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-307-Af8q8i4PMhKEpjwdfo6xaA-1; Fri, 27 Jun 2025 07:35:28 -0400 X-MC-Unique: Af8q8i4PMhKEpjwdfo6xaA-1 X-Mimecast-MFC-AGG-ID: Af8q8i4PMhKEpjwdfo6xaA_1751024127 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A3D6918DA5CB; Fri, 27 Jun 2025 11:35:25 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 78EB630001BC; Fri, 27 Jun 2025 11:35:23 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 11/12] libcamera: simple: Require metadata only when software ISP is used Date: Fri, 27 Jun 2025 13:34:46 +0200 Message-ID: <20250627113449.23106-12-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: g5WrFih8LBJyGtmsT45-yWPaJxH_GxzTRGg-BD5HYSg_1751024127 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" If software ISP is enabled then metadata is required in the simple pipeline. But this doesn't apply if the software ISP is not actually used, for example when only a raw stream is produced. Then the pipeline waits for metadata that never comes. This patch fixes the problem by requiring metadata only when software ISP is used. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 92953cf1c..c7b05f66c 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1661,6 +1661,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request) int ret; std::map buffers; + bool metadataRequired = false; for (auto &[stream, buffer] : request->buffers()) { /* @@ -1670,6 +1671,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request) */ if (data->useConversion_) { buffers.emplace(stream, buffer); + metadataRequired = !!data->swIsp_; } else { ret = data->video_->queueBuffer(buffer); if (ret < 0) @@ -1677,7 +1679,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request) } } - data->frameInfo_.create(request, !!data->swIsp_); + data->frameInfo_.create(request, metadataRequired); if (data->useConversion_) { data->conversionQueue_.push({ request, std::move(buffers) }); if (data->swIsp_) From patchwork Fri Jun 27 11:34:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 23683 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 BBBD1BDCBF for ; Fri, 27 Jun 2025 11:35:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6BFDE68E17; Fri, 27 Jun 2025 13:35:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Xfqgs8yz"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5697168E08 for ; Fri, 27 Jun 2025 13:35:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1751024135; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BDua2j51bpZsJ1Ui+u+Z/9HLNGGZoDmWtjoBIt1lGt0=; b=Xfqgs8yzUV0f1jdfYOoJ+yROadrmt7nqQEfEzoFfo054+6ulY9O/Ccek1AaoOgM3TUxF0i dzisH1kIq/bsKXT7TEA4BMhoD2Y5hj0t0/7CGALo2l8NOfvb+GfQ5cPkPscqJCqzTOGucQ vTt5H1lV0WP92WH8VOc+1e/R4xQ0v7k= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-319-VuR9uKIRPKKyMolt6fvV8A-1; Fri, 27 Jun 2025 07:35:30 -0400 X-MC-Unique: VuR9uKIRPKKyMolt6fvV8A-1 X-Mimecast-MFC-AGG-ID: VuR9uKIRPKKyMolt6fvV8A_1751024129 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 29E4C1800366; Fri, 27 Jun 2025 11:35:29 +0000 (UTC) Received: from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.86]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3F1F830001BC; Fri, 27 Jun 2025 11:35:25 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Milan Zamazal , Laurent Pinchart , Kieran Bingham , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Paul Elder Subject: [PATCH v7 12/12] libcamera: simple: Make raw streams working Date: Fri, 27 Jun 2025 13:34:47 +0200 Message-ID: <20250627113449.23106-13-mzamazal@redhat.com> In-Reply-To: <20250627113449.23106-1-mzamazal@redhat.com> References: <20250627113449.23106-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: j9V_08ZlSgKAQQq5ZZT2US-FeuDkTBLZ3YnpfevGwz0_1751024129 X-Mimecast-Originator: redhat.com content-type: text/plain; charset="US-ASCII"; x-default=true 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" When a raw stream is requested, whether alone or together with a processed stream, its buffers must be handled outside the software ISP machinery. They serve as output buffers, even when a processed stream is produced. At most one raw stream and at most one processed stream are supported and can be combined. An example of producing both raw and processed files using `cam' application: cam -c1 -C100 -Ffile# \ -s role=viewfinder,width=1920,height=1080,pixelformat=RGB888 \ -s role=raw,width=3280,height=2464,pixelformat=SRGGB8 \ Note the difference in viewfinder and raw stream sizes due to the fact that debayering requires enlarging the image width, which enforces selecting a larger sensor resolution in this case. In order to distinguish between different cases, processedRequested_ and rawRequested_ flags are copied from SimpleCameraConfiguration to SimpleCameraData after successful configure(), similarly to useConversion_ flag. This is the final step to make raw streams working. Signed-off-by: Milan Zamazal --- src/libcamera/pipeline/simple/simple.cpp | 35 ++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index c7b05f66c..0e8932263 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -346,6 +346,8 @@ public: }; std::queue conversionQueue_; bool useConversion_; + bool processedRequested_; + bool rawRequested_; std::unique_ptr converter_; std::unique_ptr swIsp_; @@ -871,10 +873,13 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) * point converting an erroneous buffer. */ if (buffer->metadata().status != FrameMetadata::FrameSuccess) { - if (!useConversion_) { + if (rawRequested_) { /* No conversion, just complete the request. */ Request *request = buffer->request(); pipe->completeBuffer(request, buffer); + SimpleFrameInfo *info = frameInfo_.find(request->sequence()); + if (info) + info->metadataRequired = false; tryCompleteRequest(request); return; } @@ -884,7 +889,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) * buffer for capture (unless the stream is being stopped), and * complete the request with all the user-facing buffers. */ - if (buffer->metadata().status != FrameMetadata::FrameCancelled) + if (buffer->metadata().status != FrameMetadata::FrameCancelled && + !rawRequested_) video_->queueBuffer(buffer); if (conversionQueue_.empty()) @@ -933,13 +939,14 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) */ if (useConversion_) { if (conversionQueue_.empty()) { - video_->queueBuffer(buffer); + if (!rawRequested_) + video_->queueBuffer(buffer); return; } if (converter_) converter_->queueBuffers(buffer, conversionQueue_.front().outputs); - else + else if (processedRequested_) /* * request->sequence() cannot be retrieved from `buffer' inside * queueBuffers because unique_ptr's make buffer->request() invalid @@ -949,6 +956,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) conversionQueue_.front().outputs); conversionQueue_.pop(); + if (rawRequested_) + pipe->completeBuffer(request, buffer); return; } @@ -986,7 +995,8 @@ void SimpleCameraData::tryCompleteRequest(Request *request) void SimpleCameraData::conversionInputDone(FrameBuffer *buffer) { /* Queue the input buffer back for capture. */ - video_->queueBuffer(buffer); + if (!rawRequested_) + video_->queueBuffer(buffer); } void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer) @@ -1506,6 +1516,8 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) /* Configure the converter if needed. */ std::vector> outputCfgs; data->useConversion_ = config->needConversion(); + data->processedRequested_ = config->processedRequested_; + data->rawRequested_ = config->rawRequested_; for (unsigned int i = 0; i < config->size(); ++i) { StreamConfiguration &cfg = config->at(i); @@ -1544,7 +1556,7 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, * Export buffers on the converter or capture video node, depending on * whether the converter is used or not. */ - if (data->useConversion_) + if (data->useConversion_ && !data->rawRequested_) return data->converter_ ? data->converter_->exportBuffers(stream, count, buffers) : data->swIsp_->exportBuffers(stream, count, buffers); @@ -1567,7 +1579,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL return -EBUSY; } - if (data->useConversion_) { + if (data->useConversion_ && !data->rawRequested_) { /* * When using the converter allocate a fixed number of internal * buffers. @@ -1575,7 +1587,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL ret = video->allocateBuffers(kNumInternalBuffers, &data->conversionBuffers_); } else { - /* Otherwise, prepare for using buffers from the only stream. */ + /* Otherwise, prepare for using buffers from the only or raw stream. */ Stream *stream = &data->streams_[0]; ret = video->importBuffers(stream->configuration().bufferCount); } @@ -1617,8 +1629,9 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL } /* Queue all internal buffers for capture. */ - for (std::unique_ptr &buffer : data->conversionBuffers_) - video->queueBuffer(buffer.get()); + if (!data->rawRequested_) + for (std::unique_ptr &buffer : data->conversionBuffers_) + video->queueBuffer(buffer.get()); } return 0; @@ -1669,7 +1682,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request) * queue, it will be handed to the converter in the capture * completion handler. */ - if (data->useConversion_) { + if (data->useConversion_ && !isFormatRaw(stream->configuration().pixelFormat)) { buffers.emplace(stream, buffer); metadataRequired = !!data->swIsp_; } else {