From patchwork Fri Oct 23 10:58:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 28593 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 A170EC324C for ; Fri, 23 Oct 2026 11:00:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 680D268FCB; Fri, 23 Oct 2026 13:00:48 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="laUvmczL"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5F82768FCB for ; Fri, 23 Oct 2026 13:00:47 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c30:59f6:be2b:2877:6bc4:392]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 380954D89; Fri, 23 Oct 2026 12:58:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1792753118; bh=0y/oA1+KGIZFtpUSbpLciZ3rgOYFMLbyKWl6eRIjsUo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=laUvmczLH/WbnDuOgZ1aSqyAfYjRQs0tgMSrz/3mBlE2+pn0H9IG9ieTVkTHqQMvd VwIkqj2WcJ96CRxUUBVkbZ4TmTYPOWoMc2P5kwU0sfUl5Yc7DXw4MkIHJkhVhNP2fL i7RO8V2Y0AuFVlZVX0Lp5uvCcQUj2bJaf3deP5/A= From: Jai Luthra Date: Fri, 23 Oct 2026 16:28:31 +0530 Subject: [PATCH WIP RFC 23/26] pipeline: rpi: pisp: Migrate to RAW formats MIME-Version: 1.0 Message-Id: <20261023-b4-raw-model-v1-23-eadb9948901b@ideasonboard.com> References: <20261023-b4-raw-model-v1-0-eadb9948901b@ideasonboard.com> In-Reply-To: <20261023-b4-raw-model-v1-0-eadb9948901b@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart , Kieran Bingham , Sakari Ailus , Naushir Patuck , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=8761; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=0y/oA1+KGIZFtpUSbpLciZ3rgOYFMLbyKWl6eRIjsUo=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBq2z3ZXpI2W6zcN9i8BNShFdi+xj9EzsSO2UA8z +RUBQ8y/jmJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCats92QAKCRBD3pH5JJpx RdasEAC5/My0nBb/3jYhcs2VzT9ealBbKPPjfkfcgV+MD2H9xKps3VbmG/fq0DQNUS8dZ3GSyF9 KjoMSG04PnAfKoBQ4OVPWWkAOnZjMFRwW9I2JvL+n8UmcjXq3H7RV4lTQ63Pt5+4DZ8q1UEaoG/ PMLpzlglIgP/L+hpreadIRahqHC34tDujCK1HMkJjs8mpeyRYSyW4EcUMHNMBO9g6eT3LJgf63g 3oqR7wKIqrSCbG5QHJyPhMPNxPbsuP6JqxmwHH3MTkTL2c0NBLFaFuoALkJ36r8Ky40lr/xenfx 7peFLJqyNSGi46L/4H2Cl8T01JqGNEXCJw1t6HJl11aX2LLsnaApuRawczEavXfUWzwLD24BHoo wM6Plm3bCoFLZ5cEse9vursEkcTIdMG3dNyAyj7sBbAb60VZZvKpM6eUGVD9S6Mvu7U6QMo5C2B 6i56P4GjT6/Jg+P1gxd7huKBX+/cr7dSyhZj5toW+UIgOR3tZmU3neml/K+hvFFoGzrI78tTBHg m7TFTdwiA6dZYXuD45glD1uAC8FLEr5QA9tn6yeHZhKry5YsMMF9KadZ8ibdpQlf3wXlJILM+W3 Pm2ocTOp0K4i2xonv79l2jWLX5GzcwzZ9MwHTJnOj0Tfr6SWu1CtxZLSUGvXTLMAEyPTVhiddcN QyNeIINyOPHv6AA== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 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" Both the PiSP CFE and BE drivers support the new generic RAW formats, so switch to using those. Both of those hardware blocks need to know the bayer order of the incoming raw data. They used to extract it from the media bus codes before, which is no longer possible. Instead pass it explicitly to them by fetching it from the CameraSensor::bayerOrder() helper. Also drop the now unnecessary mbusCodeUnpacked16() helper. Signed-off-by: Jai Luthra --- src/libcamera/pipeline/rpi/pisp/pisp.cpp | 76 ++++++++++++-------------------- 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp index b4a5f87aa93d..41e1b46a1136 100644 --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include "libcamera/internal/device_enumerator.h" @@ -56,32 +57,12 @@ constexpr unsigned int DefaultCompressionOffset = 2048; constexpr unsigned int DefaultCompressionMode = 1; const std::vector> BayerToMbusCodeMap{ - { { ColorFilterArray::BGGR, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR8_1X8, }, - { { ColorFilterArray::GBRG, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG8_1X8, }, - { { ColorFilterArray::GRBG, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG8_1X8, }, - { { ColorFilterArray::RGGB, 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB8_1X8, }, - { { ColorFilterArray::BGGR, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR10_1X10, }, - { { ColorFilterArray::GBRG, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG10_1X10, }, - { { ColorFilterArray::GRBG, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG10_1X10, }, - { { ColorFilterArray::RGGB, 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB10_1X10, }, - { { ColorFilterArray::BGGR, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR12_1X12, }, - { { ColorFilterArray::GBRG, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG12_1X12, }, - { { ColorFilterArray::GRBG, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG12_1X12, }, - { { ColorFilterArray::RGGB, 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB12_1X12, }, - { { ColorFilterArray::BGGR, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR14_1X14, }, - { { ColorFilterArray::GBRG, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG14_1X14, }, - { { ColorFilterArray::GRBG, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG14_1X14, }, - { { ColorFilterArray::RGGB, 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB14_1X14, }, - { { ColorFilterArray::BGGR, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SBGGR16_1X16, }, - { { ColorFilterArray::GBRG, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGBRG16_1X16, }, - { { ColorFilterArray::GRBG, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SGRBG16_1X16, }, - { { ColorFilterArray::RGGB, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_SRGGB16_1X16, }, - { { ColorFilterArray::BGGR, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SBGGR16_1X16, }, - { { ColorFilterArray::GBRG, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SGBRG16_1X16, }, - { { ColorFilterArray::GRBG, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SGRBG16_1X16, }, - { { ColorFilterArray::RGGB, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_SRGGB16_1X16, }, - { { ColorFilterArray::MONO, 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_Y16_1X16, }, - { { ColorFilterArray::MONO, 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_Y16_1X16, }, + { { 8, BayerFormat::Packing::None }, MEDIA_BUS_FMT_RAW_8, }, + { { 10, BayerFormat::Packing::None }, MEDIA_BUS_FMT_RAW_10, }, + { { 12, BayerFormat::Packing::None }, MEDIA_BUS_FMT_RAW_12, }, + { { 14, BayerFormat::Packing::None }, MEDIA_BUS_FMT_RAW_14, }, + { { 16, BayerFormat::Packing::None }, MEDIA_BUS_FMT_RAW_16, }, + { { 16, BayerFormat::Packing::PISP1 }, MEDIA_BUS_FMT_RAW_16, }, }; unsigned int bayerToMbusCode(const BayerFormat &bayer) @@ -97,19 +78,9 @@ unsigned int bayerToMbusCode(const BayerFormat &bayer) return 0; } -uint32_t mbusCodeUnpacked16(unsigned int code) +uint8_t toPiSPBayerOrder(const ColorFilterArray &cfa) { - BayerFormat bayer = BayerFormat::fromMbusCode(code); - BayerFormat bayer16(bayer.cfa.order, 16, BayerFormat::Packing::None); - - return bayerToMbusCode(bayer16); -} - -uint8_t toPiSPBayerOrder(V4L2PixelFormat format) -{ - BayerFormat bayer = BayerFormat::fromV4L2PixelFormat(format); - - switch (bayer.cfa.order) { + switch (cfa.order) { case ColorFilterArray::Order::BGGR: return PISP_BAYER_ORDER_BGGR; case ColorFilterArray::Order::GBRG: @@ -816,9 +787,10 @@ private: int configureEntities(V4L2SubdeviceFormat sensorFormat, V4L2SubdeviceFormat &embeddedFormat); - int configureCfe(); + int configureCfe(const ColorFilterArray &bayerOrder); bool calculateCscConfiguration(const V4L2DeviceFormat &v4l2Format, pisp_be_ccm_config &csc); - int configureBe(const std::optional &yuvColorSpace); + int configureBe(const std::optional &yuvColorSpace, + const ColorFilterArray &bayerOrder); void platformSetIspCrop(unsigned int index, const Rectangle &ispCrop) override; @@ -1444,6 +1416,13 @@ int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConf V4L2VideoDevice *cfe = cfe_[Cfe::Output0].dev(); V4L2DeviceFormat cfeFormat; + /* + * The sensor bayer order is the order of the data arriving at the + * CFE Frontend, as affected by any transform applied to the sensor. + */ + ColorFilterArray sensorBayerOrder = + sensor_->bayerOrder(rpiConfig->combinedTransform_); + /* * See which streams are requested, and route the user * StreamConfiguration appropriately. @@ -1454,7 +1433,7 @@ int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConf * mbus code right at the start. */ V4L2SubdeviceFormat sensorFormatMod = rpiConfig->sensorFormat_; - sensorFormatMod.code = mbusCodeUnpacked16(sensorFormatMod.code); + sensorFormatMod.code = MEDIA_BUS_FMT_RAW_16; cfeFormat = RPi::PipelineHandlerBase::toV4L2DeviceFormat(cfe, sensorFormatMod, BayerFormat::Packing::PISP1); @@ -1679,10 +1658,10 @@ int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConf } configureEntities(rpiConfig->sensorFormat_, embeddedFormat); - configureCfe(); + configureCfe(sensorBayerOrder); if (beEnabled_) - configureBe(rpiConfig->yuvColorSpace_); + configureBe(rpiConfig->yuvColorSpace_, sensorBayerOrder); return 0; } @@ -1915,7 +1894,7 @@ void PiSPCameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool handleState(); } -int PiSPCameraData::configureCfe() +int PiSPCameraData::configureCfe(const ColorFilterArray &bayerOrder) { V4L2DeviceFormat cfeFormat; cfe_[Cfe::Output0].dev()->getFormat(&cfeFormat); @@ -1927,7 +1906,7 @@ int PiSPCameraData::configureCfe() global.enables &= ~PISP_FE_ENABLE_COMPRESS0; global.enables |= PISP_FE_ENABLE_OUTPUT0; - global.bayer_order = toPiSPBayerOrder(cfeFormat.fourcc); + global.bayer_order = toPiSPBayerOrder(bayerOrder); pisp_image_format_config image = toPiSPImageFormat(cfeFormat); pisp_fe_input_config input = {}; @@ -2002,7 +1981,8 @@ bool PiSPCameraData::calculateCscConfiguration(const V4L2DeviceFormat &v4l2Forma return false; } -int PiSPCameraData::configureBe(const std::optional &yuvColorSpace) +int PiSPCameraData::configureBe(const std::optional &yuvColorSpace, + const ColorFilterArray &bayerOrder) { pisp_image_format_config inputFormat; V4L2DeviceFormat cfeFormat; @@ -2025,7 +2005,7 @@ int PiSPCameraData::configureBe(const std::optional &yuvColorSpace) PISP_BE_RGB_ENABLE_CSC1); global.bayer_enables |= PISP_BE_BAYER_ENABLE_INPUT; - global.bayer_order = toPiSPBayerOrder(cfeFormat.fourcc); + global.bayer_order = toPiSPBayerOrder(bayerOrder); if (PISP_IMAGE_FORMAT_COMPRESSED(inputFormat.format)) { pisp_decompress_config decompress; @@ -2249,7 +2229,7 @@ int PiSPCameraData::configureEntities(V4L2SubdeviceFormat sensorFormat, } V4L2SubdeviceFormat feFormat = sensorFormat; - feFormat.code = mbusCodeUnpacked16(sensorFormat.code); + feFormat.code = MEDIA_BUS_FMT_RAW_16; ret = feSubdev_->setFormat(feVideoSinkPad, &feFormat); if (ret) return ret;