From patchwork Wed Feb 21 17:40:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 19523 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 2F625C0F1B for ; Wed, 21 Feb 2024 17:40:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0A5C262819; Wed, 21 Feb 2024 18:40:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="qjE3qpmr"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CAE4A62805 for ; Wed, 21 Feb 2024 18:40:27 +0100 (CET) Received: from localhost.localdomain (unknown [IPv6:2001:b07:5d2e:52c9:cc1e:e404:491f:e6ea]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AA10E720; Wed, 21 Feb 2024 18:40:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1708537219; bh=C9zQWpF2Pk3tAkuTtTdIwy50nUFri2LcYCqo1c4smko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qjE3qpmrYZqmSyAaG5zJsOzxLjIrNqlx+B1mHUfuuTB0NbYvwag5iTJLo5wpnviGS BK5ZyRvMKPWR0KVG0QjoqyJTYZiZIyPCosKzaicg4yoM+jBmzUbMLBIoLiMVOEE12P 8BxcnCUlKFsSrX1kulOpcuQswppAODCpYxEDpqLI= From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Subject: [PATCH 1/5] libcamera: Allow pipeline to provide a Private request Date: Wed, 21 Feb 2024 18:40:09 +0100 Message-ID: <20240221174015.52958-2-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240221174015.52958-1-jacopo.mondi@ideasonboard.com> References: <20240221174015.52958-1-jacopo.mondi@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: , Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In order to allow each pipeline handler to create a Request::Private derived class to store ancillary data associated with a capture request, modify the way a Request is created by the PipelineHandler base class. Introduce a virtual PipelineHandler::createRequestDevice() that pipeline handler implementation can optionally override to provide a custom private data type to initialize the Request with. As we can't anymore create a Request without going through an active camera, drop the queueRequest() checks from the Camera statemachine test. Signed-off-by: Jacopo Mondi Reviewed-by: Daniel Scally Tested-by: Daniel Scally Reviewed-by: Stefan Klug --- include/libcamera/internal/pipeline_handler.h | 5 ++- include/libcamera/request.h | 3 +- src/libcamera/camera.cpp | 8 +--- src/libcamera/pipeline_handler.cpp | 38 ++++++++++++++++--- src/libcamera/request.cpp | 15 +++++--- test/camera/statemachine.cpp | 12 ------ 6 files changed, 50 insertions(+), 31 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index c96944f4ecc4..bbe74f22e5ae 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -21,6 +21,7 @@ #include #include "libcamera/internal/ipa_proxy.h" +#include "libcamera/internal/request.h" namespace libcamera { @@ -59,7 +60,7 @@ public: void stop(Camera *camera); bool hasPendingRequests(const Camera *camera) const; - void registerRequest(Request *request); + std::unique_ptr createRequest(Camera *camera, uint64_t cookie); void queueRequest(Request *request); bool completeBuffer(Request *request, FrameBuffer *buffer); @@ -74,6 +75,8 @@ protected: void registerCamera(std::shared_ptr camera); void hotplugMediaDevice(MediaDevice *media); + virtual std::unique_ptr createRequestDevice(Camera *camera, + uint64_t cookie); virtual int queueRequestDevice(Camera *camera, Request *request) = 0; virtual void stopDevice(Camera *camera) = 0; diff --git a/include/libcamera/request.h b/include/libcamera/request.h index dffde1536cad..e16e61a93873 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -45,9 +45,10 @@ public: using BufferMap = std::map; - Request(Camera *camera, uint64_t cookie = 0); + Request(std::unique_ptr d, uint64_t cookie = 0); ~Request(); + static std::unique_ptr create(std::unique_ptr d, uint64_t); void reuse(ReuseFlag flags = Default); ControlList &controls() { return *controls_; } diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index a71dc933b911..b7053576fe42 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -1236,12 +1236,8 @@ std::unique_ptr Camera::createRequest(uint64_t cookie) if (ret < 0) return nullptr; - std::unique_ptr request = std::make_unique(this, cookie); - - /* Associate the request with the pipeline handler. */ - d->pipe_->registerRequest(request.get()); - - return request; + /* Create a Request from the pipeline handler. */ + return d->pipe_->createRequest(this, cookie); } /** diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 29e0c98a6db5..f2a8cdac0408 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -371,20 +371,25 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const } /** - * \fn PipelineHandler::registerRequest() - * \brief Register a request for use by the pipeline handler - * \param[in] request The request to register + * \fn PipelineHandler::createRequest() + * \brief Create a request and register it for use by the pipeline handler + * \param[in] camera The camera the Request belongs to + * \param[in] cookie The Request unique identifier * - * This function is called when the request is created, and allows the pipeline - * handler to perform any one-time initialization it requries for the request. + * This function is called to create a Request by calling createRequestDevice() + * which can be optionally provided by the PipelineHandler derived classes. */ -void PipelineHandler::registerRequest(Request *request) +std::unique_ptr PipelineHandler::createRequest(Camera *camera, uint64_t cookie) { + std::unique_ptr request = createRequestDevice(camera, cookie); + /* * Connect the request prepared signal to notify the pipeline handler * when a request is ready to be processed. */ request->_d()->prepared.connect(this, &PipelineHandler::doQueueRequests); + + return request; } /** @@ -462,6 +467,27 @@ void PipelineHandler::doQueueRequests() } } +/** + * \brief Create a Request from the pipeline handler + * \param[in] camera The camera the Request belongs to + * \param[in] cookie The Request unique identifier + * + * A virtual function that PipelineHandler derived classes are free to override + * in order to initialize a Request with a custom Request::Private derived + * class. + * + * This is the base class implementation that use Request::Private to + * initialize the Request. + * + * \return A unique pointer to a newly created Request + */ +std::unique_ptr +PipelineHandler::createRequestDevice(Camera *camera, uint64_t cookie) +{ + auto d = std::make_unique(camera); + return Request::create(std::move(d), cookie); +} + /** * \fn PipelineHandler::queueRequestDevice() * \brief Queue a request to the device diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 949c556fa437..d1051ad3d25e 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -336,7 +336,7 @@ void Request::Private::timeout() /** * \brief Create a capture request for a camera - * \param[in] camera The camera that creates the request + * \param[in] d The request private data * \param[in] cookie Opaque cookie for application use * * The \a cookie is stored in the request and is accessible through the @@ -344,12 +344,17 @@ void Request::Private::timeout() * the request to an external resource in the request completion handler, and is * completely opaque to libcamera. */ -Request::Request(Camera *camera, uint64_t cookie) - : Extensible(std::make_unique(camera)), - cookie_(cookie), status_(RequestPending) +std::unique_ptr Request::create(std::unique_ptr d, + uint64_t cookie) +{ + return std::make_unique(std::move(d), cookie); +} + +Request::Request(std::unique_ptr d, uint64_t cookie) + : Extensible(std::move(d)), cookie_(cookie), status_(RequestPending) { controls_ = new ControlList(controls::controls, - camera->_d()->validator()); + _d()->camera()->_d()->validator()); /** * \todo Add a validator for metadata controls. diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index 9c2b0c6a7d99..5714061f88b5 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -38,10 +38,6 @@ protected: if (camera_->start() != -EACCES) return TestFail; - Request request(camera_.get()); - if (camera_->queueRequest(&request) != -EACCES) - return TestFail; - /* Test operations which should pass. */ if (camera_->release()) return TestFail; @@ -68,10 +64,6 @@ protected: if (camera_->start() != -EACCES) return TestFail; - Request request(camera_.get()); - if (camera_->queueRequest(&request) != -EACCES) - return TestFail; - /* Test operations which should pass. */ if (camera_->stop()) return TestFail; @@ -95,10 +87,6 @@ protected: if (camera_->acquire() != -EBUSY) return TestFail; - Request request1(camera_.get()); - if (camera_->queueRequest(&request1) != -EACCES) - return TestFail; - /* Test operations which should pass. */ std::unique_ptr request2 = camera_->createRequest(); if (!request2)