From patchwork Wed Mar 25 15:14:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 26372 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 BED8EC32FA for ; Wed, 25 Mar 2026 15:16:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 68C0462CDF; Wed, 25 Mar 2026 16:16:06 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HLH0ourw"; 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 96C0062CDA for ; Wed, 25 Mar 2026 16:16:05 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:b16a:5ed9:4ada:a95a]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 9609D1AFB; Wed, 25 Mar 2026 16:14:47 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1774451687; bh=Iy4AqolszNI6X5zcfVsnGNJIhlZ4gPoEIOTgX2W+sfE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HLH0ourwxUzJU+61e/jEYXX7CwuUiZ+9eZwf7v+PLsM/bb2Uk8ZmYu5VK6Kvrvd2r UkbOcKcOXwc7XTlQ2SIQnyPWLV45pwC5s3B0H+zJCEaKajwDvokugD9PMjutQBn4cY Ybkbq/jKCoeWK9pUUm45lUNhD0x7H6UQke8fOYwY= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v2 30/32] pipeline: rkisp1: rkisp1_path: Modify interface to be compatible with BufferQueue Date: Wed, 25 Mar 2026 16:14:02 +0100 Message-ID: <20260325151416.2114564-31-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260325151416.2114564-1-stefan.klug@ideasonboard.com> References: <20260325151416.2114564-1-stefan.klug@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" The BufferQueue delegate expects an interface equal to the one provided by the V4L2VideoDevice. Modify the RkISP1Path class to support that interface to prepare for the migration to BufferQueue. Signed-off-by: Stefan Klug --- Changes in v2: - Added this patch --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 44 ++++++++++++++----- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 42 ++---------------- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 23 ++++++++-- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index c46515110ffc..998ee3c813bc 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1099,14 +1099,15 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) { RkISP1CameraData *data = cameraData(camera); + utils::ScopeExitActions actions; unsigned int ipaBufferId = 1; int ret; - auto errorCleanup = utils::scope_exit{ [&]() { + actions += [&]() { paramBuffers_.clear(); statBuffers_.clear(); mainPathBuffers_.clear(); - } }; + }; if (!isRaw_) { ret = param_->allocateBuffers(kRkISP1InternalBufferCount, ¶mBuffers_); @@ -1127,6 +1128,22 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) for (std::unique_ptr &buffer : mainPathBuffers_) availableMainPathBuffers_.push(buffer.get()); + } else if (data->mainPath_->isEnabled()) { + ret = mainPath_.importBuffers(data->mainPathStream_.configuration().bufferCount); + + if (ret < 0) + return ret; + + actions += [&]() { mainPath_.releaseBuffers(); }; + } + + if (hasSelfPath_ && data->selfPath_->isEnabled()) { + ret = selfPath_.importBuffers(data->selfPathStream_.configuration().bufferCount); + + if (ret < 0) + return ret; + + actions += [&]() { selfPath_.releaseBuffers(); }; } auto pushBuffers = [&](const std::vector> &buffers, @@ -1147,7 +1164,7 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) data->ipa_->mapBuffers(data->ipaBuffers_); - errorCleanup.release(); + actions.release(); return 0; } @@ -1181,6 +1198,12 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) if (stat_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release stat buffers"; + if (mainPath_.releaseBuffers()) + LOG(RkISP1, Error) << "Failed to release main path buffers"; + + if (hasSelfPath_ && selfPath_.releaseBuffers()) + LOG(RkISP1, Error) << "Failed to release self path buffers"; + return 0; } @@ -1263,16 +1286,17 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL } if (data->mainPath_->isEnabled()) { - ret = mainPath_.start(data->mainPathStream_.configuration().bufferCount); + ret = mainPath_.streamOn(); if (ret) return ret; - actions += [&]() { mainPath_.stop(); }; + actions += [&]() { mainPath_.streamOff(); }; } if (hasSelfPath_ && data->selfPath_->isEnabled()) { - ret = selfPath_.start(data->selfPathStream_.configuration().bufferCount); + ret = selfPath_.streamOn(); if (ret) return ret; + actions += [&]() { selfPath_.streamOff(); }; } isp_->setFrameStartEnabled(true); @@ -1299,8 +1323,8 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera) data->ipa_->stop(); if (hasSelfPath_) - selfPath_.stop(); - mainPath_.stop(); + selfPath_.streamOff(); + mainPath_.streamOff(); if (!isRaw_) { ret = stat_->streamOff(); @@ -1664,9 +1688,9 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) return false; isp_->frameStart.connect(this, &PipelineHandlerRkISP1::frameStart); - mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::imageBufferReady); + mainPath_.bufferReady.connect(this, &PipelineHandlerRkISP1::imageBufferReady); if (hasSelfPath_) - selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::imageBufferReady); + selfPath_.bufferReady.connect(this, &PipelineHandlerRkISP1::imageBufferReady); stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statBufferReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramBufferReady); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index ef9cfbdc327a..80a01280e6f7 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -8,6 +8,7 @@ #include "rkisp1_path.h" #include +#include #include @@ -58,7 +59,7 @@ const std::map formatToMediaBus = { RkISP1Path::RkISP1Path(const char *name, const Span &formats, const Size &minResolution, const Size &maxResolution) - : name_(name), running_(false), formats_(formats), + : name_(name), formats_(formats), minResolution_(minResolution), maxResolution_(maxResolution), link_(nullptr) { @@ -77,6 +78,7 @@ bool RkISP1Path::init(std::shared_ptr media) if (video_->open() < 0) return false; + video_->bufferReady.connect(this, [this](FrameBuffer *buffer) { this->bufferReady.emit(buffer); }); populateFormats(); link_ = media->link("rkisp1_isp", 2, resizer, 0); @@ -480,44 +482,6 @@ int RkISP1Path::configure(const StreamConfiguration &config, return 0; } -int RkISP1Path::start(unsigned int bufferCount) -{ - int ret; - - if (running_) - return -EBUSY; - - ret = video_->importBuffers(bufferCount); - if (ret) - return ret; - - ret = video_->streamOn(); - if (ret) { - LOG(RkISP1, Error) - << "Failed to start " << name_ << " path"; - - video_->releaseBuffers(); - return ret; - } - - running_ = true; - - return 0; -} - -void RkISP1Path::stop() -{ - if (!running_) - return; - - if (video_->streamOff()) - LOG(RkISP1, Warning) << "Failed to stop " << name_ << " path"; - - video_->releaseBuffers(); - - running_ = false; -} - /* * \todo Remove the hardcoded resolutions and formats once kernels older than * v6.4 will stop receiving LTS support (scheduled for December 2027 for v6.1). diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 0c68e9eb99af..d2bce01c9336 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -58,19 +58,34 @@ public: return video_->exportBuffers(bufferCount, buffers); } - int start(unsigned int bufferCount); - void stop(); + int allocateBuffers(unsigned int bufferCount, + std::vector> *buffers) + { + return video_->allocateBuffers(bufferCount, buffers); + } + + int importBuffers(unsigned int count) + { + return video_->importBuffers(count); + } + + int releaseBuffers() + { + return video_->releaseBuffers(); + } + + int streamOn() { return video_->streamOn(); }; + int streamOff() { return video_->streamOff(); }; int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); } - Signal &bufferReady() { return video_->bufferReady; } const Size &maxResolution() const { return maxResolution_; } + Signal bufferReady; private: void populateFormats(); Size filterSensorResolution(const CameraSensor *sensor); const char *name_; - bool running_; const Span formats_; std::set streamFormats_;