From patchwork Thu Aug 27 10:50:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 28135 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 DA691BDDFC for ; Thu, 27 Aug 2026 10:51:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 85CF5684AB; Thu, 27 Aug 2026 12:51:24 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Wz5bpBS8"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7E93D68487 for ; Thu, 27 Aug 2026 12:51:23 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2400:2411:160:2f00:306c:5b5b:3c7f:eabd]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E157B5B3; Thu, 27 Aug 2026 12:49:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1787827797; bh=ypgaeSKGTecFJxmyEszOvRBHjkql1IoNR37SL1UYewM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wz5bpBS8TF/4fWLi+pHq3kaYN6mVv5+QqPWxvEy6O9u0o7tyESwsn0oiOBCJun6S/ 4mVY5Bajc8rgPpKRi+vNt7dmD48k1RzYc+M4s4F+FnIZLk/XeZO3sz5Ja+p3PvmVT0 Yq8oa4Z53WFAQJkIpMn/QJfK5VlOR1emfPARINCg= From: Paul Elder To: laurent.pinchart@ideasonboard.com Cc: Paul Elder , michael.riesch@collabora.com, xuhf@rock-chips.com, stefan.klug@ideasonboard.com, kieran.bingham@ideasonboard.com, dan.scally@ideasonboard.com, jacopo.mondi@ideasonboard.com, nicolas.dufresne@collabora.com, mehdi.djait@linux.intel.com, libcamera-devel@lists.libcamera.org Subject: [PATCH v3 15/20] ipa: rkisp2: algo: crop: Implement scaler crop Date: Thu, 27 Aug 2026 19:50:08 +0900 Message-ID: <20260827105018.2781166-16-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20260827105018.2781166-1-paul.elder@ideasonboard.com> References: <20260827105018.2781166-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement a thin algorithm for handling the ScalerCrop control. As rkisp2 uses parameter buffers to configure scaling and cropping (as opposed to v4l2 subdev pads), it is cleaner to implement scaler crop as an algorithm in the IPA. Signed-off-by: Paul Elder --- New in v2 --- src/ipa/rkisp2/algorithms/crop.cpp | 99 +++++++++++++++++++++++++++ src/ipa/rkisp2/algorithms/crop.h | 39 +++++++++++ src/ipa/rkisp2/algorithms/meson.build | 1 + 3 files changed, 139 insertions(+) create mode 100644 src/ipa/rkisp2/algorithms/crop.cpp create mode 100644 src/ipa/rkisp2/algorithms/crop.h diff --git a/src/ipa/rkisp2/algorithms/crop.cpp b/src/ipa/rkisp2/algorithms/crop.cpp new file mode 100644 index 000000000000..df275173c497 --- /dev/null +++ b/src/ipa/rkisp2/algorithms/crop.cpp @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * RkISP2 Crop + */ + +#include "crop.h" + +#include + +#include + +#include +#include + +#include + +/** + * \file crop.h + */ + +namespace libcamera { + +namespace ipa::rkisp2::algorithms { + +/** + * \class Crop + * \brief RkISP2 Crop + * + * This is a thin algorithm that implements ScalerCrop for the RkISP2. + * + * As the cropping of the RkISP2 is controlled by parameter buffers instead of + * by V4L2 crop rectangles, it is more practical to implement the ScalerCrop + * control here instead of in the pipeline handler. This also has the positive + * side effect of supporting per-frame ScalerCrop. + */ + +LOG_DEFINE_CATEGORY(RkISP2Crop) + +/** + * \copydoc libcamera::ipa::Algorithm::queueRequest + */ +void Crop::queueRequest(IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) +{ + frameContext.crop.crop = context.activeState.crop.crop; + + const auto &scalerCrop = controls.get(controls::ScalerCrop); + if (!scalerCrop) + return; + + context.activeState.crop.crop = *scalerCrop; + + frameContext.crop.crop = context.activeState.crop.crop; + frameContext.crop.set = true; +} + +/** + * \copydoc libcamera::ipa::Algorithm::prepare + */ +void Crop::prepare([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] RkISP2Params *params) +{ + if (!frameContext.crop.set) + return; + + auto config = params->block(); + config.setEnabled(true); + + config->crop_en = RKISP2_ISP_CROP_ENABLE_MAIN; + config->mp_crop.h_offs = frameContext.crop.crop.x; + config->mp_crop.v_offs = frameContext.crop.crop.y; + config->mp_crop.h_size = frameContext.crop.crop.width; + config->mp_crop.v_size = frameContext.crop.crop.height; +} + +/** + * \copydoc libcamera::ipa::Algorithm::process + */ +void Crop::process([[maybe_unused]] IPAContext &context, + [[maybe_unused]] const uint32_t frame, + IPAFrameContext &frameContext, + [[maybe_unused]] const RkISP2Stats *stats, + ControlList &metadata) +{ + /* \todo Adjust this to match the spec */ + metadata.set(controls::ScalerCrop, frameContext.crop.crop); +} + +REGISTER_IPA_ALGORITHM(Crop, "Crop") + +} /* namespace ipa::rkisp2::algorithms */ + +} /* namespace libcamera */ diff --git a/src/ipa/rkisp2/algorithms/crop.h b/src/ipa/rkisp2/algorithms/crop.h new file mode 100644 index 000000000000..7c21e20c86ec --- /dev/null +++ b/src/ipa/rkisp2/algorithms/crop.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026, Ideas On Board + * + * RkISP2 Crop + */ + +#pragma once + +#include "algorithm.h" + +namespace libcamera { + +namespace ipa::rkisp2::algorithms { + +class Crop : public Algorithm +{ +public: + Crop() = default; + ~Crop() = default; + + void queueRequest(IPAContext &context, + const uint32_t frame, + IPAFrameContext &frameContext, + const ControlList &controls) override; + void prepare(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + RkISP2Params *params) override; + void process(IPAContext &context, const uint32_t frame, + IPAFrameContext &frameContext, + const RkISP2Stats *stats, + ControlList &metadata) override; + +private: + Rectangle defaultCrop_; +}; + +} /* namespace ipa::rkisp2::algorithms */ +} /* namespace libcamera */ diff --git a/src/ipa/rkisp2/algorithms/meson.build b/src/ipa/rkisp2/algorithms/meson.build index bcc947fabdb4..9ccc9653233a 100644 --- a/src/ipa/rkisp2/algorithms/meson.build +++ b/src/ipa/rkisp2/algorithms/meson.build @@ -5,6 +5,7 @@ rkisp2_ipa_algorithms = files([ 'awb.cpp', 'bls.cpp', 'ccm.cpp', + 'crop.cpp', 'csm.cpp', 'goc.cpp', 'lsc.cpp',