From patchwork Wed May 27 15:07:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Mader X-Patchwork-Id: 26810 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 C0755C328C for ; Wed, 27 May 2026 15:07:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7974C63021; Wed, 27 May 2026 17:07:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=collabora.com header.i=robert.mader@collabora.com header.b="SppV8brU"; dkim-atps=neutral Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1DAC462FE1 for ; Wed, 27 May 2026 17:07:40 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; t=1779894457; cv=none; d=zohomail.com; s=zohoarc; b=Ru8q3BhLC1xsNIpeghowKx0Ah3U66BitvbRDKkdxrkq61fYc2EJ5BY62gkibxZUZKZfpqQ7g6PX9yUO+P4KEdAvlDM0s+g+jWxiS75FRzm3uR5eow2R1w8FLErMGE8AbGRbZ+LrJLAiKu4X8fw32pJg1HncjHlfZbV79doVQsQ8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1779894457; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ko/DzzOJgkNfW7oV3sqSG/SGo1Mg04nDIP5hQ1Jm/n4=; b=SaBAYKccY9I+4swiXX/5fScWtdGj4fM0NLqgQ3AA2HLhOws5BHHcfBHnUDjWyT3F8egVfNnwr0lZPMBq5xiyDCVF0Ms6v313RMswUzloNFNuaOYU7TAV8w604D1kxzepZqTKWHlWtkDRr/5r6UuQtyT8ZH8J2CleYKfhYtTaBfU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=robert.mader@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1779894457; s=zohomail; d=collabora.com; i=robert.mader@collabora.com; h=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-ID:MIME-Version:Content-Transfer-Encoding:Message-Id:Reply-To; bh=Ko/DzzOJgkNfW7oV3sqSG/SGo1Mg04nDIP5hQ1Jm/n4=; b=SppV8brUPT1BKQsge/o8il0LG4UOKAvdLMFZ+c85XbODBeqirNwF6wjfUNJaS2j3 atCfvth8pumw1VODh0cc3Ac3Fa60WqJnuRd4ziLHiXkmPgCEvGaaftaOq1eBu0zjpu+ W5YL6ohYltdRmIrpUL/T2XdGdzYQWiKxP7yPrQrI= Received: by mx.zohomail.com with SMTPS id 1779894454875745.5897331191827; Wed, 27 May 2026 08:07:34 -0700 (PDT) From: Robert Mader To: libcamera-devel@lists.libcamera.org Cc: Robert Mader Subject: [PATCH v1] software_isp: Request input buffer alignment of 256 bytes Date: Wed, 27 May 2026 17:07:15 +0200 Message-ID: <20260527150715.67574-1-robert.mader@collabora.com> X-Mailer: git-send-email 2.54.0 MIME-Version: 1.0 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 using the GPU-ISP. This should increase the chances that input buffers can be imported and directly be used by the GPU as stride requirements are the most common reason for import fails. Notes: - 256 is already used for output buffers and known to work across most hardware. Unfortunately there is no API to query the optimal value from the GL driver. - The V4L2 API does not require drivers to honor stride request, thus we log those cases. Signed-off-by: Robert Mader --- Follow-up to https://patchwork.libcamera.org/project/libcamera/list/?series=5965 --- .../libcamera/internal/software_isp/software_isp.h | 1 + src/libcamera/pipeline/simple/simple.cpp | 12 ++++++++++++ src/libcamera/software_isp/debayer.cpp | 8 ++++++++ src/libcamera/software_isp/debayer.h | 1 + src/libcamera/software_isp/debayer_egl.cpp | 7 +++++++ src/libcamera/software_isp/debayer_egl.h | 1 + src/libcamera/software_isp/software_isp.cpp | 13 +++++++++++++ 7 files changed, 43 insertions(+) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index 86cb8f8de..7440937c2 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -61,6 +61,7 @@ public: std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size); + uint32_t getPreferredInputStride(const PixelFormat &inputFormat, const Size &size); int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs, diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index c6fe12d65..0de2fe695 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1542,6 +1542,11 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) captureFormat.fourcc = videoFormat; captureFormat.size = pipeConfig->captureSize; + uint32_t requested_bpl = 0; + if (data->swIsp_) + requested_bpl = data->swIsp_->getPreferredInputStride(videoFormat.toPixelFormat(), pipeConfig->captureSize); + captureFormat.planes[0].bpl = requested_bpl; + ret = video->setFormat(&captureFormat); if (ret) return ret; @@ -1561,6 +1566,13 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c) return -EINVAL; } + if (requested_bpl && captureFormat.planes[0].bpl != requested_bpl) { + LOG(SimplePipeline, Info) + << "Input buffer stride ignored by the driver. " + << "Requested " << requested_bpl + << ", got " << captureFormat.planes[0].bpl; + } + /* Configure the converter if needed. */ std::vector> outputCfgs; data->useConversion_ = config->needConversion(); diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp index 2d7abfb83..858c9b97c 100644 --- a/src/libcamera/software_isp/debayer.cpp +++ b/src/libcamera/software_isp/debayer.cpp @@ -103,6 +103,14 @@ Debayer::~Debayer() * there is no valid output config */ +/** + * \fn uint32_t Debayer::getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) + * Get the preferred input stride in bytes for the given input format and size + * \param[in] inputFormat The input format + * \param[in] size The input size (width and height in pixels) + * \return The preferred input stride in bytes + */ + /** * \fn void Debayer::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params) * \brief Process the bayer data into the requested format diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h index a2a17ec18..136374b8d 100644 --- a/src/libcamera/software_isp/debayer.h +++ b/src/libcamera/software_isp/debayer.h @@ -46,6 +46,7 @@ public: virtual std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0; + virtual uint32_t getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) { return 0; } virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) = 0; virtual int start() { return 0; } diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 7b9e02d90..b7ddec17e 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -20,6 +20,7 @@ #include +#include "libcamera/internal/formats.h" #include "libcamera/internal/framebuffer.h" #include "../glsl_shaders.h" @@ -377,6 +378,12 @@ DebayerEGL::strideAndFrameSize(const PixelFormat &outputFormat, const Size &size return std::make_tuple(stride, stride * size.height); } +uint32_t DebayerEGL::getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) +{ + const PixelFormatInfo &info = PixelFormatInfo::info(inputFormat); + return info.stride(size.width, 0, 256); +} + void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms) { /* diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 141fb288f..1b0153853 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -50,6 +50,7 @@ public: std::vector formats(PixelFormat input) override; std::tuple strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override; + uint32_t getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) override; void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) override; int start() override; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 781cf02f8..f6c8f498e 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -255,6 +255,19 @@ SoftwareIsp::strideAndFrameSize(const PixelFormat &outputFormat, const Size &siz return debayer_->strideAndFrameSize(outputFormat, size); } +/** + * Get the preferred input stride in bytes for the given input format and size + * \param[in] inputFormat The input format + * \param[in] size The input size (width and height in pixels) + * \return The preferred input stride in bytes + */ +uint32_t SoftwareIsp::getPreferredInputStride(const PixelFormat &inputFormat, const Size &size) +{ + ASSERT(debayer_); + + return debayer_->getPreferredInputStride(inputFormat, size); +} + /** * \brief Configure the SoftwareIsp object according to the passed in parameters * \param[in] inputCfg The input configuration