From bc2b7c2ff22502a578eaae8b0b1aa10bc9c18b2a Mon Sep 17 00:00:00 2001 From: Santiago Barros Date: Tue, 26 May 2026 17:40:08 -0600 Subject: [PATCH] pipeline: rpi: Derive RAW stream Bayer order from the selected sensor mode The IMX900 uses a different Bayer order per mode (binned 1032x776 = GBRG, full-resolution 2064x1552 = RGGB). RPiCameraConfiguration::validate() sets the RAW stream's Bayer order from sensor_->bayerOrder(combinedTransform_), i.e. the sensor's single assumed native order, which libcamera takes from the first-enumerated mbus code (SGBRG12, GBRG). At full resolution findBestFormat() correctly selects the RGGB mode, but the RAW stream order stays GBRG, so the CFE output node is configured with PC1g (GBRG) while the CSI2 source pad is RGGB. The RP1 CFE then rejects the pipeline at stream-on: rp1-cfe: Format mismatch! /dev/video7: Failed to start streaming: Invalid argument This breaks every capture wider than the binned mode. Derive the RAW stream Bayer order from the actually-selected sensor mode (sensorFormat_.code), which is exactly what the CFE source pad carries, instead of the assumed single native order. Full-res then selects PC1R (RGGB) and link validation passes; the binned mode continues to use PC1g. Verified on IMX900 (Framos FSM:GO) on Raspberry Pi 5, Raspberry Pi OS trixie, kernel 6.18.29+rpt-rpi-2712: full-res 2064x1552 JPEG + RAW capture now succeed. Signed-off-by: Santiago Barros --- src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 09d30f34d..67a0a8dc9 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -246,7 +246,14 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() */ BayerFormat cfgBayer = BayerFormat::fromPixelFormat(rawStream->pixelFormat); - cfgBayer.order = data_->sensor_->bayerOrder(combinedTransform_); + /* + * Some sensors (e.g. IMX900) use a different Bayer order for + * different modes (binned vs full-res), which breaks the + * single-native-order assumption of sensor_->bayerOrder(). + * Derive the order from the actually-selected sensor mode so + * it matches the CFE source pad and link validation passes. + */ + cfgBayer.order = BayerFormat::fromMbusCode(sensorFormat_.code).order; if (rawStream->pixelFormat != cfgBayer.toPixelFormat()) { rawStream->pixelFormat = cfgBayer.toPixelFormat();