From patchwork Tue Dec 9 18:09:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaac Scott X-Patchwork-Id: 25392 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 19EE0BD1F1 for ; Tue, 9 Dec 2025 18:10:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C8D9961429; Tue, 9 Dec 2025 19:10:09 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vsuGqn4j"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4426F61429 for ; Tue, 9 Dec 2025 19:10:06 +0100 (CET) Received: from isaac-ThinkPad-T16-Gen-2.infra.iob (cpc90716-aztw32-2-0-cust408.18-1.cable.virginm.net [86.26.101.153]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C224710; Tue, 9 Dec 2025 19:10:05 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1765303805; bh=UD6fpWZwvBFwoCKR6V5tU+NV5XY0uUzW5yrhZrm2P24=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vsuGqn4jaFVuLG2OalJldOM+wCrmqpPZT31op0BdG/U63CM8aV5hSAVWicR9G0xJ/ exiP1+PSnByUe9jRSREte2wQbgu9diOQNWkeYSltlJYfOY/AlOiZ6Es1135yzl9cye wLoPq9k0WU0AP+heqaEn5w+pPWNwNHlcgkTEn6FE= From: Isaac Scott To: libcamera-devel@lists.libcamera.org Cc: Isaac Scott Subject: [RFC PATCH 3/6] pipeline: rkisp1: Add support for YUV passthrough Date: Tue, 9 Dec 2025 18:09:51 +0000 Message-ID: <20251209180954.332392-4-isaac.scott@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251209180954.332392-1-isaac.scott@ideasonboard.com> References: <20251209180954.332392-1-isaac.scott@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" When the rkisp1 is configured to bypass ISP blocks, we will have no params buffers. Modify the rkisp1 pipeline handler to not wait for params buffers to become available before queueing buffers back to the rkisp1. Signed-off-by: Isaac Scott --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 39 +++++++++++-------- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 7 ++-- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 5fd110269..ad0f3af34 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -77,7 +77,7 @@ public: RkISP1Frames(PipelineHandler *pipe); RkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request, - bool isRaw); + bool isIspBypassed); int destroy(unsigned int frame); void clear(); @@ -232,7 +232,7 @@ private: std::unique_ptr stat_; bool hasSelfPath_; - bool isRaw_; + bool isIspBypassed_; RkISP1MainPath mainPath_; RkISP1SelfPath selfPath_; @@ -257,7 +257,7 @@ RkISP1Frames::RkISP1Frames(PipelineHandler *pipe) } RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request, - bool isRaw) + bool isIspBypassed) { unsigned int frame = data->frame_; @@ -266,7 +266,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req FrameBuffer *mainPathBuffer = nullptr; FrameBuffer *selfPathBuffer = nullptr; - if (!isRaw) { + if (!isIspBypassed) { if (pipe_->availableParamBuffers_.empty()) { LOG(RkISP1, Error) << "Parameters buffer underrun"; return nullptr; @@ -970,8 +970,15 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) Rectangle outputCrop = inputCrop; + /* We cannot convert YUV to bayer, so YUV must be passthrough */ + isIspBypassed_ = info.colourEncoding == PixelFormatInfo::ColourEncodingRAW || + info.colourEncoding == PixelFormatInfo::ColourEncodingYUV; + + LOG(RkISP1, Debug) + << "ISP is " << (isIspBypassed_ ? "in " : "not in ") << "bypass"; + /* YUYV8_2X8 is required on the ISP source path pad for YUV output. */ - if (!isRaw_) + if (!isIspBypassed_) format.code = MEDIA_BUS_FMT_YUYV8_2X8; /* @@ -1047,7 +1054,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) * the isp output to the same size as the sensor output. */ StreamConfiguration ispCfg = cfg; - if (data->usesDewarper_) { + if (data->usesDewarper_ && !isIspBypassed_) { outputCfgs.push_back(const_cast(cfg)); ispCfg.bufferCount = kRkISP1MinBufferCount; @@ -1151,7 +1158,7 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) mainPathBuffers_.clear(); } }; - if (!isRaw_) { + if (!isIspBypassed_) { ret = param_->allocateBuffers(kRkISP1MinBufferCount, ¶mBuffers_); if (ret < 0) return ret; @@ -1248,7 +1255,7 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL data->frame_ = 0; - if (!isRaw_) { + if (!isIspBypassed_) { ret = param_->streamOn(); if (ret) { LOG(RkISP1, Error) @@ -1312,7 +1319,7 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera) selfPath_.stop(); mainPath_.stop(); - if (!isRaw_) { + if (!isIspBypassed_) { ret = stat_->streamOff(); if (ret) LOG(RkISP1, Warning) @@ -1339,12 +1346,12 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request) { RkISP1CameraData *data = cameraData(camera); - RkISP1FrameInfo *info = data->frameInfo_.create(data, request, isRaw_); + RkISP1FrameInfo *info = data->frameInfo_.create(data, request, isIspBypassed_); if (!info) return -ENOENT; data->ipa_->queueRequest(data->frame_, request->controls()); - if (isRaw_) { + if (isIspBypassed_) { if (info->mainPathBuffer) data->mainPath_->queueBuffer(info->mainPathBuffer); @@ -1588,10 +1595,10 @@ void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info) if (request->hasPendingBuffers()) return; - if (!info->metadataProcessed) + if (!isIspBypassed_ && !info->metadataProcessed) return; - if (!isRaw_ && !info->paramDequeued) + if (!isIspBypassed_ && !info->paramDequeued) return; data->frameInfo_.destroy(info->frame); @@ -1646,14 +1653,14 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer) request->metadata().set(controls::SensorTimestamp, metadata.timestamp); - if (isRaw_) { + /* We do not have stats buffers in bypass mode */ + if (!isIspBypassed_) { const ControlList &ctrls = data->delayedCtrls_->get(metadata.sequence); data->ipa_->processStats(info->frame, 0, ctrls); } } else { - if (isRaw_) - info->metadataProcessed = true; + info->metadataProcessed = true; } if (!data->usesDewarper_) { diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index ef9cfbdc3..903e1aaeb 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -238,11 +238,10 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size, if (!rawFormat.isValid()) { LOG(RkISP1, Error) << "Sensor " << sensor->model() - << " doesn't support raw capture"; - return {}; + << " doesn't support raw/bypass capture"; + } else { + format = rawFormat; } - - format = rawFormat; } else { format = formats::NV12; }