Show a patch.

GET /api/patches/19328/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 19328,
    "url": "https://patchwork.libcamera.org/api/patches/19328/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/19328/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<ZXt1mDW1SpMyLrbT@duo.ucw.cz>",
    "date": "2023-12-14T21:37:28",
    "name": "[libcamera-devel,RFC] Add 8-bit bayer support.",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "7cab97db530d11f62bb3653b4394129532f18693",
    "submitter": {
        "id": 49,
        "url": "https://patchwork.libcamera.org/api/people/49/?format=api",
        "name": "Pavel Machek",
        "email": "pavel@ucw.cz"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/19328/mbox/",
    "series": [
        {
            "id": 4119,
            "url": "https://patchwork.libcamera.org/api/series/4119/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4119",
            "date": "2023-12-14T21:37:28",
            "name": "[libcamera-devel,RFC] Add 8-bit bayer support.",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/4119/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/19328/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/19328/checks/",
    "tags": {},
    "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 B9001BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 14 Dec 2023 21:37:31 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 02DC962B2A;\n\tThu, 14 Dec 2023 22:37:31 +0100 (CET)",
            "from jabberwock.ucw.cz (jabberwock.ucw.cz [46.255.230.98])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id F0E6661D97\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 14 Dec 2023 22:37:28 +0100 (CET)",
            "by jabberwock.ucw.cz (Postfix, from userid 1017)\n\tid AA1A71C006F; Thu, 14 Dec 2023 22:37:28 +0100 (CET)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1702589851;\n\tbh=WfxhVSvHfG8lERROEGr9Hv/HVLIBBTEbNF54sDHgem4=;\n\th=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post:\n\tList-Help:List-Subscribe:From:Reply-To:From;\n\tb=TSVvmVZi+i4kb8mzYuSevAIQpuehSz86pRrHcalTJr4qjljvJzbqPZaWDhw8hhpY+\n\tlOW/K0Mtv45wUBnmcXAvAdrLTopo/WlrvOQadOJ+Ws7sRYn0Qmlh3hoTMeWKbvA5s5\n\tyN+X9w9O+Kw/5xqmSeIOXFcEGus85Ascr6JePY2Sb/Rl1LZhQ1kGjSA9IO10xfVL27\n\tbZGp8sD4Bw4x40W6g47BH1E0DY5xZyUC0qYxAHzWXMdQeNColJ5B5MAw9+hwv111n4\n\tf1LYFt/2IB36X+c/Bg9XJdJN1gHd60eQ8sb+RrxBL1KzeTOfHvCaQ7a/yDxTO9O2BY\n\toNsMT7YdzybRQ==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucw.cz; s=gen1;\n\tt=1702589848;\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\tbh=gWZX1rGZJJWFDz6LHEWoaImjs3+/OLyFKBjcW5Y3GHM=;\n\tb=D+AmeXn0Tetp0zObx57NjQBEgpH7mSFCVw8WF252CFWN4Tac+gh6xBcvYxcM+bcJv8lSb/\n\thfLKecvEozu7p0M5pHd+oWcLa0JvZjKS0IywfimSFZvoaQXaAZyziFI2GF4/z7CJXdCraA\n\tznbSseyGHUQVIrXKDrPiNb/BHWCidYM="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ucw.cz header.i=@ucw.cz\n\theader.b=\"D+AmeXn0\"; dkim-atps=neutral",
        "Date": "Thu, 14 Dec 2023 22:37:28 +0100",
        "To": "hdegoede@redhat.com, libcamera-devel@lists.libcamera.org",
        "Message-ID": "<ZXt1mDW1SpMyLrbT@duo.ucw.cz>",
        "MIME-Version": "1.0",
        "Content-Type": "multipart/signed; micalg=pgp-sha1;\n\tprotocol=\"application/pgp-signature\"; boundary=\"LScSc9zHUDhZKbw6\"",
        "Content-Disposition": "inline",
        "Signed-off-by": "Pavel Machek <pavel@ucw.cz>",
        "Subject": "[libcamera-devel] [RFC] Add 8-bit bayer support.",
        "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>",
        "From": "Pavel Machek via libcamera-devel <libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Pavel Machek <pavel@ucw.cz>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "---\n\nDid I get it mostly right? I can't test other formats but providing\nthem should not be too hard. Does it make sense to add this to your\nseries or is it better to just wait for v1 to be merged?",
    "diff": "diff --git a/include/libcamera/internal/software_isp/debayer_cpu.h b/include/libcamera/internal/software_isp/debayer_cpu.h\nindex 7fb5be77..f3bb4321 100644\n--- a/include/libcamera/internal/software_isp/debayer_cpu.h\n+++ b/include/libcamera/internal/software_isp/debayer_cpu.h\n@@ -67,6 +67,9 @@ private:\n \tvoid debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src);\n \tvoid debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src);\n \n+\tvoid debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src);\n+\tvoid debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src);\n+\n \ttypedef void (DebayerCpu::*debayerFn)(uint8_t *dst, const uint8_t *src);\n \n \tstruct DebayerInputConfig {\ndiff --git a/include/libcamera/internal/software_isp/swstats_cpu.h b/include/libcamera/internal/software_isp/swstats_cpu.h\nindex 0ceb995f..3c43e146 100644\n--- a/include/libcamera/internal/software_isp/swstats_cpu.h\n+++ b/include/libcamera/internal/software_isp/swstats_cpu.h\n@@ -29,6 +29,8 @@ public:\n \t/* FIXME this should be dropped once AWB has moved to the IPA */\n \tSwIspStats getStats() { return *sharedStats_; }\n private:\n+\tvoid statsBGGR8Line0(const uint8_t *src, unsigned int stride);\n+\n \tvoid statsBGGR10PLine0(const uint8_t *src, unsigned int stride);\n \tvoid statsGBRG10PLine0(const uint8_t *src, unsigned int stride);\n \tvoid statsGRBG10PLine0(const uint8_t *src, unsigned int stride);\ndiff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\nindex 3eacdd5d..52910a03 100644\n--- a/src/libcamera/software_isp/debayer_cpu.cpp\n+++ b/src/libcamera/software_isp/debayer_cpu.cpp\n@@ -111,6 +111,36 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src)\n \t}\n }\n \n+void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src)\n+{\n+\tconst int width_in_bytes = window_.width;\n+\tstruct ctxt_8bit_src c = {\n+\t\tsrc - inputConfig_.stride, src, src + inputConfig_.stride,\n+\t\tred_, green_, blue_ };\n+\n+\tfor (int x = 0; x < width_in_bytes; ) {\n+\t\t/* Even pixel */\n+\t\tbggr8_bgr888(c, dst, x++, 1, 1);\n+\t\t/* Odd pixel BGGR -> GBRG */\n+\t\tgbrg8_bgr888(c, dst, x++, 1, 1);\n+\t}\n+}\n+\n+void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src)\n+{\n+\tconst int width_in_bytes = window_.width;\n+\tstruct ctxt_8bit_src c = {\n+\t\tsrc - inputConfig_.stride, src, src + inputConfig_.stride,\n+\t\tred_, green_, blue_ };\n+\n+\tfor (int x = 0; x < width_in_bytes; ) {\n+\t\t/* Even pixel */\n+\t\tgrbg8_bgr888(c, dst, x++, 1, 1);\n+\t\t/* Odd pixel GRBG -> RGGB */\n+\t\trggb8_bgr888(c, dst, x++, 1, 1);\n+\t}\n+}\n+\n void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src)\n {\n \tconst int width_in_bytes = window_.width * 5 / 4;\n@@ -152,6 +182,22 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf\n \tBayerFormat bayerFormat =\n \t\tBayerFormat::fromPixelFormat(inputFormat);\n \n+\tif (bayerFormat.bitDepth == 8) {\n+\t    \tconfig.bpp = 8;\n+\t\tconfig.patternSize.height = 2;\n+\t\tconfig.patternSize.width = 4;\n+\t\tconfig.x_shift = 0;\n+\t\tconfig.outputFormats = std::vector<PixelFormat>({ formats::RGB888 });\n+\n+\t\tswitch (bayerFormat.order) {\n+\t\tcase BayerFormat::BGGR:\n+\t\t\treturn 0;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t/* } else if (future supported fmts) { ... */\n+\t}\n+\n \tif (bayerFormat.bitDepth == 10 &&\n \t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n \t    \tconfig.bpp = 10;\n@@ -195,6 +241,17 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, [[maybe_unused]] Pi\n \tBayerFormat bayerFormat =\n \t\tBayerFormat::fromPixelFormat(inputFormat);\n \n+\tif (bayerFormat.bitDepth == 8) {\n+\t\tswitch (bayerFormat.order) {\n+\t\tcase BayerFormat::BGGR:\n+\t\t\tdebayer0_ = &DebayerCpu::debayer8_BGBG_BGR888;\n+\t\t\tdebayer1_ = &DebayerCpu::debayer8_GRGR_BGR888;\n+\t\t\treturn 0;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n \tif (bayerFormat.bitDepth == 10 &&\n \t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n \t\tswitch (bayerFormat.order) {\ndiff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp\nindex 15f23953..e65b1b65 100644\n--- a/src/libcamera/software_isp/swstats_cpu.cpp\n+++ b/src/libcamera/software_isp/swstats_cpu.cpp\n@@ -37,9 +37,9 @@ static const unsigned int GREEN_Y_MUL = 150;\t\t/* 0.59 * 256 */\n static const unsigned int BLUE_Y_MUL = 29;\t\t/* 0.11 * 256 */\n \n static inline __attribute__((always_inline)) void\n-statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, unsigned int &bright_sum_, unsigned int &too_bright_sum_, SwIspStats &stats_)\n+statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bggr, unsigned int &bright_sum_, unsigned int &too_bright_sum_, SwIspStats &stats_, bool is10p)\n {\n-\tconst int width_in_bytes = width * 5 / 4;\n+\tconst int width_in_bytes = width * (4 + is10p) / 4;\n \tuint8_t r, g, b, g2;\n \tunsigned int y_val;\n \tunsigned int sumR = 0;\n@@ -49,7 +49,7 @@ statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bg\n \tunsigned int bright_sum = 0;\n \tunsigned int too_bright_sum = 0;\n \n-\tfor (int x = 0; x < width_in_bytes; x += 5) {\n+\tfor (int x = 0; x < width_in_bytes; x += (4 + is10p)) {\n \t\tif (bggr) {\n \t\t\t/* BGGR */\n \t\t\tb  = src0[x];\n@@ -84,26 +84,31 @@ statsBayer10P(const int width, const uint8_t *src0, const uint8_t *src1, bool bg\n \ttoo_bright_sum_ += too_bright_sum;\n }\n \n+void SwStatsCpu::statsBGGR8Line0(const uint8_t *src, unsigned int stride)\n+{\n+\tstatsBayer10P(window_.width, src, src + stride, true, bright_sum_, too_bright_sum_, stats_, false);\n+}\n+\n void SwStatsCpu::statsBGGR10PLine0(const uint8_t *src, unsigned int stride)\n {\n-\tstatsBayer10P(window_.width, src, src + stride, true, bright_sum_, too_bright_sum_, stats_);\n+\tstatsBayer10P(window_.width, src, src + stride, true, bright_sum_, too_bright_sum_, stats_, true);\n }\n \n void SwStatsCpu::statsGBRG10PLine0(const uint8_t *src, unsigned int stride)\n {\n-\tstatsBayer10P(window_.width, src, src + stride, false, bright_sum_, too_bright_sum_, stats_);\n+\tstatsBayer10P(window_.width, src, src + stride, false, bright_sum_, too_bright_sum_, stats_, true);\n }\n \n void SwStatsCpu::statsGRBG10PLine0(const uint8_t *src, unsigned int stride)\n {\n \t/* GRBG is BGGR with the lines swapped */\n-\tstatsBayer10P(window_.width, src + stride, src, true, bright_sum_, too_bright_sum_, stats_);\n+\tstatsBayer10P(window_.width, src + stride, src, true, bright_sum_, too_bright_sum_, stats_, true);\n }\n \n void SwStatsCpu::statsRGGB10PLine0(const uint8_t *src, unsigned int stride)\n {\n \t/* RGGB is GBRG with the lines swapped */\n-\tstatsBayer10P(window_.width, src + stride, src, false, bright_sum_, too_bright_sum_, stats_);\n+\tstatsBayer10P(window_.width, src + stride, src, false, bright_sum_, too_bright_sum_, stats_, true);\n }\n \n void SwStatsCpu::resetStats(void)\n@@ -134,6 +139,24 @@ int SwStatsCpu::configure(const StreamConfiguration &inputCfg)\n \tstartFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::resetStats;\n \tfinishFrame_ = (SwStats::statsVoidFn)&SwStatsCpu::finishStats;\n \n+\tif (bayerFormat.bitDepth == 8) {\n+\t\tbpp_ = 8;\n+\t\tpatternSize_.height = 2;\n+\t\tpatternSize_.width = 4;\n+\t\ty_skip_mask_ = 0x0c; /* Skip every 3th and 4th line */\n+\t\tx_shift_ = 0;\n+\n+\t\tswitch (bayerFormat.order) {\n+\t\tcase BayerFormat::BGGR:\n+\t\t\tstats0_ = (SwStats::statsProcessFn)&SwStatsCpu::statsBGGR8Line0;\n+\t\t\treturn 0;\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\t/* } else if (future supported fmts) { ... */\n+\t}\n+\n+\n \tif (bayerFormat.bitDepth == 10 &&\n \t    bayerFormat.packing == BayerFormat::Packing::CSI2) {\n \t\tbpp_ = 10;\n",
    "prefixes": [
        "libcamera-devel",
        "RFC"
    ]
}