From patchwork Sat Jan 13 14:22:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 19407 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id F2CE3C328C for ; Sat, 13 Jan 2024 14:23:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 96BFE628D8; Sat, 13 Jan 2024 15:23:13 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1705155793; bh=SDHhaQ6+Ym6KOnX6DRinkpCo6BVpc5mSXiCTgqa1lL8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=b4YXJVHn/m0fFhLfRYyS6Ly8ClRh988dm2RPqmGPb6ypcaoSeOtga7oZ6YeH+oc1G pSgLZEtpu0zPiC8+BoQx2yyJjN0IkhAuBN0lMXZmyWUyNdYTHXMztX7RVcJLgsLg1D gOeMsASh8/TzgQpAa8fM1i+wk8bfKuFbjNQr6dJ0U0WsMc8G3RmHBYUCsw0BJTs+Jd QGOEPtOo2h/KQMPKUgvAY4ZejgQIRGC9sS42yNbeOL3UOhPtMvDVyfUj0p470af9gC 5jUu1D8BUIR49qfxfl+1vvAxTPqEDnSe6Y3QGXDpDXeFsGz7zLhkaVPpckw70kzwqg BFQZSchz3Bf3A== Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B660E628BA for ; Sat, 13 Jan 2024 15:23:11 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="MMvARURB"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1705155790; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i+hhMJI4JwhF6806NjP/595IzSd4eALvqtFpD2YFpZ4=; b=MMvARURBUmvZF4fP376FMApMnzT/gdns3iplBZFaWIFDCa7v85axxEYg6RZKPeKIZfZuOU ac1S4xpFT8sUXg7rUZcJ/VoMinPG3cQCHAQD5eyD1IEU1FDdUfYq15Y9hZ3er1ZJJyw2Ob bk0EnPEFJ9mahcJFvQiB3AUmkIhYCSc= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-454-FfISoMptMAKqHZhugg4pOw-1; Sat, 13 Jan 2024 09:23:07 -0500 X-MC-Unique: FfISoMptMAKqHZhugg4pOw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3628B85A589; Sat, 13 Jan 2024 14:23:07 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3EB053C25; Sat, 13 Jan 2024 14:23:05 +0000 (UTC) To: libcamera-devel@lists.libcamera.org, Andrey Konovalov Date: Sat, 13 Jan 2024 15:22:17 +0100 Message-ID: <20240113142218.28063-18-hdegoede@redhat.com> In-Reply-To: <20240113142218.28063-1-hdegoede@redhat.com> References: <20240113142218.28063-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [libcamera-devel] [PATCH v2 17/18] libcamera: debayer_cpu: Add support for 8 and 10 bpp unpacked bayer input X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Hans de Goede via libcamera-devel From: Hans de Goede Reply-To: Hans de Goede Cc: Maxime Ripard , g.martti@gmail.com, t.langendam@gmail.com, srinivas.kandagatla@linaro.org, Pavel Machek , Bryan O'Donoghue , admin@dennisbonke.com Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support for 8 and 10 bpp unpacked bayer input for all 4 standard bayer orders. Signed-off-by: Hans de Goede Tested-by: Bryan O'Donoghue # sc8280xp Lenovo x13s Tested-by: Pavel Machek --- .../internal/software_isp/debayer_cpu.h | 9 ++ src/libcamera/software_isp/debayer_cpu.cpp | 100 ++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/include/libcamera/internal/software_isp/debayer_cpu.h b/include/libcamera/internal/software_isp/debayer_cpu.h index 78573f44..99914e2a 100644 --- a/include/libcamera/internal/software_isp/debayer_cpu.h +++ b/include/libcamera/internal/software_isp/debayer_cpu.h @@ -17,6 +17,7 @@ #include +#include "libcamera/internal/bayer_format.h" #include "libcamera/internal/software_isp/swstats_cpu.h" #include "libcamera/internal/software_isp/debayer.h" @@ -80,6 +81,12 @@ private: void shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src); void process2(const uint8_t *src, uint8_t *dst); void process4(const uint8_t *src, uint8_t *dst); + /* 8-bit raw bayer format */ + void debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); + void debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); + /* unpacked 10-bit raw bayer format */ + void debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); + void debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); /* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */ void debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]); void debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]); @@ -103,6 +110,7 @@ private: int getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config); int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config); + int setupStandardBayerOrder(BayerFormat::Order order); int setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat); uint8_t gamma_[1024]; @@ -119,6 +127,7 @@ private: std::unique_ptr stats_; uint8_t *lineBuffers_[5]; unsigned int lineBufferIndex_; + unsigned int x_shift_; /* Offset of 0/1 applied to window_.x */ bool enableInputMemcpy_; float gamma_correction_; int measuredFrames_; diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp index e0c3c658..d1f8fa15 100644 --- a/src/libcamera/software_isp/debayer_cpu.cpp +++ b/src/libcamera/software_isp/debayer_cpu.cpp @@ -45,6 +45,11 @@ DebayerCpu::~DebayerCpu() free(lineBuffers_[i]); } +#define DECLARE_SRC_POINTERS(pixel_t) \ + const pixel_t *prev = (const pixel_t *)src[0] + x_shift_; \ + const pixel_t *curr = (const pixel_t *)src[1] + x_shift_; \ + const pixel_t *next = (const pixel_t *)src[2] + x_shift_; + // RGR // GBG // RGR @@ -81,6 +86,46 @@ DebayerCpu::~DebayerCpu() *dst++ = red_[curr[x] / (div)]; \ x++; +void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) +{ + DECLARE_SRC_POINTERS(uint8_t) + + for (int x = 0; x < (int)window_.width;) { + BGGR_BGR888(1, 1, 1) + GBRG_BGR888(1, 1, 1) + } +} + +void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) +{ + DECLARE_SRC_POINTERS(uint8_t) + + for (int x = 0; x < (int)window_.width;) { + GRBG_BGR888(1, 1, 1) + RGGB_BGR888(1, 1, 1) + } +} + +void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) +{ + DECLARE_SRC_POINTERS(uint16_t) + + for (int x = 0; x < (int)window_.width;) { + BGGR_BGR888(1, 1, 4) + GBRG_BGR888(1, 1, 4) + } +} + +void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]) +{ + DECLARE_SRC_POINTERS(uint16_t) + + for (int x = 0; x < (int)window_.width;) { + GRBG_BGR888(1, 1, 4) + RGGB_BGR888(1, 1, 4) + } +} + void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]) { const int width_in_bytes = window_.width * 5 / 4; @@ -170,6 +215,16 @@ int DebayerCpu::getInputConfig(PixelFormat inputFormat, DebayerInputConfig &conf BayerFormat bayerFormat = BayerFormat::fromPixelFormat(inputFormat); + if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10) && + bayerFormat.packing == BayerFormat::Packing::None && + isStandardBayerOrder(bayerFormat.order)) { + config.bpp = (bayerFormat.bitDepth + 7) & ~7; + config.patternSize.width = 2; + config.patternSize.height = 2; + config.outputFormats = std::vector({ formats::RGB888 }); + return 0; + } + if (bayerFormat.bitDepth == 10 && bayerFormat.packing == BayerFormat::Packing::CSI2 && isStandardBayerOrder(bayerFormat.order)) { @@ -197,12 +252,57 @@ int DebayerCpu::getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &c return -EINVAL; } +/* + * Check for standard Bayer orders and set x_shift_ and swap debayer0/1, so that + * a single pair of BGGR debayer functions can be used for all 4 standard orders. + */ +int DebayerCpu::setupStandardBayerOrder(BayerFormat::Order order) +{ + switch (order) { + case BayerFormat::BGGR: + break; + case BayerFormat::GBRG: + x_shift_ = 1; /* BGGR -> GBRG */ + break; + case BayerFormat::GRBG: + std::swap(debayer0_, debayer1_); /* BGGR -> GRBG */ + break; + case BayerFormat::RGGB: + x_shift_ = 1; /* BGGR -> GBRG */ + std::swap(debayer0_, debayer1_); /* GBRG -> RGGB */ + break; + default: + return -EINVAL; + } + + return 0; +} + /* TODO: this ignores outputFormat since there is only 1 supported outputFormat for now */ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, [[maybe_unused]] PixelFormat outputFormat) { BayerFormat bayerFormat = BayerFormat::fromPixelFormat(inputFormat); + x_shift_ = 0; + + if ((bayerFormat.bitDepth == 8 || bayerFormat.bitDepth == 10) && + bayerFormat.packing == BayerFormat::Packing::None && + isStandardBayerOrder(bayerFormat.order)) { + switch (bayerFormat.bitDepth) { + case 8: + debayer0_ = &DebayerCpu::debayer8_BGBG_BGR888; + debayer1_ = &DebayerCpu::debayer8_GRGR_BGR888; + break; + case 10: + debayer0_ = &DebayerCpu::debayer10_BGBG_BGR888; + debayer1_ = &DebayerCpu::debayer10_GRGR_BGR888; + break; + } + setupStandardBayerOrder(bayerFormat.order); + return 0; + } + if (bayerFormat.bitDepth == 10 && bayerFormat.packing == BayerFormat::Packing::CSI2) { switch (bayerFormat.order) {