[{"id":30025,"web_url":"https://patchwork.libcamera.org/comment/30025/","msgid":"<87iky6jewc.fsf@redhat.com>","date":"2024-06-18T18:15:47","subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Robert Mader <robert.mader@collabora.com> writes:\n\n> In order to be more compatible with modern hardware and APIs. This\n> notably allows GL implementations to directly import the buffers more\n> often and seems to be required for Wayland.\n>\n> Further more, as we already enforce a 8 byte stride, these formats work\n> better for clients that don't support padding - such as libwebrtc at the\n> time of writing.\n>\n> Tested devices:\n>  - Librem5\n>  - PinePhone\n>  - Thinkpad X13s\n>\n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>\n> ---\n>\n> Changes in v3:\n>  - Remove previously introduced variable again and use C++ templates\n>    instead in order to avoid runtime costs\n>  - Small cleanups and linting fixes\n>\n> Changes in v2:\n>  - Reduce code duplication by using a runtime variable instead\n>  - Small cleanups\n\nHi Robert,\n\nthis looks much better, thank you.\n\nReviewed-by: Milan Zamazal <mzamazal@redhat.com>\n\n> ---\n>  src/libcamera/software_isp/debayer_cpu.cpp | 75 +++++++++++++++++-----\n>  src/libcamera/software_isp/debayer_cpu.h   | 10 +++\n>  2 files changed, 69 insertions(+), 16 deletions(-)\n>\n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index c038eed4..f8d2677d 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -74,6 +74,8 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[curr[x] / (div)];                                                      \\\n>  \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>  \t*dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> +\tif constexpr (addAlphaByte)                                                           \\\n> +\t\t*dst++ = 255;                                                                 \\\n>  \tx++;\n>  \n>  /*\n> @@ -85,6 +87,8 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>  \t*dst++ = green_[curr[x] / (div)];                         \\\n>  \t*dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> +\tif constexpr (addAlphaByte)                               \\\n> +\t\t*dst++ = 255;                                     \\\n>  \tx++;\n>  \n>  /*\n> @@ -96,6 +100,8 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>  \t*dst++ = green_[curr[x] / (div)];                          \\\n>  \t*dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n> +\tif constexpr (addAlphaByte)                                \\\n> +\t\t*dst++ = 255;                                      \\\n>  \tx++;\n>  \n>  /*\n> @@ -107,8 +113,11 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>  \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>  \t*dst++ = red_[curr[x] / (div)];                                                        \\\n> +\tif constexpr (addAlphaByte)                                                            \\\n> +\t\t*dst++ = 255;                                                                  \\\n>  \tx++;\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n> @@ -119,6 +128,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n> @@ -129,6 +139,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -140,6 +151,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -151,6 +163,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -162,6 +175,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -173,6 +187,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -198,6 +213,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -218,6 +234,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -238,6 +255,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -280,7 +298,12 @@ 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, formats::BGR888 });\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\treturn 0;\n>  \t}\n>  \n> @@ -290,7 +313,12 @@ 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, formats::BGR888 });\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\treturn 0;\n>  \t}\n>  \n> @@ -306,6 +334,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>  \t\treturn 0;\n>  \t}\n>  \n> +\tif (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n> +\t    outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n> +\t\tconfig.bpp = 32;\n> +\t\treturn 0;\n> +\t}\n> +\n>  \tLOG(Debayer, Info)\n>  \t\t<< \"Unsupported output format \" << outputFormat.toString();\n>  \treturn -EINVAL;\n> @@ -341,6 +375,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  {\n>  \tBayerFormat bayerFormat =\n>  \t\tBayerFormat::fromPixelFormat(inputFormat);\n> +\tbool addAlphaByte = false;\n>  \n>  \txShift_ = 0;\n>  \tswapRedBlueGains_ = false;\n> @@ -351,8 +386,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t};\n>  \n>  \tswitch (outputFormat) {\n> +\tcase formats::XRGB8888:\n> +\tcase formats::ARGB8888:\n> +\t\taddAlphaByte = true;\n> +\t\t[[fallthrough]];\n>  \tcase formats::RGB888:\n>  \t\tbreak;\n> +\tcase formats::XBGR8888:\n> +\tcase formats::ABGR8888:\n> +\t\taddAlphaByte = true;\n> +\t\t[[fallthrough]];\n>  \tcase formats::BGR888:\n>  \t\t/* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>  \t\tswapRedBlueGains_ = true;\n> @@ -383,16 +426,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t    isStandardBayerOrder(bayerFormat.order)) {\n>  \t\tswitch (bayerFormat.bitDepth) {\n>  \t\tcase 8:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer8_BGBG_BGR888<true> : &DebayerCpu::debayer8_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer8_GRGR_BGR888<true> : &DebayerCpu::debayer8_GRGR_BGR888<false>;\n>  \t\t\tbreak;\n>  \t\tcase 10:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10_BGBG_BGR888<true> : &DebayerCpu::debayer10_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10_GRGR_BGR888<true> : &DebayerCpu::debayer10_GRGR_BGR888<false>;\n>  \t\t\tbreak;\n>  \t\tcase 12:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer12_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer12_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer12_BGBG_BGR888<true> : &DebayerCpu::debayer12_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer12_GRGR_BGR888<true> : &DebayerCpu::debayer12_GRGR_BGR888<false>;\n>  \t\t\tbreak;\n>  \t\t}\n>  \t\tsetupStandardBayerOrder(bayerFormat.order);\n> @@ -403,20 +446,20 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n>  \t\tswitch (bayerFormat.order) {\n>  \t\tcase BayerFormat::BGGR:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::GBRG:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::GRBG:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::RGGB:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tdefault:\n>  \t\t\tbreak;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index be7dcdca..1dac6435 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -85,18 +85,28 @@ private:\n>  \tusing debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \t/* 8-bit raw bayer format */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* unpacked 10-bit raw bayer format */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* unpacked 12-bit raw bayer format */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \tstruct DebayerInputConfig {","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 24898BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Jun 2024 18:15:56 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2D327654A4;\n\tTue, 18 Jun 2024 20:15:55 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 65DA661A1F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Jun 2024 20:15:53 +0200 (CEST)","from mail-lj1-f198.google.com (mail-lj1-f198.google.com\n\t[209.85.208.198]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-549-wwKUEFPuNQG9u8qO5-LcRQ-1; Tue, 18 Jun 2024 14:15:50 -0400","by mail-lj1-f198.google.com with SMTP id\n\t38308e7fff4ca-2ec0397ff31so45377361fa.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Jun 2024 11:15:50 -0700 (PDT)","from nuthatch (ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-422f6320bfdsm196840125e9.37.2024.06.18.11.15.47\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 18 Jun 2024 11:15:47 -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=\"K0Vx7KHZ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1718734552;\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=Q43ArtLNCa1m27UCJV0bxyh4sy0f86fZPMX7oYkEFk8=;\n\tb=K0Vx7KHZ9SHP8wl7rmQrsKxk2SUmbk0TkayRVlh1ZbnHPuGU7srHy4TUc/t2A8KYPPkLmm\n\tHVWMONVAoisv8gNxkzj161mlnHtszu0go08k6UKcYFwZTQVl6bfz6JW4aQtuQ+2OoR6/7u\n\tF2754LqQH/qjQBAaC4Aucnbs/1tQVY8=","X-MC-Unique":"wwKUEFPuNQG9u8qO5-LcRQ-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1718734549; x=1719339349;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=Q43ArtLNCa1m27UCJV0bxyh4sy0f86fZPMX7oYkEFk8=;\n\tb=A9vASMCY8PUVpK3dhGBgvoonyXEBN2Q/j4Y97syf+3LFujeFa3YLp8oocNz/4uB4iS\n\tVfKb5NiQG2Pnt5isLMHaNS6KLeJXt7xFNlz/88deAsHVuXtGbEoH3lSJI0lmnnIh+tGO\n\txh46jSzi4d4U4z3OmJCiSolkDCwQkISy0YhOAxEeZhz73mWZKJeYWM8Y+qnCTgKuNUz9\n\ta4hNby6n/DRrUv2ph3CvJCVfHajeW4zkr1j+n91DLLtKcpBwI2NeZK6BeQ/D7jE+K/Jz\n\tbSXWo6ddLE0Wou4I/ozAXYzx/8I2l9rgZl/wmqdn+h/J1d8DCc0FgT4oqvvMJjdexYTb\n\teZIQ==","X-Gm-Message-State":"AOJu0YwW7toGQyNo8k97q5ohAs4/a1dtDrbiVaS0ajDD/pQIV91Jn2Tc\n\toET0QtWlFHGRkHYlbFkE6KtL6Q6gseiQ6dE67OgsSrhODm58pPokLkCx9f+p0mVM9RrXAE59eXW\n\tU+ElwJxIt0ZzDg5KXvCXKMMVE08ycffGvsH7yX+yfCpOD1eDFqz8SYlelZhfVadLkh5lMsUs=","X-Received":["by 2002:a2e:8904:0:b0:2ec:1dfc:45cd with SMTP id\n\t38308e7fff4ca-2ec3cea476cmr4054111fa.4.1718734549070; \n\tTue, 18 Jun 2024 11:15:49 -0700 (PDT)","by 2002:a2e:8904:0:b0:2ec:1dfc:45cd with SMTP id\n\t38308e7fff4ca-2ec3cea476cmr4053911fa.4.1718734548607; \n\tTue, 18 Jun 2024 11:15:48 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IFo4G6nUdhv6qWqilVZ7CmSiFjt8LooWunQgu0nkxqIW4fuXpnsuWjyGenr81bO9tgcO//Yig==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Robert Mader <robert.mader@collabora.com>","Cc":"libcamera-devel@lists.libcamera.org,  Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","In-Reply-To":"<20240618063227.197989-1-robert.mader@collabora.com> (Robert\n\tMader's message of \"Tue, 18 Jun 2024 08:31:59 +0200\")","References":"<20240618063227.197989-1-robert.mader@collabora.com>","Date":"Tue, 18 Jun 2024 20:15:47 +0200","Message-ID":"<87iky6jewc.fsf@redhat.com>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","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>"}},{"id":30026,"web_url":"https://patchwork.libcamera.org/comment/30026/","msgid":"<171879106746.804094.663439147425782768@ping.linuxembedded.co.uk>","date":"2024-06-19T09:57:47","subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Robert Mader (2024-06-18 07:31:59)\n> In order to be more compatible with modern hardware and APIs. This\n> notably allows GL implementations to directly import the buffers more\n> often and seems to be required for Wayland.\n> \n> Further more, as we already enforce a 8 byte stride, these formats work\n> better for clients that don't support padding - such as libwebrtc at the\n> time of writing.\n> \n> Tested devices:\n>  - Librem5\n>  - PinePhone\n>  - Thinkpad X13s\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\nRe-tested again on the x13s, and firefox-nightly.\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n\n> \n> ---\n> \n> Changes in v3:\n>  - Remove previously introduced variable again and use C++ templates\n>    instead in order to avoid runtime costs\n>  - Small cleanups and linting fixes\n> \n> Changes in v2:\n>  - Reduce code duplication by using a runtime variable instead\n>  - Small cleanups\n> ---\n>  src/libcamera/software_isp/debayer_cpu.cpp | 75 +++++++++++++++++-----\n>  src/libcamera/software_isp/debayer_cpu.h   | 10 +++\n>  2 files changed, 69 insertions(+), 16 deletions(-)\n> \n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index c038eed4..f8d2677d 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -74,6 +74,8 @@ DebayerCpu::~DebayerCpu()\n>         *dst++ = blue_[curr[x] / (div)];                                                      \\\n>         *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>         *dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> +       if constexpr (addAlphaByte)                                                           \\\n> +               *dst++ = 255;                                                                 \\\n>         x++;\n>  \n>  /*\n> @@ -85,6 +87,8 @@ DebayerCpu::~DebayerCpu()\n>         *dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>         *dst++ = green_[curr[x] / (div)];                         \\\n>         *dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> +       if constexpr (addAlphaByte)                               \\\n> +               *dst++ = 255;                                     \\\n>         x++;\n>  \n>  /*\n> @@ -96,6 +100,8 @@ DebayerCpu::~DebayerCpu()\n>         *dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>         *dst++ = green_[curr[x] / (div)];                          \\\n>         *dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n> +       if constexpr (addAlphaByte)                                \\\n> +               *dst++ = 255;                                      \\\n>         x++;\n>  \n>  /*\n> @@ -107,8 +113,11 @@ DebayerCpu::~DebayerCpu()\n>         *dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>         *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>         *dst++ = red_[curr[x] / (div)];                                                        \\\n> +       if constexpr (addAlphaByte)                                                            \\\n> +               *dst++ = 255;                                                                  \\\n>         x++;\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         DECLARE_SRC_POINTERS(uint8_t)\n> @@ -119,6 +128,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         DECLARE_SRC_POINTERS(uint8_t)\n> @@ -129,6 +139,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         DECLARE_SRC_POINTERS(uint16_t)\n> @@ -140,6 +151,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         DECLARE_SRC_POINTERS(uint16_t)\n> @@ -151,6 +163,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         DECLARE_SRC_POINTERS(uint16_t)\n> @@ -162,6 +175,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         DECLARE_SRC_POINTERS(uint16_t)\n> @@ -173,6 +187,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         const int widthInBytes = window_.width * 5 / 4;\n> @@ -198,6 +213,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         const int widthInBytes = window_.width * 5 / 4;\n> @@ -218,6 +234,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         const int widthInBytes = window_.width * 5 / 4;\n> @@ -238,6 +255,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>         }\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>         const int widthInBytes = window_.width * 5 / 4;\n> @@ -280,7 +298,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>                 config.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>                 config.patternSize.width = 2;\n>                 config.patternSize.height = 2;\n> -               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> +               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n> +                                                                 formats::XRGB8888,\n> +                                                                 formats::ARGB8888,\n> +                                                                 formats::BGR888,\n> +                                                                 formats::XBGR8888,\n> +                                                                 formats::ABGR8888 });\n>                 return 0;\n>         }\n>  \n> @@ -290,7 +313,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>                 config.bpp = 10;\n>                 config.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>                 config.patternSize.height = 2;\n> -               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> +               config.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n> +                                                                 formats::XRGB8888,\n> +                                                                 formats::ARGB8888,\n> +                                                                 formats::BGR888,\n> +                                                                 formats::XBGR8888,\n> +                                                                 formats::ABGR8888 });\n>                 return 0;\n>         }\n>  \n> @@ -306,6 +334,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>                 return 0;\n>         }\n>  \n> +       if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n> +           outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n> +               config.bpp = 32;\n> +               return 0;\n> +       }\n> +\n>         LOG(Debayer, Info)\n>                 << \"Unsupported output format \" << outputFormat.toString();\n>         return -EINVAL;\n> @@ -341,6 +375,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  {\n>         BayerFormat bayerFormat =\n>                 BayerFormat::fromPixelFormat(inputFormat);\n> +       bool addAlphaByte = false;\n>  \n>         xShift_ = 0;\n>         swapRedBlueGains_ = false;\n> @@ -351,8 +386,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>         };\n>  \n>         switch (outputFormat) {\n> +       case formats::XRGB8888:\n> +       case formats::ARGB8888:\n> +               addAlphaByte = true;\n> +               [[fallthrough]];\n>         case formats::RGB888:\n>                 break;\n> +       case formats::XBGR8888:\n> +       case formats::ABGR8888:\n> +               addAlphaByte = true;\n> +               [[fallthrough]];\n>         case formats::BGR888:\n>                 /* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>                 swapRedBlueGains_ = true;\n> @@ -383,16 +426,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>             isStandardBayerOrder(bayerFormat.order)) {\n>                 switch (bayerFormat.bitDepth) {\n>                 case 8:\n> -                       debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer8_BGBG_BGR888<true> : &DebayerCpu::debayer8_BGBG_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer8_GRGR_BGR888<true> : &DebayerCpu::debayer8_GRGR_BGR888<false>;\n>                         break;\n>                 case 10:\n> -                       debayer0_ = &DebayerCpu::debayer10_BGBG_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer10_GRGR_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer10_BGBG_BGR888<true> : &DebayerCpu::debayer10_BGBG_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer10_GRGR_BGR888<true> : &DebayerCpu::debayer10_GRGR_BGR888<false>;\n>                         break;\n>                 case 12:\n> -                       debayer0_ = &DebayerCpu::debayer12_BGBG_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer12_GRGR_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer12_BGBG_BGR888<true> : &DebayerCpu::debayer12_BGBG_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer12_GRGR_BGR888<true> : &DebayerCpu::debayer12_GRGR_BGR888<false>;\n>                         break;\n>                 }\n>                 setupStandardBayerOrder(bayerFormat.order);\n> @@ -403,20 +446,20 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>             bayerFormat.packing == BayerFormat::Packing::CSI2) {\n>                 switch (bayerFormat.order) {\n>                 case BayerFormat::BGGR:\n> -                       debayer0_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n>                         return 0;\n>                 case BayerFormat::GBRG:\n> -                       debayer0_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n>                         return 0;\n>                 case BayerFormat::GRBG:\n> -                       debayer0_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n>                         return 0;\n>                 case BayerFormat::RGGB:\n> -                       debayer0_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> -                       debayer1_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> +                       debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n> +                       debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n>                         return 0;\n>                 default:\n>                         break;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index be7dcdca..1dac6435 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -85,18 +85,28 @@ private:\n>         using debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n>  \n>         /* 8-bit raw bayer format */\n> +       template<bool addAlphaByte>\n>         void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +       template<bool addAlphaByte>\n>         void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>         /* unpacked 10-bit raw bayer format */\n> +       template<bool addAlphaByte>\n>         void debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +       template<bool addAlphaByte>\n>         void debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>         /* unpacked 12-bit raw bayer format */\n> +       template<bool addAlphaByte>\n>         void debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +       template<bool addAlphaByte>\n>         void debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>         /* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n> +       template<bool addAlphaByte>\n>         void debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +       template<bool addAlphaByte>\n>         void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +       template<bool addAlphaByte>\n>         void debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +       template<bool addAlphaByte>\n>         void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \n>         struct DebayerInputConfig {\n> -- \n> 2.45.2\n>","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 A6841BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 19 Jun 2024 09:57:53 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A3D0B654A4;\n\tWed, 19 Jun 2024 11:57:52 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 940D561A0F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 19 Jun 2024 11:57:50 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0CCE9F89;\n\tWed, 19 Jun 2024 11:57:32 +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=\"FtZlhUPO\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1718791052;\n\tbh=MstAyhsyk9Lf01xNC9HFKfFBdNfRPJ94mSqcZmCYLAg=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=FtZlhUPOEO53tVZCJLvg4GDapacibTArgOszEeSyTE5HVvNX/FK4W5GdMIHKM0jH5\n\tQYTbd1oiZGA/yO8Apqjl0hXdA/MJ9uxVa2xznAoyDk4Pu4czN1NZiAa6Kz2ZSU8uH3\n\t+xlVz3kEjqdIoLxsNvOn3OoyEuyGvnLUC1ub02H8=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20240618063227.197989-1-robert.mader@collabora.com>","References":"<20240618063227.197989-1-robert.mader@collabora.com>","Subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Robert Mader <robert.mader@collabora.com>","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Wed, 19 Jun 2024 10:57:47 +0100","Message-ID":"<171879106746.804094.663439147425782768@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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":30045,"web_url":"https://patchwork.libcamera.org/comment/30045/","msgid":"<3048b066-a927-4602-a783-e3f660ff018c@redhat.com>","date":"2024-06-24T09:37:52","subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":102,"url":"https://patchwork.libcamera.org/api/people/102/","name":"Hans de Goede","email":"hdegoede@redhat.com"},"content":"Hi,\n\nOn 6/18/24 8:31 AM, Robert Mader wrote:\n> In order to be more compatible with modern hardware and APIs. This\n> notably allows GL implementations to directly import the buffers more\n> often and seems to be required for Wayland.\n> \n> Further more, as we already enforce a 8 byte stride, these formats work\n> better for clients that don't support padding - such as libwebrtc at the\n> time of writing.\n> \n> Tested devices:\n>  - Librem5\n>  - PinePhone\n>  - Thinkpad X13s\n> \n> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\nThanks, patch looks good to me:\n\nReviewed-by: Hans de Goede <hdegoede@redhat.com>\n\nRegards,\n\nHans\n\n\n\n\n> \n> ---\n> \n> Changes in v3:\n>  - Remove previously introduced variable again and use C++ templates\n>    instead in order to avoid runtime costs\n>  - Small cleanups and linting fixes\n> \n> Changes in v2:\n>  - Reduce code duplication by using a runtime variable instead\n>  - Small cleanups\n> ---\n>  src/libcamera/software_isp/debayer_cpu.cpp | 75 +++++++++++++++++-----\n>  src/libcamera/software_isp/debayer_cpu.h   | 10 +++\n>  2 files changed, 69 insertions(+), 16 deletions(-)\n> \n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index c038eed4..f8d2677d 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -74,6 +74,8 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[curr[x] / (div)];                                                      \\\n>  \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>  \t*dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> +\tif constexpr (addAlphaByte)                                                           \\\n> +\t\t*dst++ = 255;                                                                 \\\n>  \tx++;\n>  \n>  /*\n> @@ -85,6 +87,8 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>  \t*dst++ = green_[curr[x] / (div)];                         \\\n>  \t*dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> +\tif constexpr (addAlphaByte)                               \\\n> +\t\t*dst++ = 255;                                     \\\n>  \tx++;\n>  \n>  /*\n> @@ -96,6 +100,8 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>  \t*dst++ = green_[curr[x] / (div)];                          \\\n>  \t*dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n> +\tif constexpr (addAlphaByte)                                \\\n> +\t\t*dst++ = 255;                                      \\\n>  \tx++;\n>  \n>  /*\n> @@ -107,8 +113,11 @@ DebayerCpu::~DebayerCpu()\n>  \t*dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>  \t*dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>  \t*dst++ = red_[curr[x] / (div)];                                                        \\\n> +\tif constexpr (addAlphaByte)                                                            \\\n> +\t\t*dst++ = 255;                                                                  \\\n>  \tx++;\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n> @@ -119,6 +128,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n> @@ -129,6 +139,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -140,6 +151,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -151,6 +163,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -162,6 +175,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -173,6 +187,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -198,6 +213,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -218,6 +234,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -238,6 +255,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> +template<bool addAlphaByte>\n>  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -280,7 +298,12 @@ 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, formats::BGR888 });\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\treturn 0;\n>  \t}\n>  \n> @@ -290,7 +313,12 @@ 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, formats::BGR888 });\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\treturn 0;\n>  \t}\n>  \n> @@ -306,6 +334,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>  \t\treturn 0;\n>  \t}\n>  \n> +\tif (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n> +\t    outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n> +\t\tconfig.bpp = 32;\n> +\t\treturn 0;\n> +\t}\n> +\n>  \tLOG(Debayer, Info)\n>  \t\t<< \"Unsupported output format \" << outputFormat.toString();\n>  \treturn -EINVAL;\n> @@ -341,6 +375,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  {\n>  \tBayerFormat bayerFormat =\n>  \t\tBayerFormat::fromPixelFormat(inputFormat);\n> +\tbool addAlphaByte = false;\n>  \n>  \txShift_ = 0;\n>  \tswapRedBlueGains_ = false;\n> @@ -351,8 +386,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t};\n>  \n>  \tswitch (outputFormat) {\n> +\tcase formats::XRGB8888:\n> +\tcase formats::ARGB8888:\n> +\t\taddAlphaByte = true;\n> +\t\t[[fallthrough]];\n>  \tcase formats::RGB888:\n>  \t\tbreak;\n> +\tcase formats::XBGR8888:\n> +\tcase formats::ABGR8888:\n> +\t\taddAlphaByte = true;\n> +\t\t[[fallthrough]];\n>  \tcase formats::BGR888:\n>  \t\t/* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>  \t\tswapRedBlueGains_ = true;\n> @@ -383,16 +426,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t    isStandardBayerOrder(bayerFormat.order)) {\n>  \t\tswitch (bayerFormat.bitDepth) {\n>  \t\tcase 8:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer8_BGBG_BGR888<true> : &DebayerCpu::debayer8_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer8_GRGR_BGR888<true> : &DebayerCpu::debayer8_GRGR_BGR888<false>;\n>  \t\t\tbreak;\n>  \t\tcase 10:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10_BGBG_BGR888<true> : &DebayerCpu::debayer10_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10_GRGR_BGR888<true> : &DebayerCpu::debayer10_GRGR_BGR888<false>;\n>  \t\t\tbreak;\n>  \t\tcase 12:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer12_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer12_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer12_BGBG_BGR888<true> : &DebayerCpu::debayer12_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer12_GRGR_BGR888<true> : &DebayerCpu::debayer12_GRGR_BGR888<false>;\n>  \t\t\tbreak;\n>  \t\t}\n>  \t\tsetupStandardBayerOrder(bayerFormat.order);\n> @@ -403,20 +446,20 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  \t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n>  \t\tswitch (bayerFormat.order) {\n>  \t\tcase BayerFormat::BGGR:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::GBRG:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::GRBG:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tcase BayerFormat::RGGB:\n> -\t\t\tdebayer0_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> -\t\t\tdebayer1_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> +\t\t\tdebayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n> +\t\t\tdebayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n>  \t\t\treturn 0;\n>  \t\tdefault:\n>  \t\t\tbreak;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index be7dcdca..1dac6435 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -85,18 +85,28 @@ private:\n>  \tusing debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \t/* 8-bit raw bayer format */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* unpacked 10-bit raw bayer format */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* unpacked 12-bit raw bayer format */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n> +\ttemplate<bool addAlphaByte>\n>  \tvoid debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \tstruct DebayerInputConfig {","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 19B84BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Jun 2024 09:38:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C6ED0654A9;\n\tMon, 24 Jun 2024 11:37:59 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0E97F619EA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Jun 2024 11:37:57 +0200 (CEST)","from mail-ed1-f72.google.com (mail-ed1-f72.google.com\n\t[209.85.208.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-161-jCBSEf8gMUG8lb6cSo6piQ-1; Mon, 24 Jun 2024 05:37:55 -0400","by mail-ed1-f72.google.com with SMTP id\n\t4fb4d7f45d1cf-57d24c8f338so1831371a12.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Jun 2024 02:37:55 -0700 (PDT)","from [10.40.98.157] ([78.108.130.194])\n\tby smtp.gmail.com with ESMTPSA id\n\t4fb4d7f45d1cf-57d303d80f7sm4514583a12.8.2024.06.24.02.37.52\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tMon, 24 Jun 2024 02:37:52 -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=\"JgspyNTh\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1719221876;\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\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=4QafEBwodfJ3jTBOf6LG6pKeH4Gi39+7IdEPgFCdl0w=;\n\tb=JgspyNThBk3ynCwaTMZeLA9acSsAYu+o9bX5mGSArbArQ6zRQm6G9mxOsXPf3HaQUcH00z\n\tERuTUOqCRqQxuVc20MxjfL6c9UNTUNIYWIRbO2/CWE00Qk4RBIt/HW+N4UqdS43VyfNM6D\n\tgPAMGFkZtoPfMUHmdVJOkMs+pvw7s/8=","X-MC-Unique":"jCBSEf8gMUG8lb6cSo6piQ-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1719221874; x=1719826674;\n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:cc:to:subject:user-agent:mime-version:date:message-id\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=4QafEBwodfJ3jTBOf6LG6pKeH4Gi39+7IdEPgFCdl0w=;\n\tb=Cgk7clljUTHGEJ8BrmMj8OcL5I/GIm0O1kRJj8l1hp3EJ3Me7+MwasII8HeI9XJitM\n\tKoTh/e98xnZy20RXzy8vDZH1WNT0fhHIWdIkr6DMZ4l20JDsXVsIvukDphDHX6ekM/j+\n\twLUNxIew2G3jCA6CowyDBbKmFefhHPuPy71ez6ll4r2AR4FlLc28iimZa233TcVOnJVv\n\tJeY4f431v3pmHaqF1d5Gjokxd0zrCkRJyqYux7jybEGDWTmIxl2tP7tM6Zfb7htWdbdR\n\tcCKU2WRra3yoT78qUySG/rNkH+D3Cr/jyBs93T5WpJA/OPf5wChu+foiVHR0gnr2J5nd\n\tn1mg==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCXYtCXloa/pY7NcJKxRTm92Gc0poo0rVYz/eVMw2FysJOKBAimflGek+vADmum20fP1hEYtLSd3I7uskS7QWb5gDqE9+beb4LqueIApkCHnJwvBxw==","X-Gm-Message-State":"AOJu0YwwTxygIYK6kkKPQSNqiFnJuJvIFTJ7dppptMc6cyQMcDZhMgXQ\n\tO1JP+9BrWfaJz5HHBKKxqzSSU7QnI/qxsuxObapXTBnvuN7JQaef+zmp29saNcyz1ePx5iUyWbg\n\tINik3Fd1GtT3vOJ+qRLO73C/GXEEheXu3FkGQC3kFpVC+M3OBnAm5ii8k5i5Tpu+PohDVFyxhqG\n\tCVZm8=","X-Received":["by 2002:a50:cd84:0:b0:57c:61a2:ed47 with SMTP id\n\t4fb4d7f45d1cf-57d4bd83130mr2316592a12.24.1719221873925; \n\tMon, 24 Jun 2024 02:37:53 -0700 (PDT)","by 2002:a50:cd84:0:b0:57c:61a2:ed47 with SMTP id\n\t4fb4d7f45d1cf-57d4bd83130mr2316583a12.24.1719221873396; \n\tMon, 24 Jun 2024 02:37:53 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IESaa/oAP9N3eyJaenlT6MvxiaG9EUr4B54s0avFWwzrQOD9AmjzghApKqa9lOhTGsEw0a33A==","Message-ID":"<3048b066-a927-4602-a783-e3f660ff018c@redhat.com>","Date":"Mon, 24 Jun 2024 11:37:52 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","To":"Robert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>","References":"<20240618063227.197989-1-robert.mader@collabora.com>","From":"Hans de Goede <hdegoede@redhat.com>","In-Reply-To":"<20240618063227.197989-1-robert.mader@collabora.com>","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"7bit","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":30049,"web_url":"https://patchwork.libcamera.org/comment/30049/","msgid":"<171922977962.341316.6814845742008517299@ping.linuxembedded.co.uk>","date":"2024-06-24T11:49:39","subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Hans de Goede (2024-06-24 10:37:52)\n> Hi,\n> \n> On 6/18/24 8:31 AM, Robert Mader wrote:\n> > In order to be more compatible with modern hardware and APIs. This\n> > notably allows GL implementations to directly import the buffers more\n> > often and seems to be required for Wayland.\n> > \n> > Further more, as we already enforce a 8 byte stride, these formats work\n> > better for clients that don't support padding - such as libwebrtc at the\n> > time of writing.\n> > \n> > Tested devices:\n> >  - Librem5\n> >  - PinePhone\n> >  - Thinkpad X13s\n> > \n> > Signed-off-by: Robert Mader <robert.mader@collabora.com>\n> > Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> Thanks, patch looks good to me:\n> \n> Reviewed-by: Hans de Goede <hdegoede@redhat.com>\n\nThanks Hans,\n\nI'm sorry I can't add your tag though as I merged this last week.\n- https://git.libcamera.org/libcamera/libcamera.git/commit/?id=437e601653e69c82f5396979d99e7b9b5bb6086b\n\n--\nKieran\n\n\n> \n> Regards,\n> \n> Hans\n> \n> \n> \n> \n> > \n> > ---\n> > \n> > Changes in v3:\n> >  - Remove previously introduced variable again and use C++ templates\n> >    instead in order to avoid runtime costs\n> >  - Small cleanups and linting fixes\n> > \n> > Changes in v2:\n> >  - Reduce code duplication by using a runtime variable instead\n> >  - Small cleanups\n> > ---\n> >  src/libcamera/software_isp/debayer_cpu.cpp | 75 +++++++++++++++++-----\n> >  src/libcamera/software_isp/debayer_cpu.h   | 10 +++\n> >  2 files changed, 69 insertions(+), 16 deletions(-)\n> > \n> > diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> > index c038eed4..f8d2677d 100644\n> > --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> > +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> > @@ -74,6 +74,8 @@ DebayerCpu::~DebayerCpu()\n> >       *dst++ = blue_[curr[x] / (div)];                                                      \\\n> >       *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n> >       *dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> > +     if constexpr (addAlphaByte)                                                           \\\n> > +             *dst++ = 255;                                                                 \\\n> >       x++;\n> >  \n> >  /*\n> > @@ -85,6 +87,8 @@ DebayerCpu::~DebayerCpu()\n> >       *dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n> >       *dst++ = green_[curr[x] / (div)];                         \\\n> >       *dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> > +     if constexpr (addAlphaByte)                               \\\n> > +             *dst++ = 255;                                     \\\n> >       x++;\n> >  \n> >  /*\n> > @@ -96,6 +100,8 @@ DebayerCpu::~DebayerCpu()\n> >       *dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n> >       *dst++ = green_[curr[x] / (div)];                          \\\n> >       *dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n> > +     if constexpr (addAlphaByte)                                \\\n> > +             *dst++ = 255;                                      \\\n> >       x++;\n> >  \n> >  /*\n> > @@ -107,8 +113,11 @@ DebayerCpu::~DebayerCpu()\n> >       *dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n> >       *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n> >       *dst++ = red_[curr[x] / (div)];                                                        \\\n> > +     if constexpr (addAlphaByte)                                                            \\\n> > +             *dst++ = 255;                                                                  \\\n> >       x++;\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       DECLARE_SRC_POINTERS(uint8_t)\n> > @@ -119,6 +128,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       DECLARE_SRC_POINTERS(uint8_t)\n> > @@ -129,6 +139,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       DECLARE_SRC_POINTERS(uint16_t)\n> > @@ -140,6 +151,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       DECLARE_SRC_POINTERS(uint16_t)\n> > @@ -151,6 +163,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       DECLARE_SRC_POINTERS(uint16_t)\n> > @@ -162,6 +175,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       DECLARE_SRC_POINTERS(uint16_t)\n> > @@ -173,6 +187,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       const int widthInBytes = window_.width * 5 / 4;\n> > @@ -198,6 +213,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       const int widthInBytes = window_.width * 5 / 4;\n> > @@ -218,6 +234,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       const int widthInBytes = window_.width * 5 / 4;\n> > @@ -238,6 +255,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n> >       }\n> >  }\n> >  \n> > +template<bool addAlphaByte>\n> >  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n> >  {\n> >       const int widthInBytes = window_.width * 5 / 4;\n> > @@ -280,7 +298,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n> >               config.bpp = (bayerFormat.bitDepth + 7) & ~7;\n> >               config.patternSize.width = 2;\n> >               config.patternSize.height = 2;\n> > -             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> > +             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n> > +                                                               formats::XRGB8888,\n> > +                                                               formats::ARGB8888,\n> > +                                                               formats::BGR888,\n> > +                                                               formats::XBGR8888,\n> > +                                                               formats::ABGR8888 });\n> >               return 0;\n> >       }\n> >  \n> > @@ -290,7 +313,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n> >               config.bpp = 10;\n> >               config.patternSize.width = 4; /* 5 bytes per *4* pixels */\n> >               config.patternSize.height = 2;\n> > -             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n> > +             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n> > +                                                               formats::XRGB8888,\n> > +                                                               formats::ARGB8888,\n> > +                                                               formats::BGR888,\n> > +                                                               formats::XBGR8888,\n> > +                                                               formats::ABGR8888 });\n> >               return 0;\n> >       }\n> >  \n> > @@ -306,6 +334,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n> >               return 0;\n> >       }\n> >  \n> > +     if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n> > +         outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n> > +             config.bpp = 32;\n> > +             return 0;\n> > +     }\n> > +\n> >       LOG(Debayer, Info)\n> >               << \"Unsupported output format \" << outputFormat.toString();\n> >       return -EINVAL;\n> > @@ -341,6 +375,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n> >  {\n> >       BayerFormat bayerFormat =\n> >               BayerFormat::fromPixelFormat(inputFormat);\n> > +     bool addAlphaByte = false;\n> >  \n> >       xShift_ = 0;\n> >       swapRedBlueGains_ = false;\n> > @@ -351,8 +386,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n> >       };\n> >  \n> >       switch (outputFormat) {\n> > +     case formats::XRGB8888:\n> > +     case formats::ARGB8888:\n> > +             addAlphaByte = true;\n> > +             [[fallthrough]];\n> >       case formats::RGB888:\n> >               break;\n> > +     case formats::XBGR8888:\n> > +     case formats::ABGR8888:\n> > +             addAlphaByte = true;\n> > +             [[fallthrough]];\n> >       case formats::BGR888:\n> >               /* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n> >               swapRedBlueGains_ = true;\n> > @@ -383,16 +426,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n> >           isStandardBayerOrder(bayerFormat.order)) {\n> >               switch (bayerFormat.bitDepth) {\n> >               case 8:\n> > -                     debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer8_BGBG_BGR888<true> : &DebayerCpu::debayer8_BGBG_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer8_GRGR_BGR888<true> : &DebayerCpu::debayer8_GRGR_BGR888<false>;\n> >                       break;\n> >               case 10:\n> > -                     debayer0_ = &DebayerCpu::debayer10_BGBG_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer10_GRGR_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10_BGBG_BGR888<true> : &DebayerCpu::debayer10_BGBG_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10_GRGR_BGR888<true> : &DebayerCpu::debayer10_GRGR_BGR888<false>;\n> >                       break;\n> >               case 12:\n> > -                     debayer0_ = &DebayerCpu::debayer12_BGBG_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer12_GRGR_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer12_BGBG_BGR888<true> : &DebayerCpu::debayer12_BGBG_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer12_GRGR_BGR888<true> : &DebayerCpu::debayer12_GRGR_BGR888<false>;\n> >                       break;\n> >               }\n> >               setupStandardBayerOrder(bayerFormat.order);\n> > @@ -403,20 +446,20 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n> >           bayerFormat.packing == BayerFormat::Packing::CSI2) {\n> >               switch (bayerFormat.order) {\n> >               case BayerFormat::BGGR:\n> > -                     debayer0_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n> >                       return 0;\n> >               case BayerFormat::GBRG:\n> > -                     debayer0_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n> >                       return 0;\n> >               case BayerFormat::GRBG:\n> > -                     debayer0_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n> >                       return 0;\n> >               case BayerFormat::RGGB:\n> > -                     debayer0_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n> > -                     debayer1_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n> > +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n> > +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n> >                       return 0;\n> >               default:\n> >                       break;\n> > diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> > index be7dcdca..1dac6435 100644\n> > --- a/src/libcamera/software_isp/debayer_cpu.h\n> > +++ b/src/libcamera/software_isp/debayer_cpu.h\n> > @@ -85,18 +85,28 @@ private:\n> >       using debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n> >  \n> >       /* 8-bit raw bayer format */\n> > +     template<bool addAlphaByte>\n> >       void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> > +     template<bool addAlphaByte>\n> >       void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> >       /* unpacked 10-bit raw bayer format */\n> > +     template<bool addAlphaByte>\n> >       void debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> > +     template<bool addAlphaByte>\n> >       void debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> >       /* unpacked 12-bit raw bayer format */\n> > +     template<bool addAlphaByte>\n> >       void debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> > +     template<bool addAlphaByte>\n> >       void debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> >       /* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n> > +     template<bool addAlphaByte>\n> >       void debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> > +     template<bool addAlphaByte>\n> >       void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> > +     template<bool addAlphaByte>\n> >       void debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n> > +     template<bool addAlphaByte>\n> >       void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> >  \n> >       struct DebayerInputConfig {\n>","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 88A49BDB1D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Jun 2024 11:49:43 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2ABAC654A9;\n\tMon, 24 Jun 2024 13:49:43 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E553654A1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Jun 2024 13:49:42 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8824D7E0;\n\tMon, 24 Jun 2024 13:49:20 +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=\"RKUnXCGU\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1719229760;\n\tbh=26vpuvYRdxNE1QUKZmbnm4lN6FOF14c2/r2qrd27qSI=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=RKUnXCGUV5FWj4l9pChxqxsPtl4j9a150shKs8kroTgUdtfI+EboHvEEa+eoUgNqk\n\tQzemeRiJvnFL5X8B20dKr9NLUJE57/Id4+kcSlCeopi2CZhE/9iOXeANMjb6GgY2Sm\n\tWuLxoIM/z53/lkusoDo23yZFfXAXvhKbAI/Bz9iE=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<3048b066-a927-4602-a783-e3f660ff018c@redhat.com>","References":"<20240618063227.197989-1-robert.mader@collabora.com>\n\t<3048b066-a927-4602-a783-e3f660ff018c@redhat.com>","Subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"","To":"Hans de Goede <hdegoede@redhat.com>,\n\tRobert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 24 Jun 2024 12:49:39 +0100","Message-ID":"<171922977962.341316.6814845742008517299@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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":30050,"web_url":"https://patchwork.libcamera.org/comment/30050/","msgid":"<7d34e67f-79f9-4bb7-b336-9f856ef41f12@redhat.com>","date":"2024-06-24T12:33:44","subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","submitter":{"id":102,"url":"https://patchwork.libcamera.org/api/people/102/","name":"Hans de Goede","email":"hdegoede@redhat.com"},"content":"Hi,\n\nOn 6/24/24 1:49 PM, Kieran Bingham wrote:\n> Quoting Hans de Goede (2024-06-24 10:37:52)\n>> Hi,\n>>\n>> On 6/18/24 8:31 AM, Robert Mader wrote:\n>>> In order to be more compatible with modern hardware and APIs. This\n>>> notably allows GL implementations to directly import the buffers more\n>>> often and seems to be required for Wayland.\n>>>\n>>> Further more, as we already enforce a 8 byte stride, these formats work\n>>> better for clients that don't support padding - such as libwebrtc at the\n>>> time of writing.\n>>>\n>>> Tested devices:\n>>>  - Librem5\n>>>  - PinePhone\n>>>  - Thinkpad X13s\n>>>\n>>> Signed-off-by: Robert Mader <robert.mader@collabora.com>\n>>> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>>\n>> Thanks, patch looks good to me:\n>>\n>> Reviewed-by: Hans de Goede <hdegoede@redhat.com>\n> \n> Thanks Hans,\n> \n> I'm sorry I can't add your tag though as I merged this last week.\n> - https://git.libcamera.org/libcamera/libcamera.git/commit/?id=437e601653e69c82f5396979d99e7b9b5bb6086b\n\nNo worries, good that it is already merged :)\n\nRegards,\n\nHans\n\n\n\n\n>>> ---\n>>>\n>>> Changes in v3:\n>>>  - Remove previously introduced variable again and use C++ templates\n>>>    instead in order to avoid runtime costs\n>>>  - Small cleanups and linting fixes\n>>>\n>>> Changes in v2:\n>>>  - Reduce code duplication by using a runtime variable instead\n>>>  - Small cleanups\n>>> ---\n>>>  src/libcamera/software_isp/debayer_cpu.cpp | 75 +++++++++++++++++-----\n>>>  src/libcamera/software_isp/debayer_cpu.h   | 10 +++\n>>>  2 files changed, 69 insertions(+), 16 deletions(-)\n>>>\n>>> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n>>> index c038eed4..f8d2677d 100644\n>>> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n>>> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n>>> @@ -74,6 +74,8 @@ DebayerCpu::~DebayerCpu()\n>>>       *dst++ = blue_[curr[x] / (div)];                                                      \\\n>>>       *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];       \\\n>>>       *dst++ = red_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>>> +     if constexpr (addAlphaByte)                                                           \\\n>>> +             *dst++ = 255;                                                                 \\\n>>>       x++;\n>>>  \n>>>  /*\n>>> @@ -85,6 +87,8 @@ DebayerCpu::~DebayerCpu()\n>>>       *dst++ = blue_[(prev[x] + next[x]) / (2 * (div))];        \\\n>>>       *dst++ = green_[curr[x] / (div)];                         \\\n>>>       *dst++ = red_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>>> +     if constexpr (addAlphaByte)                               \\\n>>> +             *dst++ = 255;                                     \\\n>>>       x++;\n>>>  \n>>>  /*\n>>> @@ -96,6 +100,8 @@ DebayerCpu::~DebayerCpu()\n>>>       *dst++ = blue_[(curr[x - p] + curr[x + n]) / (2 * (div))]; \\\n>>>       *dst++ = green_[curr[x] / (div)];                          \\\n>>>       *dst++ = red_[(prev[x] + next[x]) / (2 * (div))];          \\\n>>> +     if constexpr (addAlphaByte)                                \\\n>>> +             *dst++ = 255;                                      \\\n>>>       x++;\n>>>  \n>>>  /*\n>>> @@ -107,8 +113,11 @@ DebayerCpu::~DebayerCpu()\n>>>       *dst++ = blue_[(prev[x - p] + prev[x + n] + next[x - p] + next[x + n]) / (4 * (div))]; \\\n>>>       *dst++ = green_[(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div))];        \\\n>>>       *dst++ = red_[curr[x] / (div)];                                                        \\\n>>> +     if constexpr (addAlphaByte)                                                            \\\n>>> +             *dst++ = 255;                                                                  \\\n>>>       x++;\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       DECLARE_SRC_POINTERS(uint8_t)\n>>> @@ -119,6 +128,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       DECLARE_SRC_POINTERS(uint8_t)\n>>> @@ -129,6 +139,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       DECLARE_SRC_POINTERS(uint16_t)\n>>> @@ -140,6 +151,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       DECLARE_SRC_POINTERS(uint16_t)\n>>> @@ -151,6 +163,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       DECLARE_SRC_POINTERS(uint16_t)\n>>> @@ -162,6 +175,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       DECLARE_SRC_POINTERS(uint16_t)\n>>> @@ -173,6 +187,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       const int widthInBytes = window_.width * 5 / 4;\n>>> @@ -198,6 +213,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       const int widthInBytes = window_.width * 5 / 4;\n>>> @@ -218,6 +234,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       const int widthInBytes = window_.width * 5 / 4;\n>>> @@ -238,6 +255,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>       }\n>>>  }\n>>>  \n>>> +template<bool addAlphaByte>\n>>>  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>>  {\n>>>       const int widthInBytes = window_.width * 5 / 4;\n>>> @@ -280,7 +298,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>>>               config.bpp = (bayerFormat.bitDepth + 7) & ~7;\n>>>               config.patternSize.width = 2;\n>>>               config.patternSize.height = 2;\n>>> -             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n>>> +             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n>>> +                                                               formats::XRGB8888,\n>>> +                                                               formats::ARGB8888,\n>>> +                                                               formats::BGR888,\n>>> +                                                               formats::XBGR8888,\n>>> +                                                               formats::ABGR8888 });\n>>>               return 0;\n>>>       }\n>>>  \n>>> @@ -290,7 +313,12 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n>>>               config.bpp = 10;\n>>>               config.patternSize.width = 4; /* 5 bytes per *4* pixels */\n>>>               config.patternSize.height = 2;\n>>> -             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888, formats::BGR888 });\n>>> +             config.outputFormats = std::vector<PixelFormat>({ formats::RGB888,\n>>> +                                                               formats::XRGB8888,\n>>> +                                                               formats::ARGB8888,\n>>> +                                                               formats::BGR888,\n>>> +                                                               formats::XBGR8888,\n>>> +                                                               formats::ABGR8888 });\n>>>               return 0;\n>>>       }\n>>>  \n>>> @@ -306,6 +334,12 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c\n>>>               return 0;\n>>>       }\n>>>  \n>>> +     if (outputFormat == formats::XRGB8888 || outputFormat == formats::ARGB8888 ||\n>>> +         outputFormat == formats::XBGR8888 || outputFormat == formats::ABGR8888) {\n>>> +             config.bpp = 32;\n>>> +             return 0;\n>>> +     }\n>>> +\n>>>       LOG(Debayer, Info)\n>>>               << \"Unsupported output format \" << outputFormat.toString();\n>>>       return -EINVAL;\n>>> @@ -341,6 +375,7 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>>  {\n>>>       BayerFormat bayerFormat =\n>>>               BayerFormat::fromPixelFormat(inputFormat);\n>>> +     bool addAlphaByte = false;\n>>>  \n>>>       xShift_ = 0;\n>>>       swapRedBlueGains_ = false;\n>>> @@ -351,8 +386,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>>       };\n>>>  \n>>>       switch (outputFormat) {\n>>> +     case formats::XRGB8888:\n>>> +     case formats::ARGB8888:\n>>> +             addAlphaByte = true;\n>>> +             [[fallthrough]];\n>>>       case formats::RGB888:\n>>>               break;\n>>> +     case formats::XBGR8888:\n>>> +     case formats::ABGR8888:\n>>> +             addAlphaByte = true;\n>>> +             [[fallthrough]];\n>>>       case formats::BGR888:\n>>>               /* Swap R and B in bayer order to generate BGR888 instead of RGB888 */\n>>>               swapRedBlueGains_ = true;\n>>> @@ -383,16 +426,16 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>>           isStandardBayerOrder(bayerFormat.order)) {\n>>>               switch (bayerFormat.bitDepth) {\n>>>               case 8:\n>>> -                     debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer8_BGBG_BGR888<true> : &DebayerCpu::debayer8_BGBG_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer8_GRGR_BGR888<true> : &DebayerCpu::debayer8_GRGR_BGR888<false>;\n>>>                       break;\n>>>               case 10:\n>>> -                     debayer0_ = &DebayerCpu::debayer10_BGBG_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer10_GRGR_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10_BGBG_BGR888<true> : &DebayerCpu::debayer10_BGBG_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10_GRGR_BGR888<true> : &DebayerCpu::debayer10_GRGR_BGR888<false>;\n>>>                       break;\n>>>               case 12:\n>>> -                     debayer0_ = &DebayerCpu::debayer12_BGBG_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer12_GRGR_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer12_BGBG_BGR888<true> : &DebayerCpu::debayer12_BGBG_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer12_GRGR_BGR888<true> : &DebayerCpu::debayer12_GRGR_BGR888<false>;\n>>>                       break;\n>>>               }\n>>>               setupStandardBayerOrder(bayerFormat.order);\n>>> @@ -403,20 +446,20 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>>           bayerFormat.packing == BayerFormat::Packing::CSI2) {\n>>>               switch (bayerFormat.order) {\n>>>               case BayerFormat::BGGR:\n>>> -                     debayer0_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n>>>                       return 0;\n>>>               case BayerFormat::GBRG:\n>>> -                     debayer0_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n>>>                       return 0;\n>>>               case BayerFormat::GRBG:\n>>> -                     debayer0_ = &DebayerCpu::debayer10P_GRGR_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer10P_BGBG_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_GRGR_BGR888<true> : &DebayerCpu::debayer10P_GRGR_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_BGBG_BGR888<true> : &DebayerCpu::debayer10P_BGBG_BGR888<false>;\n>>>                       return 0;\n>>>               case BayerFormat::RGGB:\n>>> -                     debayer0_ = &DebayerCpu::debayer10P_RGRG_BGR888;\n>>> -                     debayer1_ = &DebayerCpu::debayer10P_GBGB_BGR888;\n>>> +                     debayer0_ = addAlphaByte ? &DebayerCpu::debayer10P_RGRG_BGR888<true> : &DebayerCpu::debayer10P_RGRG_BGR888<false>;\n>>> +                     debayer1_ = addAlphaByte ? &DebayerCpu::debayer10P_GBGB_BGR888<true> : &DebayerCpu::debayer10P_GBGB_BGR888<false>;\n>>>                       return 0;\n>>>               default:\n>>>                       break;\n>>> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n>>> index be7dcdca..1dac6435 100644\n>>> --- a/src/libcamera/software_isp/debayer_cpu.h\n>>> +++ b/src/libcamera/software_isp/debayer_cpu.h\n>>> @@ -85,18 +85,28 @@ private:\n>>>       using debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n>>>  \n>>>       /* 8-bit raw bayer format */\n>>> +     template<bool addAlphaByte>\n>>>       void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>> +     template<bool addAlphaByte>\n>>>       void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>>       /* unpacked 10-bit raw bayer format */\n>>> +     template<bool addAlphaByte>\n>>>       void debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>> +     template<bool addAlphaByte>\n>>>       void debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>>       /* unpacked 12-bit raw bayer format */\n>>> +     template<bool addAlphaByte>\n>>>       void debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>> +     template<bool addAlphaByte>\n>>>       void debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>>       /* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n>>> +     template<bool addAlphaByte>\n>>>       void debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>> +     template<bool addAlphaByte>\n>>>       void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>> +     template<bool addAlphaByte>\n>>>       void debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>> +     template<bool addAlphaByte>\n>>>       void debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>>  \n>>>       struct DebayerInputConfig {\n>>\n>","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 22383BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Jun 2024 12:33:56 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3D5C9654A9;\n\tMon, 24 Jun 2024 14:33:55 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6AE04654A1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Jun 2024 14:33:52 +0200 (CEST)","from mail-ej1-f69.google.com (mail-ej1-f69.google.com\n\t[209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-147-n6UEvP7IPb2JbhaxzsYKgQ-1; Mon, 24 Jun 2024 08:33:47 -0400","by mail-ej1-f69.google.com with SMTP id\n\ta640c23a62f3a-a725c45ab1dso41109366b.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Jun 2024 05:33:47 -0700 (PDT)","from [10.40.98.157] ([78.108.130.194])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-a6fcf56033asm405781466b.157.2024.06.24.05.33.44\n\t(version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n\tMon, 24 Jun 2024 05:33:44 -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=\"cyItTb3s\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1719232431;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=UEl4vOXiVKxlcjuUa0xMCTdp8uXGcn2rypSuoasasIc=;\n\tb=cyItTb3sr9pdEpKDQuVqzSZL6W7Jgkyi5OeK89ih7i6sOYD4+RAt36h9kAezFqgJSCqIOn\n\tvM/Q6U5jYRx0rNW6EfJWTCUsIa9OYqT0wtmB5X2XAojm5dqW3cyXYZdEAXuqwpcAFxHZHU\n\tvWZO3jqLox/0RpPQJuSdmctahvjnVaU=","X-MC-Unique":"n6UEvP7IPb2JbhaxzsYKgQ-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1719232425; x=1719837225;\n\th=content-transfer-encoding:in-reply-to:from:content-language\n\t:references:to:subject:user-agent:mime-version:date:message-id\n\t:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n\tbh=UEl4vOXiVKxlcjuUa0xMCTdp8uXGcn2rypSuoasasIc=;\n\tb=JyWndK7OPz09oxdSEaXpGuYk0D00xChngD+zHMw5ZP5P1h5WCTQ8nHfLJQdM1F3vCu\n\tCBU2QLphkImUiMnANnMndRE7WXXZInuNkNKpCAC/Ru1EOg/NF7Vv7FOJKIrxFDbszZmS\n\tyM3mOW3LLNp13PIU+MoL2aZg/DMOlNCCULiZSHO76Q0MURSniCJNRpuUK/pwRszTsiY2\n\tfi50gjyo6N65joB2ekzMn4rTShQVuddTGQ52V1NbuptkqaJ3c7xAq9ki3EgOPIq8/hw8\n\tKkHdOMglt89u/Y0a/oKRZHdxPxE+JtqnI3r8D9YLoqNxVPAQm418wgqi5cN3H6JV65rh\n\t+W1Q==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCX8te/aXwbXD+cG2nxOXV74B3f9TeUxLwIJjbMUrby9VyngP2mg0sXGO1pgmFlJAuAYEIkyyHm8vykN9b4QflRJTzqLXQVDVXMfC62CmitDXH9zIA==","X-Gm-Message-State":"AOJu0YyjQvnLJasZWda4Vn3ayK+j3xxdapoSp8vzRaj80fpfsjXpzjVH\n\tcoZQineGvm8Z0ZnvweEmB1JnDcSzrPg5ahItkVo/lcdNdhEXeRkJ7+1/iBgpVCEn4FiYsgHrlDs\n\tOeKRfPA9Z24s2mWhSMNiAL0dP/3GixvZRPXNxFNKf6GBQOW3ginDx2FhPbJhb/A9B/GBLE7OpL+\n\t68dbc=","X-Received":["by 2002:a17:907:7649:b0:a6f:e5f7:e966 with SMTP id\n\ta640c23a62f3a-a7242c4d33amr387798066b.45.1719232425510; \n\tMon, 24 Jun 2024 05:33:45 -0700 (PDT)","by 2002:a17:907:7649:b0:a6f:e5f7:e966 with SMTP id\n\ta640c23a62f3a-a7242c4d33amr387796266b.45.1719232425011; \n\tMon, 24 Jun 2024 05:33:45 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IE/fXBfaiCTIFUXg/auvUJPpd9o2MTdyuWgzOZ0hF3x1hBaalTvTLh3Dx/JHPVSdn9RlacEsQ==","Message-ID":"<7d34e67f-79f9-4bb7-b336-9f856ef41f12@redhat.com>","Date":"Mon, 24 Jun 2024 14:33:44 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v3] libcamera: debayer_cpu: Add 32bits/aligned output\n\tformats","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tRobert Mader <robert.mader@collabora.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20240618063227.197989-1-robert.mader@collabora.com>\n\t<3048b066-a927-4602-a783-e3f660ff018c@redhat.com>\n\t<171922977962.341316.6814845742008517299@ping.linuxembedded.co.uk>","From":"Hans de Goede <hdegoede@redhat.com>","In-Reply-To":"<171922977962.341316.6814845742008517299@ping.linuxembedded.co.uk>","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Language":"en-US","Content-Type":"text/plain; charset=UTF-8","Content-Transfer-Encoding":"7bit","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>"}}]