From patchwork Wed Sep 23 17:21:19 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 28365 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 BCCD8C32BB for ; Wed, 23 Sep 2026 17:21:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AB5636895E; Wed, 23 Sep 2026 19:21:43 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gHK5hweO"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C115C6862F for ; Wed, 23 Sep 2026 19:21:41 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:85de:a3c9:9357:b164:bf0b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5DC48177; Wed, 23 Sep 2026 19:19:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1790183994; bh=0eiL79DeoxFE4IRMhO+6zElIEu7uG7/thViC8zNJ1bM=; h=From:To:Cc:Subject:Date:From; b=gHK5hweO9VrQ1jdh6SmLd1YnSviehkxXZ3qAU+0lqWu6YmbFwxRA9xawuUqtKkPrz kES8oRsFfcp97K7O0gpixRQQtnGBCnLGtZFfgcHp75O8xFqaXnn6P8EHwDa3JCwRA+ TwHGoYKPNEP5++DBgCZe6QInyUH1Kp27w4rCpyPQ= From: Jai Luthra To: libcamera-devel@lists.libcamera.org Cc: Kieran Bingham , Naushir Patuck , Jai Luthra Subject: [PATCH] pipeline: rpi: Fix crashes due to scoring unknown formats Date: Wed, 23 Sep 2026 22:51:19 +0530 Message-ID: <20260923172119.1893511-1-jai.luthra@ideasonboard.com> X-Mailer: git-send-email 2.55.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" The mbusCodeToPixelFormat() helper is used at multiple places, including for scoring the formats advertised by the sensor, which might include formats unknown to libcamera. ASSERT(bayer.isValid()) leads to libcamera crashing in such cases, so drop it. Instead switch the return type to a std::optional<> so we can skip scoring unknown or invalid formats. Fixes: 6c71ee1f1530 ("pipeline: raspberrypi: Introduce PipelineHandlerBase class") Signed-off-by: Jai Luthra --- .../pipeline/rpi/common/pipeline_base.cpp | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) -- 2.55.0 diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 71f3f26a4ffe..a85b238ae14f 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -8,6 +8,7 @@ #include "pipeline_base.h" #include +#include #include #include @@ -43,12 +44,12 @@ namespace { constexpr unsigned int defaultRawBitDepth = 12; -PixelFormat mbusCodeToPixelFormat(unsigned int code, - BayerFormat::Packing packingReq) +std::optional +mbusCodeToPixelFormat(unsigned int code, BayerFormat::Packing packingReq) { BayerFormat bayer = BayerFormat::fromMbusCode(code); - - ASSERT(bayer.isValid()); + if (!bayer.isValid()) + return std::nullopt; bayer.packing = packingReq; PixelFormat pix = bayer.toPixelFormat(); @@ -63,6 +64,9 @@ PixelFormat mbusCodeToPixelFormat(unsigned int code, pix = bayer.toPixelFormat(); } + if (!pix.isValid()) + return std::nullopt; + return pix; } @@ -378,10 +382,12 @@ V4L2DeviceFormat PipelineHandlerBase::toV4L2DeviceFormat(const V4L2VideoDevice * BayerFormat::Packing packingReq) { unsigned int code = format.code; - const PixelFormat pix = mbusCodeToPixelFormat(code, packingReq); V4L2DeviceFormat deviceFormat; - deviceFormat.fourcc = dev->toV4L2PixelFormat(pix); + const std::optional pix = mbusCodeToPixelFormat(code, packingReq); + ASSERT(pix.has_value()); + + deviceFormat.fourcc = dev->toV4L2PixelFormat(*pix); deviceFormat.size = format.size; deviceFormat.colorSpace = format.colorSpace; return deviceFormat; @@ -395,7 +401,7 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, std::span(data); V4L2SubdeviceFormat sensorFormat; unsigned int bufferCount; - PixelFormat pixelFormat; + std::optional pixelFormat; V4L2VideoDevice::Formats fmts; Size size; std::optional colorSpace; @@ -411,7 +417,7 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, std::spanfindBestFormat(size, defaultRawBitDepth); pixelFormat = mbusCodeToPixelFormat(sensorFormat.code, BayerFormat::Packing::CSI2); - ASSERT(pixelFormat.isValid()); + ASSERT(pixelFormat.has_value()); colorSpace = ColorSpace::Raw; bufferCount = 2; break; @@ -468,10 +474,10 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, std::spansensorFormats_) { - PixelFormat pf = mbusCodeToPixelFormat(format.first, - BayerFormat::Packing::CSI2); - if (pf.isValid()) - deviceFormats.emplace(std::piecewise_construct, std::forward_as_tuple(pf), + std::optional pf = mbusCodeToPixelFormat(format.first, + BayerFormat::Packing::CSI2); + if (pf.has_value()) + deviceFormats.emplace(std::piecewise_construct, std::forward_as_tuple(*pf), std::forward_as_tuple(format.second.begin(), format.second.end())); } } else { @@ -498,7 +504,7 @@ PipelineHandlerBase::generateConfiguration(Camera *camera, std::spanaddConfiguration(cfg); @@ -958,9 +964,13 @@ V4L2SubdeviceFormat CameraData::findBestFormat(const Size &req, unsigned int bit /* Calculate the closest/best mode from the user requested size. */ for (const auto &[mbusCode, sizes] : sensorFormats_) { - const PixelFormat format = mbusCodeToPixelFormat(mbusCode, - BayerFormat::Packing::None); - const PixelFormatInfo &info = PixelFormatInfo::info(format); + const std::optional format = + mbusCodeToPixelFormat(mbusCode, BayerFormat::Packing::None); + + if (!format.has_value()) + continue; + + const PixelFormatInfo &info = PixelFormatInfo::info(*format); for (const Size &size : sizes) { double reqAr = static_cast(req.width) / req.height; @@ -981,7 +991,7 @@ V4L2SubdeviceFormat CameraData::findBestFormat(const Size &req, unsigned int bit } LOG(RPI, Debug) << "Format: " << size - << " fmt " << format + << " fmt " << *format << " Score: " << score << " (best " << bestScore << ")"; }