From patchwork Tue Feb 20 16:43:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 19518 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 A1C68C32C3 for ; Tue, 20 Feb 2024 16:43:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 52C906281A; Tue, 20 Feb 2024 17:43:39 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="r+AdyMdM"; 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 A140F6281E for ; Tue, 20 Feb 2024 17:43:26 +0100 (CET) Received: from mail.ideasonboard.com (cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3416E230E; Tue, 20 Feb 2024 17:43:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1708447399; bh=ULueQp8rIcDhjqodhbddJkkr9uqRqkkH+A1iuuLNJk0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r+AdyMdMHcbag+g/7zlFWZV8lH+CWozCDaSyXeICZnBcPgJLWcy+p4okfXbtu1NXN NZGEPgvFu0/O5KobRu48UWvQaG6w6lGL6n+Sxg9it01yClg8h6KBzspkfsyR76NvbR ewtbNfjhGAZvJwO9M7yyZQA7i2d62FAthi7FxPIo= From: Daniel Scally To: libcamera-devel@lists.libcamera.org Subject: [PATCH v2 7/7] libcamera: ipu3: Remove IPU3Frames Date: Tue, 20 Feb 2024 16:43:17 +0000 Message-Id: <20240220164317.998477-8-dan.scally@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240220164317.998477-1-dan.scally@ideasonboard.com> References: <20240220164317.998477-1-dan.scally@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 IPU3Frames class existed to track whether or not a request is ok to complete yet or not - that can now be done through internal buffer tracking within a Request::Private, so switch to that method and drop the dedicated class. Signed-off-by: Daniel Scally --- Changes in v2: - New patch src/libcamera/pipeline/ipu3/cio2.cpp | 3 +- src/libcamera/pipeline/ipu3/cio2.h | 2 +- src/libcamera/pipeline/ipu3/frames.cpp | 143 ----------------- src/libcamera/pipeline/ipu3/frames.h | 67 -------- src/libcamera/pipeline/ipu3/ipu3.cpp | 203 ++++++++++++++---------- src/libcamera/pipeline/ipu3/meson.build | 1 - 6 files changed, 122 insertions(+), 297 deletions(-) delete mode 100644 src/libcamera/pipeline/ipu3/frames.cpp delete mode 100644 src/libcamera/pipeline/ipu3/frames.h diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index 7400cb0b..e0b0d3d1 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -379,7 +379,7 @@ int CIO2Device::stop() return ret; } -FrameBuffer *CIO2Device::queueBuffer(Request *request, FrameBuffer *rawBuffer) +FrameBuffer *CIO2Device::queueBuffer(FrameBuffer *rawBuffer) { FrameBuffer *buffer = rawBuffer; @@ -392,7 +392,6 @@ FrameBuffer *CIO2Device::queueBuffer(Request *request, FrameBuffer *rawBuffer) buffer = availableBuffers_.front(); availableBuffers_.pop(); - buffer->_d()->setRequest(request); } int ret = output_->queueBuffer(buffer); diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h index bbd87eb8..42bb28b7 100644 --- a/src/libcamera/pipeline/ipu3/cio2.h +++ b/src/libcamera/pipeline/ipu3/cio2.h @@ -56,7 +56,7 @@ public: CameraSensor *sensor() { return sensor_.get(); } const CameraSensor *sensor() const { return sensor_.get(); } - FrameBuffer *queueBuffer(Request *request, FrameBuffer *rawBuffer); + FrameBuffer *queueBuffer(FrameBuffer *rawBuffer); void tryReturnBuffer(FrameBuffer *buffer); Signal &bufferReady() { return output_->bufferReady; } Signal &frameStart() { return csi2_->frameStart; } diff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp deleted file mode 100644 index a4c3477c..00000000 --- a/src/libcamera/pipeline/ipu3/frames.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * frames.cpp - Intel IPU3 Frames helper - */ - -#include "frames.h" - -#include -#include - -#include "libcamera/internal/framebuffer.h" -#include "libcamera/internal/pipeline_handler.h" -#include "libcamera/internal/v4l2_videodevice.h" - -namespace libcamera { - -LOG_DECLARE_CATEGORY(IPU3) - -IPU3Frames::IPU3Frames() -{ -} - -void IPU3Frames::init(const std::vector> ¶mBuffers, - const std::vector> &statBuffers) -{ - for (const std::unique_ptr &buffer : paramBuffers) - availableParamBuffers_.push(buffer.get()); - - for (const std::unique_ptr &buffer : statBuffers) - availableStatBuffers_.push(buffer.get()); - - frameInfo_.clear(); -} - -void IPU3Frames::clear() -{ - availableParamBuffers_ = {}; - availableStatBuffers_ = {}; -} - -IPU3Frames::Info *IPU3Frames::create(Request *request) -{ - unsigned int id = request->sequence(); - - if (availableParamBuffers_.empty()) { - LOG(IPU3, Debug) << "Parameters buffer underrun"; - return nullptr; - } - - if (availableStatBuffers_.empty()) { - LOG(IPU3, Debug) << "Statistics buffer underrun"; - return nullptr; - } - - FrameBuffer *paramBuffer = availableParamBuffers_.front(); - FrameBuffer *statBuffer = availableStatBuffers_.front(); - - paramBuffer->_d()->setRequest(request); - statBuffer->_d()->setRequest(request); - - availableParamBuffers_.pop(); - availableStatBuffers_.pop(); - - /* \todo Remove the dynamic allocation of Info */ - std::unique_ptr info = std::make_unique(); - - info->id = id; - info->request = request; - info->rawBuffer = nullptr; - info->paramBuffer = paramBuffer; - info->statBuffer = statBuffer; - info->paramDequeued = false; - info->metadataProcessed = false; - - frameInfo_[id] = std::move(info); - - return frameInfo_[id].get(); -} - -void IPU3Frames::remove(IPU3Frames::Info *info) -{ - /* Return params and stat buffer for reuse. */ - availableParamBuffers_.push(info->paramBuffer); - availableStatBuffers_.push(info->statBuffer); - - /* Delete the extended frame information. */ - frameInfo_.erase(info->id); -} - -bool IPU3Frames::tryComplete(IPU3Frames::Info *info) -{ - Request *request = info->request; - - if (request->hasPendingBuffers()) - return false; - - if (!info->metadataProcessed) - return false; - - if (!info->paramDequeued) - return false; - - remove(info); - - bufferAvailable.emit(); - - return true; -} - -IPU3Frames::Info *IPU3Frames::find(unsigned int id) -{ - const auto &itInfo = frameInfo_.find(id); - - if (itInfo != frameInfo_.end()) - return itInfo->second.get(); - - LOG(IPU3, Fatal) << "Can't find tracking information for frame " << id; - - return nullptr; -} - -IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer) -{ - for (auto const &itInfo : frameInfo_) { - Info *info = itInfo.second.get(); - - for (auto const itBuffers : info->request->buffers()) - if (itBuffers.second == buffer) - return info; - - if (info->rawBuffer == buffer || info->paramBuffer == buffer || - info->statBuffer == buffer) - return info; - } - - LOG(IPU3, Fatal) << "Can't find tracking information from buffer"; - - return nullptr; -} - -} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h deleted file mode 100644 index 6e3cb915..00000000 --- a/src/libcamera/pipeline/ipu3/frames.h +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2020, Google Inc. - * - * frames.h - Intel IPU3 Frames helper - */ - -#pragma once - -#include -#include -#include -#include - -#include - -#include - -namespace libcamera { - -class FrameBuffer; -class IPAProxy; -class PipelineHandler; -class Request; -class V4L2VideoDevice; -struct IPABuffer; - -class IPU3Frames -{ -public: - struct Info { - unsigned int id; - Request *request; - - FrameBuffer *rawBuffer; - FrameBuffer *paramBuffer; - FrameBuffer *statBuffer; - - ControlList effectiveSensorControls; - - bool paramDequeued; - bool metadataProcessed; - }; - - IPU3Frames(); - - void init(const std::vector> ¶mBuffers, - const std::vector> &statBuffers); - void clear(); - - Info *create(Request *request); - void remove(Info *info); - bool tryComplete(Info *info); - - Info *find(unsigned int id); - Info *find(FrameBuffer *buffer); - - Signal<> bufferAvailable; - -private: - std::queue availableParamBuffers_; - std::queue availableStatBuffers_; - - std::map> frameInfo_; -}; - -} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index fa4bd0bb..a8e59dea 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -34,15 +34,17 @@ #include "libcamera/internal/ipa_manager.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" +#include "libcamera/internal/request.h" #include "cio2.h" -#include "frames.h" #include "imgu.h" namespace libcamera { LOG_DEFINE_CATEGORY(IPU3) +using InternalStream = Request::Private::InternalStream; + static const ControlInfoMap::Map IPU3Controls = { { &controls::draft::PipelineDepth, ControlInfo(2, 3) }, }; @@ -58,6 +60,7 @@ public: int loadIPA(); void imguOutputBufferReady(FrameBuffer *buffer); + void imguInputBufferReady(FrameBuffer *buffer); void cio2BufferReady(FrameBuffer *buffer); void paramBufferReady(FrameBuffer *buffer); void statBufferReady(FrameBuffer *buffer); @@ -75,7 +78,6 @@ public: Rectangle cropRegion_; std::unique_ptr delayedCtrls_; - IPU3Frames frameInfos_; std::unique_ptr ipa_; @@ -86,11 +88,14 @@ public: ControlInfoMap ipaControls_; + std::queue availableParamBuffers_; + std::queue availableStatBuffers_; private: void metadataReady(unsigned int id, const ControlList &metadata); void paramsBufferReady(unsigned int id); void setSensorControls(unsigned int id, const ControlList &sensorControls, const ControlList &lensControls); + void tryCompleteRequest(Request *request); }; class IPU3CameraConfiguration : public CameraConfiguration @@ -680,19 +685,17 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera) for (const std::unique_ptr &buffer : imgu->paramBuffers_) { buffer->setCookie(ipaBufferId++); ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + data->availableParamBuffers_.push(buffer.get()); } for (const std::unique_ptr &buffer : imgu->statBuffers_) { buffer->setCookie(ipaBufferId++); ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes()); + data->availableStatBuffers_.push(buffer.get()); } data->ipa_->mapBuffers(ipaBuffers_); - data->frameInfos_.init(imgu->paramBuffers_, imgu->statBuffers_); - data->frameInfos_.bufferAvailable.connect( - data, &IPU3CameraData::queuePendingRequests); - return 0; } @@ -700,7 +703,11 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) { IPU3CameraData *data = cameraData(camera); - data->frameInfos_.clear(); + while (!data->availableStatBuffers_.empty()) + data->availableStatBuffers_.pop(); + + while (!data->availableParamBuffers_.empty()) + data->availableParamBuffers_.pop(); std::vector ids; for (IPABuffer &ipabuf : ipaBuffers_) @@ -792,6 +799,12 @@ void IPU3CameraData::cancelPendingRequests() pipe()->completeBuffer(request, buffer); } + for (auto it : request->_d()->internalBuffers()) { + FrameBuffer *b = it.second; + b->_d()->cancel(); + pipe()->completeBuffer(request, b); + } + pipe()->completeRequest(request); pendingRequests_.pop(); } @@ -802,31 +815,23 @@ void IPU3CameraData::queuePendingRequests() while (!pendingRequests_.empty()) { Request *request = pendingRequests_.front(); - IPU3Frames::Info *info = frameInfos_.create(request); - if (!info) - break; - /* * Queue a buffer on the CIO2, using the raw stream buffer * provided in the request, if any, or a CIO2 internal buffer * otherwise. */ FrameBuffer *reqRawBuffer = request->findBuffer(&rawStream_); - FrameBuffer *rawBuffer = cio2_.queueBuffer(request, reqRawBuffer); + FrameBuffer *rawBuffer = cio2_.queueBuffer(reqRawBuffer); /* * \todo If queueBuffer fails in queuing a buffer to the device, * report the request as error by cancelling the request and * calling PipelineHandler::completeRequest(). */ - if (!rawBuffer) { - frameInfos_.remove(info); + if (!rawBuffer) break; - } - - info->rawBuffer = rawBuffer; - - ipa_->queueRequest(info->id, request->controls()); + request->_d()->addInternalBuffer(InternalStream::Mem2Mem, rawBuffer); + ipa_->queueRequest(request->sequence(), request->controls()); pendingRequests_.pop(); processingRequests_.push(request); } @@ -1120,8 +1125,8 @@ int PipelineHandlerIPU3::registerCameras() &IPU3CameraData::cio2BufferReady); data->cio2_.bufferAvailable.connect( data.get(), &IPU3CameraData::queuePendingRequests); - data->imgu_->input_->bufferReady.connect(&data->cio2_, - &CIO2Device::tryReturnBuffer); + data->imgu_->input_->bufferReady.connect(data.get(), + &IPU3CameraData::imguInputBufferReady); data->imgu_->output_->bufferReady.connect(data.get(), &IPU3CameraData::imguOutputBufferReady); data->imgu_->viewfinder_->bufferReady.connect(data.get(), @@ -1200,6 +1205,17 @@ int IPU3CameraData::loadIPA() return 0; } +void IPU3CameraData::tryCompleteRequest(Request *request) +{ + if (request->hasPendingBuffers()) + return; + + pipe()->completeRequest(request); + + /* Try queue another request now that this one has completed. */ + queuePendingRequests(); +} + void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id, const ControlList &sensorControls, const ControlList &lensControls) @@ -1220,12 +1236,11 @@ void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id, void IPU3CameraData::paramsBufferReady(unsigned int id) { - IPU3Frames::Info *info = frameInfos_.find(id); - if (!info) - return; + Request *request = queuedRequests_[id]; + ASSERT(request); /* Queue all buffers from the request aimed for the ImgU. */ - for (auto it : info->request->buffers()) { + for (auto it : request->buffers()) { const Stream *stream = it.first; FrameBuffer *outbuffer = it.second; @@ -1235,25 +1250,41 @@ void IPU3CameraData::paramsBufferReady(unsigned int id) imgu_->viewfinder_->queueBuffer(outbuffer); } - info->paramBuffer->_d()->metadata().planes()[0].bytesused = + FrameBuffer *paramBuffer = request->_d()->findInternalBuffer(InternalStream::Parameters); + paramBuffer->_d()->metadata().planes()[0].bytesused = sizeof(struct ipu3_uapi_params); - imgu_->param_->queueBuffer(info->paramBuffer); - imgu_->stat_->queueBuffer(info->statBuffer); - imgu_->input_->queueBuffer(info->rawBuffer); + + if (availableStatBuffers_.empty()) { + LOG(IPU3, Error) << "Statistics buffer underrun"; + return; + } + + FrameBuffer *statBuffer = availableStatBuffers_.front(); + availableStatBuffers_.pop(); + request->_d()->addInternalBuffer(InternalStream::Statistics, statBuffer); + + imgu_->param_->queueBuffer(paramBuffer); + imgu_->stat_->queueBuffer(statBuffer); + + FrameBuffer *rawBuffer = request->_d()->findInternalBuffer(InternalStream::Mem2Mem); + ASSERT(rawBuffer); + + imgu_->input_->queueBuffer(rawBuffer); } void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) { - IPU3Frames::Info *info = frameInfos_.find(id); - if (!info) - return; + Request *request = queuedRequests_[id]; + ASSERT(request); + + FrameBuffer *statBuffer = request->_d()->findInternalBuffer(InternalStream::Statistics); + ASSERT(statBuffer); - Request *request = info->request; request->metadata().merge(metadata); + availableStatBuffers_.push(statBuffer); - info->metadataProcessed = true; - if (frameInfos_.tryComplete(info)) - pipe()->completeRequest(request); + pipe()->completeBuffer(request, statBuffer); + tryCompleteRequest(request); } /* ----------------------------------------------------------------------------- @@ -1268,13 +1299,7 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata) */ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) { - IPU3Frames::Info *info = frameInfos_.find(buffer); - if (!info) - return; - - Request *request = info->request; - - pipe()->completeBuffer(request, buffer); + Request *request = buffer->request(); request->metadata().set(controls::draft::PipelineDepth, 3); /* \todo Actually apply the scaler crop region to the ImgU. */ @@ -1283,8 +1308,25 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) cropRegion_ = *scalerCrop; request->metadata().set(controls::ScalerCrop, cropRegion_); - if (frameInfos_.tryComplete(info)) - pipe()->completeRequest(request); + pipe()->completeBuffer(request, buffer); + tryCompleteRequest(request); +} + +void IPU3CameraData::imguInputBufferReady(FrameBuffer *buffer) +{ + Request *request = buffer->request(); + + /* + * If the Request has a Mem2Mem buffer and it's **this** buffer, then + * give it back to the CIO2Device to return it to its internal queue and + * flag it as completed for the purposes of the Request + */ + FrameBuffer *reqBuffer = request->_d()->findInternalBuffer(InternalStream::Mem2Mem); + if (reqBuffer && reqBuffer == buffer) { + pipe()->completeBuffer(request, buffer); + tryCompleteRequest(request); + cio2_.tryReturnBuffer(buffer); + } } /** @@ -1296,11 +1338,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) */ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) { - IPU3Frames::Info *info = frameInfos_.find(buffer); - if (!info) - return; - - Request *request = info->request; + Request *request = buffer->request(); /* If the buffer is cancelled force a complete of the whole request. */ if (buffer->metadata().status == FrameMetadata::FrameCancelled) { @@ -1310,7 +1348,12 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) pipe()->completeBuffer(request, b); } - frameInfos_.remove(info); + for (auto it : request->_d()->internalBuffers()) { + FrameBuffer *b = it.second; + b->_d()->cancel(); + pipe()->completeBuffer(request, b); + } + pipe()->completeRequest(request); return; } @@ -1324,57 +1367,51 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) request->metadata().set(controls::SensorTimestamp, buffer->metadata().timestamp); - info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence); - if (request->findBuffer(&rawStream_)) pipe()->completeBuffer(request, buffer); - ipa_->fillParamsBuffer(info->id, info->paramBuffer->cookie()); + if (availableParamBuffers_.empty()) { + LOG(IPU3, Error) << "Parameters buffer underrun"; + return; + } + + FrameBuffer *paramBuffer = availableParamBuffers_.front(); + availableParamBuffers_.pop(); + request->_d()->addInternalBuffer(InternalStream::Parameters, paramBuffer); + + ipa_->fillParamsBuffer(request->sequence(), paramBuffer->cookie()); } void IPU3CameraData::paramBufferReady(FrameBuffer *buffer) { - IPU3Frames::Info *info = frameInfos_.find(buffer); - if (!info) - return; - - info->paramDequeued = true; + Request *request = buffer->request(); - /* - * tryComplete() will delete info if it completes the IPU3Frame. - * In that event, we must have obtained the Request before hand. - * - * \todo Improve the FrameInfo API to avoid this type of issue - */ - Request *request = info->request; + pipe()->completeBuffer(request, buffer); + tryCompleteRequest(request); - if (frameInfos_.tryComplete(info)) - pipe()->completeRequest(request); + availableParamBuffers_.push(buffer); } void IPU3CameraData::statBufferReady(FrameBuffer *buffer) { - IPU3Frames::Info *info = frameInfos_.find(buffer); - if (!info) - return; - - Request *request = info->request; + Request *request = buffer->request(); if (buffer->metadata().status == FrameMetadata::FrameCancelled) { - info->metadataProcessed = true; - - /* - * tryComplete() will delete info if it completes the IPU3Frame. - * In that event, we must have obtained the Request before hand. - */ - if (frameInfos_.tryComplete(info)) - pipe()->completeRequest(request); + pipe()->completeBuffer(request, buffer); + tryCompleteRequest(request); return; } - ipa_->processStatsBuffer(info->id, request->metadata().get(controls::SensorTimestamp).value_or(0), - info->statBuffer->cookie(), info->effectiveSensorControls); + /* + * We **must** use the sequence reported by the CIO2 when fetching the + * applied sensor controls. + */ + FrameBuffer *rawBuffer = request->_d()->findInternalBuffer(InternalStream::Mem2Mem); + ASSERT(rawBuffer); + + ipa_->processStatsBuffer(request->sequence(), request->metadata().get(controls::SensorTimestamp).value_or(0), + buffer->cookie(), delayedCtrls_->get(rawBuffer->metadata().sequence)); } /* diff --git a/src/libcamera/pipeline/ipu3/meson.build b/src/libcamera/pipeline/ipu3/meson.build index a1b0b31a..d60e07ae 100644 --- a/src/libcamera/pipeline/ipu3/meson.build +++ b/src/libcamera/pipeline/ipu3/meson.build @@ -2,7 +2,6 @@ libcamera_sources += files([ 'cio2.cpp', - 'frames.cpp', 'imgu.cpp', 'ipu3.cpp', ])