From patchwork Mon Aug 24 09:06:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 28026 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 940F5C3339 for ; Mon, 24 Aug 2026 09:07:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AA6D683B2; Mon, 24 Aug 2026 11:07:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Hd0RRoUF"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E71E468393 for ; Mon, 24 Aug 2026 11:07:47 +0200 (CEST) Received: from neptunite.hamster-moth.ts.net (unknown [IPv6:2400:2411:160:2f00:e616:f172:fe90:f1b5]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 92B38C23; Mon, 24 Aug 2026 11:06:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1787562383; bh=XG+S1xdnPRs8D/FDSuxuXnD0Mh+1iKkem31+3QqCxvc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Hd0RRoUFTHKpxQHT3B8dFqnfZMN4pRzbwN7q3eDWaiB2SgMd647S5hctWz0mhnsji dkULL9yQIxZmAng5azLdmDWFht+1kAb+g3MlyXdyFPI85kz5fobw1xSMZTgy3ahu+w 8UsTkNz9DTc8U/D+tfTTKM5q+J2zX5ZpOnMNpODk= 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 v2 15/20] ipa: rkisp2: algo: crop: Implement scaler crop Date: Mon, 24 Aug 2026 18:06:32 +0900 Message-ID: <20260824090641.3705246-16-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20260824090641.3705246-1-paul.elder@ideasonboard.com> References: <20260824090641.3705246-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..8b39821c711e --- /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 "linux/rkisp2-config.h" + +/** + * \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',