[{"id":38981,"web_url":"https://patchwork.libcamera.org/comment/38981/","msgid":"<178040263890.9008.2594484705571345789@freya>","date":"2026-06-02T12:17:18","subject":"Re: [PATCH v2] libcamera: software_isp: Support 12-bit CSI2 packed\n\traw bayer formats","submitter":{"id":223,"url":"https://patchwork.libcamera.org/api/people/223/","name":"Jai Luthra","email":"jai.luthra@ideasonboard.com"},"content":"Quoting Jai Luthra (2026-06-02 17:25:30)\n> Add support for debayering 12-bit CSI2 packed raw bayer formats.\n> \n> Also add support for the same in SwStats, skipping one 2x2 block\n> horizontally and skipping every 3rd and 4th line vertically, like done\n> for other raw bayer formats.\n> \n> GPUISP support was always present in the packed shaders (which already\n> handle skipping the pixel with LSBs), so enable it too.\n> \n> Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>\n> ---\n> This is tested for RGGB12P using IMX678 on Arduino Uno Q. The sensor\n> doesn't change bayer layout on flips, so I couldn't verify other layouts\n> ---\n> Changes in v2:\n> - Handle 12bit/10bit packed stats together\n> - Reuse output format definition across all input formats for each\n>   (CPU/GPU) pipeline\n> - Fix wrong odd pixel bayer order comments in debayer12P_xxx functions\n> - Link to v1: https://lore.kernel.org/r/20260522-swisp_12p-v1-1-e115c35387b7@ideasonboard.com\n\nSorry for the noise,\n\nLink to v1: https://lists.libcamera.org/pipermail/libcamera-devel/2026-May/058925.html\n\nI forgot to drop the lore link.\n\nThanks,\n    Jai","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 69552C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  2 Jun 2026 12:17:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A171663040;\n\tTue,  2 Jun 2026 14:17:29 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3D7BE61754\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  2 Jun 2026 14:17:28 +0200 (CEST)","from mail.ideasonboard.com (unknown\n\t[IPv6:2401:4900:1c66:476d:c684:fe78:389f:7375])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5D9D21112;\n\tTue,  2 Jun 2026 14:17:02 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jfUJSoHt\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1780402624;\n\tbh=5n0oSBCRF7LJz4tubtK5InBGuQahDXZFeFpK+A8T79w=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=jfUJSoHtWASuuYoI1uRg+fl1U5f5lRs+xtcmwV8Tjs9PIYC7uFDxHbnnkCffy0chD\n\tU9oC8KBdGGvTth4tNhDM/5n6Va7mdh35+D3fSLaJEbXtiPwI6VGPgv3DN84VQwZWac\n\tpy7cbsFivR6aZF5YLYBcK5Xm17e8sMhsi2J3Uke0=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260602-swisp_12p-v2-1-2e6d25db7081@ideasonboard.com>","References":"<20260602-swisp_12p-v2-1-2e6d25db7081@ideasonboard.com>","Subject":"Re: [PATCH v2] libcamera: software_isp: Support 12-bit CSI2 packed\n\traw bayer formats","From":"Jai Luthra <jai.luthra@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","To":"Bryan O'Donoghue <bryan.odonoghue@linaro.org>,\n\tHans de Goede <johannes.goede@oss.qualcomm.com>,\n\tMilan Zamazal <mzamazal@redhat.com>","Date":"Tue, 02 Jun 2026 17:47:18 +0530","Message-ID":"<178040263890.9008.2594484705571345789@freya>","User-Agent":"alot/0.13.dev20+g31692a239","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38987,"web_url":"https://patchwork.libcamera.org/comment/38987/","msgid":"<85y0gvvimn.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-06-03T13:49:36","subject":"Re: [PATCH v2] libcamera: software_isp: Support 12-bit CSI2 packed\n\traw bayer formats","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Jai Luthra <jai.luthra@ideasonboard.com> writes:\n\n> Add support for debayering 12-bit CSI2 packed raw bayer formats.\n>\n> Also add support for the same in SwStats, skipping one 2x2 block\n> horizontally and skipping every 3rd and 4th line vertically, like done\n> for other raw bayer formats.\n>\n> GPUISP support was always present in the packed shaders (which already\n> handle skipping the pixel with LSBs), so enable it too.\n>\n> Signed-off-by: Jai Luthra <jai.luthra@ideasonboard.com>\n\nThanks for the updates.\n\nReviewed-by: Milan Zamazal <mzamazal@redhat.com>\n\n> ---\n> This is tested for RGGB12P using IMX678 on Arduino Uno Q. The sensor\n> doesn't change bayer layout on flips, so I couldn't verify other layouts\n> ---\n> Changes in v2:\n> - Handle 12bit/10bit packed stats together\n> - Reuse output format definition across all input formats for each\n>   (CPU/GPU) pipeline\n> - Fix wrong odd pixel bayer order comments in debayer12P_xxx functions\n> - Link to v1: https://lore.kernel.org/r/20260522-swisp_12p-v1-1-e115c35387b7@ideasonboard.com\n> ---\n>  .../libcamera/internal/software_isp/swstats_cpu.h  |   3 +\n>  src/libcamera/software_isp/debayer_cpu.cpp         | 122 +++++++++++++++++++--\n>  src/libcamera/software_isp/debayer_cpu.h           |   9 ++\n>  src/libcamera/software_isp/debayer_egl.cpp         |  25 +++--\n>  src/libcamera/software_isp/swstats_cpu.cpp         |  67 ++++++++++-\n>  5 files changed, 202 insertions(+), 24 deletions(-)\n>\n> diff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\n> index b5348c6fe..13fa75826 100644\n> --- a/include/libcamera/internal/software_isp/swstats_cpu.h\n> +++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n> @@ -98,6 +98,9 @@ private:\n>  \t/* Bayer 10 bpp packed */\n>  \tvoid statsBGGR10PLine0(const uint8_t *src[], SwIspStats &stats);\n>  \tvoid statsGBRG10PLine0(const uint8_t *src[], SwIspStats &stats);\n> +\t/* Bayer 12 bpp packed */\n> +\tvoid statsBGGR12PLine0(const uint8_t *src[], SwIspStats &stats);\n> +\tvoid statsGBRG12PLine0(const uint8_t *src[], SwIspStats &stats);\n>  \n>  \tvoid processBayerFrame2(MappedFrameBuffer &in);\n>  \n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index 1f9b24da0..d2596d32b 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -351,6 +351,78 @@ void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte, bool ccmEnabled>\n> +void DebayerCpu::debayer12P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> +{\n> +\tconst int widthInBytes = window_.width * 3 / 2;\n> +\tconst uint8_t *prev = src[0];\n> +\tconst uint8_t *curr = src[1];\n> +\tconst uint8_t *next = src[2];\n> +\n> +\tfor (int x = 0; x < widthInBytes;) {\n> +\t\t/* Even pixel */\n> +\t\tBGGR_BGR888(2, 1, 1)\n> +\t\t/* Odd pixel BGGR -> GBRG */\n> +\t\tGBRG_BGR888(1, 2, 1)\n> +\t\t/* Skip 3rd src byte with 2 x 4 least-significant-bits */\n> +\t\tx++;\n> +\t}\n> +}\n> +\n> +template<bool addAlphaByte, bool ccmEnabled>\n> +void DebayerCpu::debayer12P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> +{\n> +\tconst int widthInBytes = window_.width * 3 / 2;\n> +\tconst uint8_t *prev = src[0];\n> +\tconst uint8_t *curr = src[1];\n> +\tconst uint8_t *next = src[2];\n> +\n> +\tfor (int x = 0; x < widthInBytes;) {\n> +\t\t/* Even pixel */\n> +\t\tGRBG_BGR888(2, 1, 1)\n> +\t\t/* Odd pixel GRBG -> RGGB */\n> +\t\tRGGB_BGR888(1, 2, 1)\n> +\t\t/* Skip 3rd src byte with 2 x 4 least-significant-bits */\n> +\t\tx++;\n> +\t}\n> +}\n> +\n> +template<bool addAlphaByte, bool ccmEnabled>\n> +void DebayerCpu::debayer12P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n> +{\n> +\tconst int widthInBytes = window_.width * 3 / 2;\n> +\tconst uint8_t *prev = src[0];\n> +\tconst uint8_t *curr = src[1];\n> +\tconst uint8_t *next = src[2];\n> +\n> +\tfor (int x = 0; x < widthInBytes;) {\n> +\t\t/* Even pixel */\n> +\t\tGBRG_BGR888(2, 1, 1)\n> +\t\t/* Odd pixel GBRG -> BGGR */\n> +\t\tBGGR_BGR888(1, 2, 1)\n> +\t\t/* Skip 3rd src byte with 2 x 4 least-significant-bits */\n> +\t\tx++;\n> +\t}\n> +}\n> +\n> +template<bool addAlphaByte, bool ccmEnabled>\n> +void DebayerCpu::debayer12P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n> +{\n> +\tconst int widthInBytes = window_.width * 3 / 2;\n> +\tconst uint8_t *prev = src[0];\n> +\tconst uint8_t *curr = src[1];\n> +\tconst uint8_t *next = src[2];\n> +\n> +\tfor (int x = 0; x < widthInBytes;) {\n> +\t\t/* Even pixel */\n> +\t\tRGGB_BGR888(2, 1, 1)\n> +\t\t/* Odd pixel RGGB -> GRBG */\n> +\t\tGRBG_BGR888(1, 2, 1)\n> +\t\t/* Skip 3rd src byte with 2 x 4 least-significant-bits */\n> +\t\tx++;\n> +\t}\n> +}\n> +\n>  /*\n>   * Setup the Debayer object according to the passed in parameters.\n>   * Return 0 on success, a negative errno value on failure\n> @@ -360,6 +432,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  {\n>  \tBayerFormat bayerFormat =\n>  \t\tBayerFormat::fromPixelFormat(inputFormat);\n> +\tstd::vector<PixelFormat> outputFormats = { formats::RGB888,\n> +\t\t\t\t\t\t   formats::XRGB8888,\n> +\t\t\t\t\t\t   formats::ARGB8888,\n> +\t\t\t\t\t\t   formats::BGR888,\n> +\t\t\t\t\t\t   formats::XBGR8888,\n> +\t\t\t\t\t\t   formats::ABGR8888 };\n>  \n>  \tif ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10 || bayerFormat.bitDepth == 12) &&\n>  \t    bayerFormat.packing == BayerFormat::Packing::None &&\n> @@ -367,12 +445,7 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  \t\tconfig.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>  \t\tconfig.patternSize.width = 2;\n>  \t\tconfig.patternSize.height = 2;\n> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n> -\t\t\t\t\t\t\t\t  formats::XRGB8888,\n> -\t\t\t\t\t\t\t\t  formats::ARGB8888,\n> -\t\t\t\t\t\t\t\t  formats::BGR888,\n> -\t\t\t\t\t\t\t\t  formats::XBGR8888,\n> -\t\t\t\t\t\t\t\t  formats::ABGR8888 });\n> +\t\tconfig.outputFormats = outputFormats;\n>  \t\treturn 0;\n>  \t}\n>  \n> @@ -382,12 +455,17 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  \t\tconfig.bpp = 10;\n>  \t\tconfig.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>  \t\tconfig.patternSize.height = 2;\n> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n> -\t\t\t\t\t\t\t\t  formats::XRGB8888,\n> -\t\t\t\t\t\t\t\t  formats::ARGB8888,\n> -\t\t\t\t\t\t\t\t  formats::BGR888,\n> -\t\t\t\t\t\t\t\t  formats::XBGR8888,\n> -\t\t\t\t\t\t\t\t  formats::ABGR8888 });\n> +\t\tconfig.outputFormats = outputFormats;\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tif (bayerFormat.bitDepth == 12 &&\n> +\t    bayerFormat.packing == BayerFormat::Packing::CSI2 &&\n> +\t    isStandardBayerOrder(bayerFormat.order)) {\n> +\t\tconfig.bpp = 12;\n> +\t\tconfig.patternSize.width = 2; /* 3 bytes per *2* pixels */\n> +\t\tconfig.patternSize.height = 2;\n> +\t\tconfig.outputFormats = outputFormats;\n>  \t\treturn 0;\n>  \t}\n>  \n> @@ -538,6 +616,26 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat,\n>  \t\t}\n>  \t}\n>  \n> +\tif (bayerFormat.bitDepth == 12 &&\n> +\t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n> +\t\tswitch (bayerFormat.order) {\n> +\t\tcase BayerFormat::BGGR:\n> +\t\t\tSET_DEBAYER_METHODS(debayer12P_BGBG_BGR888, debayer12P_GRGR_BGR888)\n> +\t\t\treturn 0;\n> +\t\tcase BayerFormat::GBRG:\n> +\t\t\tSET_DEBAYER_METHODS(debayer12P_GBGB_BGR888, debayer12P_RGRG_BGR888)\n> +\t\t\treturn 0;\n> +\t\tcase BayerFormat::GRBG:\n> +\t\t\tSET_DEBAYER_METHODS(debayer12P_GRGR_BGR888, debayer12P_BGBG_BGR888)\n> +\t\t\treturn 0;\n> +\t\tcase BayerFormat::RGGB:\n> +\t\t\tSET_DEBAYER_METHODS(debayer12P_RGRG_BGR888, debayer12P_GBGB_BGR888)\n> +\t\t\treturn 0;\n> +\t\tdefault:\n> +\t\t\tbreak;\n> +\t\t}\n> +\t}\n> +\n>  \treturn invalidFmt();\n>  }\n>  \n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index 68da95083..5281c65cb 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -110,6 +110,15 @@ private:\n>  \tvoid debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\t/* CSI-2 packed 12-bit raw bayer format (all the 4 orders) */\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n> +\tvoid debayer12P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n> +\tvoid debayer12P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n> +\tvoid debayer12P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n> +\tvoid debayer12P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \tstatic int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config);\n>  \tstatic int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config);\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index 7b9e02d90..9ea892f11 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -52,16 +52,18 @@ int DebayerEGL::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  \tBayerFormat bayerFormat =\n>  \t\tBayerFormat::fromPixelFormat(inputFormat);\n>  \n> +\tstd::vector<PixelFormat> outputFormats = { formats::XRGB8888,\n> +\t\t\t\t\t\t   formats::ARGB8888,\n> +\t\t\t\t\t\t   formats::XBGR8888,\n> +\t\t\t\t\t\t   formats::ABGR8888 };\n> +\n>  \tif ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10) &&\n>  \t    bayerFormat.packing == BayerFormat::Packing::None &&\n>  \t    isStandardBayerOrder(bayerFormat.order)) {\n>  \t\tconfig.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>  \t\tconfig.patternSize.width = 2;\n>  \t\tconfig.patternSize.height = 2;\n> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::XRGB8888,\n> -\t\t\t\t\t\t\t\t  formats::ARGB8888,\n> -\t\t\t\t\t\t\t\t  formats::XBGR8888,\n> -\t\t\t\t\t\t\t\t  formats::ABGR8888 });\n> +\t\tconfig.outputFormats = outputFormats;\n>  \t\treturn 0;\n>  \t}\n>  \n> @@ -71,10 +73,17 @@ int DebayerEGL::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>  \t\tconfig.bpp = 10;\n>  \t\tconfig.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>  \t\tconfig.patternSize.height = 2;\n> -\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::XRGB8888,\n> -\t\t\t\t\t\t\t\t  formats::ARGB8888,\n> -\t\t\t\t\t\t\t\t  formats::XBGR8888,\n> -\t\t\t\t\t\t\t\t  formats::ABGR8888 });\n> +\t\tconfig.outputFormats = outputFormats;\n> +\t\treturn 0;\n> +\t}\n> +\n> +\tif (bayerFormat.bitDepth == 12 &&\n> +\t    bayerFormat.packing == BayerFormat::Packing::CSI2 &&\n> +\t    isStandardBayerOrder(bayerFormat.order)) {\n> +\t\tconfig.bpp = 12;\n> +\t\tconfig.patternSize.width = 2; /* 3 bytes per *2* pixels */\n> +\t\tconfig.patternSize.height = 2;\n> +\t\tconfig.outputFormats = outputFormats;\n>  \t\treturn 0;\n>  \t}\n>  \n> diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\n> index 0815ec9a3..2f57a5f33 100644\n> --- a/src/libcamera/software_isp/swstats_cpu.cpp\n> +++ b/src/libcamera/software_isp/swstats_cpu.cpp\n> @@ -323,6 +323,58 @@ void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src[], SwIspStats &stats)\n>  \tSWSTATS_FINISH_LINE_STATS()\n>  }\n>  \n> +void SwStatsCpu::statsBGGR12PLine0(const uint8_t *src[], SwIspStats &stats)\n> +{\n> +\tconst uint8_t *src0 = src[1] + window_.x * 3 / 2;\n> +\tconst uint8_t *src1 = src[2] + window_.x * 3 / 2;\n> +\tconst unsigned int widthInBytes = window_.width * 3 / 2;\n> +\n> +\tSWSTATS_START_LINE_STATS(uint8_t)\n> +\n> +\tif (swapLines_)\n> +\t\tstd::swap(src0, src1);\n> +\n> +\t/* x += 6 sample every other 2x2 block */\n> +\tfor (unsigned int x = 0; x < widthInBytes; x += 6) {\n> +\t\tb = src0[x];\n> +\t\tg = src0[x + 1];\n> +\t\tg2 = src1[x];\n> +\t\tr = src1[x + 1];\n> +\n> +\t\tg = (g + g2) / 2;\n> +\n> +\t\tSWSTATS_ACCUMULATE_LINE_STATS(1)\n> +\t}\n> +\n> +\tSWSTATS_FINISH_LINE_STATS()\n> +}\n> +\n> +void SwStatsCpu::statsGBRG12PLine0(const uint8_t *src[], SwIspStats &stats)\n> +{\n> +\tconst uint8_t *src0 = src[1] + window_.x * 3 / 2;\n> +\tconst uint8_t *src1 = src[2] + window_.x * 3 / 2;\n> +\tconst unsigned int widthInBytes = window_.width * 3 / 2;\n> +\n> +\tSWSTATS_START_LINE_STATS(uint8_t)\n> +\n> +\tif (swapLines_)\n> +\t\tstd::swap(src0, src1);\n> +\n> +\t/* x += 6 sample every other 2x2 block */\n> +\tfor (unsigned int x = 0; x < widthInBytes; x += 6) {\n> +\t\tg = src0[x];\n> +\t\tb = src0[x + 1];\n> +\t\tr = src1[x];\n> +\t\tg2 = src1[x + 1];\n> +\n> +\t\tg = (g + g2) / 2;\n> +\n> +\t\tSWSTATS_ACCUMULATE_LINE_STATS(1)\n> +\t}\n> +\n> +\tSWSTATS_FINISH_LINE_STATS()\n> +}\n> +\n>  /**\n>   * \\brief Reset state to start statistics gathering for a new frame\n>   * \\param[in] frame The frame number\n> @@ -440,10 +492,17 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\n>  \t\t}\n>  \t}\n>  \n> -\tif (bayerFormat.bitDepth == 10 &&\n> +\tuint8_t bitDepth = bayerFormat.bitDepth;\n> +\n> +\tif ((bitDepth == 10 || bitDepth == 12) &&\n>  \t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n> +\t\tif (bitDepth == 10)\n> +\t\t\tpatternSize_.width = 4; /* 5 bytes per *4* pixels */\n> +\t\telse\n> +\t\t\tpatternSize_.width = 2; /* 3 bytes for *2* pixels */\n> +\n>  \t\tpatternSize_.height = 2;\n> -\t\tpatternSize_.width = 4; /* 5 bytes per *4* pixels */\n> +\n>  \t\t/* Skip every 3th and 4th line, sample every other 2x2 block */\n>  \t\tySkipMask_ = 0x02;\n>  \t\txShift_ = 0;\n> @@ -453,12 +512,12 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg, unsigned int stat\n>  \t\tswitch (bayerFormat.order) {\n>  \t\tcase BayerFormat::BGGR:\n>  \t\tcase BayerFormat::GRBG:\n> -\t\t\tstats0_ = &SwStatsCpu::statsBGGR10PLine0;\n> +\t\t\tstats0_ = (bitDepth == 10) ? &SwStatsCpu::statsBGGR10PLine0 : &SwStatsCpu::statsBGGR12PLine0;\n>  \t\t\tswapLines_ = bayerFormat.order == BayerFormat::GRBG;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::GBRG:\n>  \t\tcase BayerFormat::RGGB:\n> -\t\t\tstats0_ = &SwStatsCpu::statsGBRG10PLine0;\n> +\t\t\tstats0_ = (bitDepth == 10) ? &SwStatsCpu::statsGBRG10PLine0 : &SwStatsCpu::statsGBRG12PLine0;\n>  \t\t\tswapLines_ = bayerFormat.order == BayerFormat::RGGB;\n>  \t\t\treturn 0;\n>  \t\tdefault:\n>\n> ---\n> base-commit: ad5506544b798539e1d094ec2eac0b2a1ecbdc4d\n> change-id: 20260522-swisp_12p-6ad22e4d08b0\n>\n> Best regards,","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0D821C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  3 Jun 2026 13:49:45 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4885B631CC;\n\tWed,  3 Jun 2026 15:49:44 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D35D762FE1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  3 Jun 2026 15:49:42 +0200 (CEST)","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n\t[209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-644-P4wNH0mGPrSPmREHC5N-kg-1; Wed, 03 Jun 2026 09:49:40 -0400","by mail-wr1-f69.google.com with SMTP id\n\tffacd0b85a97d-45ef9f0af71so842089f8f.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 03 Jun 2026 06:49:40 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb ([213.175.37.14])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-4601f344558sm8044188f8f.18.2026.06.03.06.49.37\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 03 Jun 2026 06:49:37 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"eZYOH40Z\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1780494581;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=yxsKvx9SdOMbYyymUOeVFmOKVz3o0yQfhkiL/uNwcUM=;\n\tb=eZYOH40Z+/T1dXjmrkrpm2t3gl43eqg4oFxQ6RFRFlq0I+N7t2L1sMdxM2tqbH8bRqRLxr\n\tOD0dgMF32i9uOhQuFsfjg2EjUgtrA0HhbesaJbEZ2bstiDT8J/lT6557nSSQ+Iso8j4VL4\n\ty4xHco9QeA0zoVWXGSDI9u07Amw2Szk=","X-MC-Unique":"P4wNH0mGPrSPmREHC5N-kg-1","X-Mimecast-MFC-AGG-ID":"P4wNH0mGPrSPmREHC5N-kg_1780494579","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1780494579; x=1781099379;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=yxsKvx9SdOMbYyymUOeVFmOKVz3o0yQfhkiL/uNwcUM=;\n\tb=TUtU0ba+chODAUdxwXQiip8u4bNNNAne+QRt4Poey/4ycPxBKH29dysiJYYICCDr4K\n\t/fSsxUYdt/zrr/fcTmXRuYwl+M+aXhkBc3vE+3WG9FkXjoH4rpPdTEb87VxWbA89sAnm\n\t/ZAePTIy2qUeWBoE5F/1hWrIyYhibIMoOZ07siDNkFLtdDehijejmhsUaLXGYmVIydz1\n\ttboIILYMQKT3mjqwqmIzPVjyzigpbc7b88vzVk0bDm0zYQdPC1sGsp7kb1pIkntcGvoG\n\tiC4Uq7/nIXEtu0f9RwHkKMHWWdBZ2Cyyln/YuevcARm98GYDsQ+pxSjEFB7pEsG8smLs\n\tpbMQ==","X-Forwarded-Encrypted":"i=1;\n\tAFNElJ8jwM6MUUJb+sstHJXV8HG2+qRKeC+qQa75YA6fFYcxaMrWlS0sIGPaFygNsF6EJV/fM0C8tU7ZKTUYccrd8zA=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YzkCJ23Up0WAT/O+RhUBBCBz5uBxDtcnnpvPPCKsHxlHhRvR6Or\n\t1jLumDjtfkQMvNjtzSA7/CoQKCGxX8YYjuSUxZ9R0jQBtCjoLxtMvijUtju6OsQmhat03M5xdQ5\n\thEDvgkMyxnaUF1iICfqaWyqwZXTaCN7f8O7OWPZvz3OD+qkJ3Gdbt6qinS1h8fo7yE96wdhYNsw\n\tItuplDErTqgA3j0GjKSTjCrFg4pifUwtfVZwH+7kwlLJcMSnuQbHoVJXEX/CI=","X-Gm-Gg":"Acq92OF1BmS/pj8XPPvI+m3IggHsNlmSMyWoMLqyKY4qE5z1D+2hPE6swKdzNLgek+6\n\tz6DpqBItnE6XZLk7ftK0sdztjAFkjphb3HRvOr/9EseosBwy61K5+ZH6RBnWXb8vszU0OGWAEY4\n\tkluiCiLSeZz7gamgQLh6emH3UZRjw2DTqYBFtxxOGrZWshbUbHGnSwJUSXPkHdixLNwv3hyJkON\n\tnG00OVqUcenkQmvlH9SKhRDUITF03o91DY+kpySJd6PsAKsYDifwT09zL+svoqDrT+y6kMdTGFr\n\tD1azE/kzqsanOl3YCi+w1KtIFdPlc6F40L3XoFKyfo7gdsbfSd5AltP5op97Hwbx2r6NfPVObuB\n\txVTcAq0Kjqt5jqcKtrvP69e12YC7GUNoRTBJxf5UxJQXN5AwO","X-Received":["by 2002:adf:e00c:0:10b0:45e:f43f:128a with SMTP id\n\tffacd0b85a97d-460212cd2bbmr3855536f8f.7.1780494578986; \n\tWed, 03 Jun 2026 06:49:38 -0700 (PDT)","by 2002:adf:e00c:0:10b0:45e:f43f:128a with SMTP id\n\tffacd0b85a97d-460212cd2bbmr3855484f8f.7.1780494578379; \n\tWed, 03 Jun 2026 06:49:38 -0700 (PDT)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Jai Luthra <jai.luthra@ideasonboard.com>","Cc":"Hans de Goede <johannes.goede@oss.qualcomm.com>,  Bryan O'Donoghue\n\t<bryan.odonoghue@linaro.org>,  libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2] libcamera: software_isp: Support 12-bit CSI2 packed\n\traw bayer formats","In-Reply-To":"<20260602-swisp_12p-v2-1-2e6d25db7081@ideasonboard.com> (Jai\n\tLuthra's message of \"Tue, 02 Jun 2026 17:25:30 +0530\")","References":"<20260602-swisp_12p-v2-1-2e6d25db7081@ideasonboard.com>","Date":"Wed, 03 Jun 2026 15:49:36 +0200","Message-ID":"<85y0gvvimn.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"ORa4C7wZq5yQnakG9mAyCy9BjUVatr5JPxezETmTmrs_1780494579","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]