From patchwork Wed Apr 17 13:58:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1024 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7F68D60DBF for ; Wed, 17 Apr 2019 15:58:16 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 985064000C; Wed, 17 Apr 2019 13:58:15 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:51 +0200 Message-Id: <20190417135858.23914-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 1/8] libcamera: stream: Make Stream inheritable X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:17 -0000 In preparation for multiple streams support prepare to allow sub-classing the Stream class by removing the 'final' specifier from the class definition and make its private members protected. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- include/libcamera/stream.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index d0f7b0e12485..8a47930f8614 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -43,7 +43,7 @@ private: Size size_; }; -class Stream final +class Stream { public: class StillCapture : public StreamUsage @@ -68,7 +68,7 @@ public: BufferPool &bufferPool() { return bufferPool_; } const StreamConfiguration &configuration() const { return configuration_; } -private: +protected: friend class Camera; BufferPool bufferPool_; From patchwork Wed Apr 17 13:58:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1025 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 78C2360DBF for ; Wed, 17 Apr 2019 15:58:17 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id A20634000F; Wed, 17 Apr 2019 13:58:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:52 +0200 Message-Id: <20190417135858.23914-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 2/8] libcamera: camera: Pass the stream set to allocate/freeBuffers() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:17 -0000 Pipeline handlers might need to perform allocation of internal buffers, setup operations, or simple sanity check before going into the per-stream buffer allocation. As of now, PipelineHandler::allocateBuffers() is called once for each active stream, leaving no space for stream-independent configuration. Change this by providing to the pipeline handlers the full set of active streams, and ask them to loop over them to perform per-streams memory allocations and freeing. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/libcamera/camera.cpp | 15 ++++++--------- src/libcamera/include/pipeline_handler.h | 6 ++++-- src/libcamera/pipeline/ipu3/ipu3.cpp | 13 +++++++++---- src/libcamera/pipeline/uvcvideo.cpp | 13 +++++++++---- src/libcamera/pipeline/vimc.cpp | 13 +++++++++---- src/libcamera/pipeline_handler.cpp | 11 ++++++----- 6 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index bdf14b31d8ee..21caa24b90b5 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -647,13 +647,11 @@ int Camera::allocateBuffers() return -EINVAL; } - for (Stream *stream : activeStreams_) { - int ret = pipe_->allocateBuffers(this, stream); - if (ret) { - LOG(Camera, Error) << "Failed to allocate buffers"; - freeBuffers(); - return ret; - } + int ret = pipe_->allocateBuffers(this, activeStreams_); + if (ret) { + LOG(Camera, Error) << "Failed to allocate buffers"; + freeBuffers(); + return ret; } state_ = CameraPrepared; @@ -683,12 +681,11 @@ int Camera::freeBuffers() * by the V4L2 device that has allocated them. */ stream->bufferPool().destroyBuffers(); - pipe_->freeBuffers(this, stream); } state_ = CameraConfigured; - return 0; + return pipe_->freeBuffers(this, activeStreams_); } /** diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h index 33b820e706cc..a0862ebf35df 100644 --- a/src/libcamera/include/pipeline_handler.h +++ b/src/libcamera/include/pipeline_handler.h @@ -58,8 +58,10 @@ public: streamConfiguration(Camera *camera, const std::vector &usages) = 0; virtual int configureStreams(Camera *camera, const CameraConfiguration &config) = 0; - virtual int allocateBuffers(Camera *camera, Stream *stream) = 0; - virtual int freeBuffers(Camera *camera, Stream *stream) = 0; + virtual int allocateBuffers(Camera *camera, + const std::set &streams) = 0; + virtual int freeBuffers(Camera *camera, + const std::set &streams) = 0; virtual int start(Camera *camera) = 0; virtual void stop(Camera *camera); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index ca09da753b90..f96e8763bce9 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -145,8 +145,10 @@ public: int configureStreams(Camera *camera, const CameraConfiguration &config) override; - int allocateBuffers(Camera *camera, Stream *stream) override; - int freeBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, + const std::set &streams) override; + int freeBuffers(Camera *camera, + const std::set &streams) override; int start(Camera *camera) override; void stop(Camera *camera) override; @@ -305,9 +307,11 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, return 0; } -int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) +int PipelineHandlerIPU3::allocateBuffers(Camera *camera, + const std::set &streams) { IPU3CameraData *data = cameraData(camera); + Stream *stream = *streams.begin(); CIO2Device *cio2 = &data->cio2_; ImgUDevice *imgu = data->imgu_; int ret; @@ -346,7 +350,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream) return 0; } -int PipelineHandlerIPU3::freeBuffers(Camera *camera, Stream *stream) +int PipelineHandlerIPU3::freeBuffers(Camera *camera, + const std::set &streams) { IPU3CameraData *data = cameraData(camera); diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp index cd472cfadd86..b8f634d88b46 100644 --- a/src/libcamera/pipeline/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo.cpp @@ -32,8 +32,10 @@ public: int configureStreams(Camera *camera, const CameraConfiguration &config) override; - int allocateBuffers(Camera *camera, Stream *stream) override; - int freeBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, + const std::set &streams) override; + int freeBuffers(Camera *camera, + const std::set &streams) override; int start(Camera *camera) override; void stop(Camera *camera) override; @@ -127,9 +129,11 @@ int PipelineHandlerUVC::configureStreams(Camera *camera, return 0; } -int PipelineHandlerUVC::allocateBuffers(Camera *camera, Stream *stream) +int PipelineHandlerUVC::allocateBuffers(Camera *camera, + const std::set &streams) { UVCCameraData *data = cameraData(camera); + Stream *stream = *streams.begin(); const StreamConfiguration &cfg = stream->configuration(); LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers"; @@ -137,7 +141,8 @@ int PipelineHandlerUVC::allocateBuffers(Camera *camera, Stream *stream) return data->video_->exportBuffers(&stream->bufferPool()); } -int PipelineHandlerUVC::freeBuffers(Camera *camera, Stream *stream) +int PipelineHandlerUVC::freeBuffers(Camera *camera, + const std::set &streams) { UVCCameraData *data = cameraData(camera); return data->video_->releaseBuffers(); diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp index c8bbe2a19847..22449e47bc2d 100644 --- a/src/libcamera/pipeline/vimc.cpp +++ b/src/libcamera/pipeline/vimc.cpp @@ -32,8 +32,10 @@ public: int configureStreams(Camera *camera, const CameraConfiguration &config) override; - int allocateBuffers(Camera *camera, Stream *stream) override; - int freeBuffers(Camera *camera, Stream *stream) override; + int allocateBuffers(Camera *camera, + const std::set &streams) override; + int freeBuffers(Camera *camera, + const std::set &streams) override; int start(Camera *camera) override; void stop(Camera *camera) override; @@ -127,9 +129,11 @@ int PipelineHandlerVimc::configureStreams(Camera *camera, return 0; } -int PipelineHandlerVimc::allocateBuffers(Camera *camera, Stream *stream) +int PipelineHandlerVimc::allocateBuffers(Camera *camera, + const std::set &streams) { VimcCameraData *data = cameraData(camera); + Stream *stream = *streams.begin(); const StreamConfiguration &cfg = stream->configuration(); LOG(VIMC, Debug) << "Requesting " << cfg.bufferCount << " buffers"; @@ -137,7 +141,8 @@ int PipelineHandlerVimc::allocateBuffers(Camera *camera, Stream *stream) return data->video_->exportBuffers(&stream->bufferPool()); } -int PipelineHandlerVimc::freeBuffers(Camera *camera, Stream *stream) +int PipelineHandlerVimc::freeBuffers(Camera *camera, + const std::set &streams) { VimcCameraData *data = cameraData(camera); return data->video_->releaseBuffers(); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 43550c0e0210..911d08448e69 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -193,10 +193,11 @@ PipelineHandler::~PipelineHandler() * \fn PipelineHandler::allocateBuffers() * \brief Allocate buffers for a stream * \param[in] camera The camera the \a stream belongs to - * \param[in] stream The stream to allocate buffers for + * \param[in] streams The set of streams to allocate buffers for * - * This method allocates buffers internally in the pipeline handler and - * associates them with the stream's buffer pool. + * This method allocates buffers internally in the pipeline handler for each + * stream in the \a streams buffer set, and associates them with the stream's + * buffer pool. * * The intended caller of this method is the Camera class. * @@ -207,9 +208,9 @@ PipelineHandler::~PipelineHandler() * \fn PipelineHandler::freeBuffers() * \brief Free all buffers associated with a stream * \param[in] camera The camera the \a stream belongs to - * \param[in] stream The stream to free buffers from + * \param[in] streams The set of streams to free buffers from * - * After a capture session has been stopped all buffers associated with the + * After a capture session has been stopped all buffers associated with each * stream shall be freed. * * The intended caller of this method is the Camera class. From patchwork Wed Apr 17 13:58:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1026 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1694E60DC3 for ; Wed, 17 Apr 2019 15:58:18 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 9E53440017; Wed, 17 Apr 2019 13:58:17 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:53 +0200 Message-Id: <20190417135858.23914-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 3/8] libcamera: camera: Don't call freeBuffer() on allocateBuffer() error X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:18 -0000 Do not assume the freeBuffer() function can handle allocateBuffer() method failures, as error handling and clean up should be performed by allocateBuffer() method itself. Perform clean-up on allocations failures in the IPU3 pipeline handler, now that freeBuffers() is not called anymore. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/camera.cpp | 1 - src/libcamera/pipeline/ipu3/ipu3.cpp | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 21caa24b90b5..2d0a80664214 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -650,7 +650,6 @@ int Camera::allocateBuffers() int ret = pipe_->allocateBuffers(this, activeStreams_); if (ret) { LOG(Camera, Error) << "Failed to allocate buffers"; - freeBuffers(); return ret; } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f96e8763bce9..6e093fc22259 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -314,6 +314,7 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream = *streams.begin(); CIO2Device *cio2 = &data->cio2_; ImgUDevice *imgu = data->imgu_; + unsigned int bufferCount; int ret; /* Share buffers between CIO2 output and ImgU input. */ @@ -323,31 +324,39 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, ret = imgu->importBuffers(pool); if (ret) - return ret; + goto error_free_cio2; /* Export ImgU output buffers to the stream's pool. */ ret = imgu->exportBuffers(&imgu->output_, &stream->bufferPool()); if (ret) - return ret; + goto error_free_imgu; /* * Reserve memory in viewfinder and stat output devices. Use the * same number of buffers as the ones requested for the output * stream. */ - unsigned int bufferCount = stream->bufferPool().count(); + bufferCount = stream->bufferPool().count(); imgu->viewfinder_.pool->createBuffers(bufferCount); ret = imgu->exportBuffers(&imgu->viewfinder_, imgu->viewfinder_.pool); if (ret) - return ret; + goto error_free_imgu; imgu->stat_.pool->createBuffers(bufferCount); ret = imgu->exportBuffers(&imgu->stat_, imgu->stat_.pool); if (ret) - return ret; + goto error_free_imgu; return 0; + +error_free_imgu: + imgu->freeBuffers(); + +error_free_cio2: + cio2->freeBuffers(); + + return ret; } int PipelineHandlerIPU3::freeBuffers(Camera *camera, From patchwork Wed Apr 17 13:58:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1027 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AACD560DC5 for ; Wed, 17 Apr 2019 15:58:18 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 3B26340004; Wed, 17 Apr 2019 13:58:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:54 +0200 Message-Id: <20190417135858.23914-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 4/8] libcamera: v4l2_device: Propagate releaseBuffers() error X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:19 -0000 The error code returned by requestBuffers(0) was not propagated to the caller. Fix it. Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/v4l2_device.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 4cc4a6d656b1..d394632dad4c 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -737,10 +737,9 @@ int V4L2Device::releaseBuffers() { LOG(V4L2, Debug) << "Releasing bufferPool"; - requestBuffers(0); bufferPool_ = nullptr; - return 0; + return requestBuffers(0); } /** From patchwork Wed Apr 17 13:58:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1028 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AD59F60DBF for ; Wed, 17 Apr 2019 15:58:19 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id D119D40002; Wed, 17 Apr 2019 13:58:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:55 +0200 Message-Id: <20190417135858.23914-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 5/8] libcamera: request: Add hasPendingBuffers() method X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:19 -0000 Add method to verify if a request has pending buffers yet to be completed. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- include/libcamera/request.h | 2 ++ src/libcamera/request.cpp | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 0dbd425115e8..0188bcab8383 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -37,6 +37,8 @@ public: Status status() const { return status_; } + bool hasPendingBuffers() const { return !pending_.empty(); } + private: friend class Camera; friend class PipelineHandler; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index e0e77e972411..e5c25d2c6988 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -106,6 +106,14 @@ Buffer *Request::findBuffer(Stream *stream) const * \return The request completion status */ +/** + * \fn Request::hasPendingBuffers() + * \brief Check if a request has buffers yet to be completed + * + * \return True if the request has buffers pending for completion, false + * otherwise + */ + /** * \brief Prepare the resources for the completion handler */ @@ -127,7 +135,7 @@ int Request::prepare() */ void Request::complete(Status status) { - ASSERT(pending_.empty()); + ASSERT(!hasPendingBuffers()); status_ = status; } @@ -149,7 +157,7 @@ bool Request::completeBuffer(Buffer *buffer) int ret = pending_.erase(buffer); ASSERT(ret == 1); - return pending_.empty(); + return !hasPendingBuffers(); } } /* namespace libcamera */ From patchwork Wed Apr 17 13:58:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1029 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4EDF460DBF for ; Wed, 17 Apr 2019 15:58:20 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id D2F9940004; Wed, 17 Apr 2019 13:58:19 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:56 +0200 Message-Id: <20190417135858.23914-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 6/8] libcamera: camera: Validate Request before queueing it X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:20 -0000 Extend the Request::prepare() operation to validate the request before preparing it. Return an error if the request is invalid, which for now is limited to ensuring that the request contains at least one buffer. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/camera.cpp | 11 ++++++++--- src/libcamera/request.cpp | 12 +++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 2d0a80664214..75a21008070b 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -713,9 +713,14 @@ Request *Camera::createRequest() * \brief Queue a request to the camera * \param[in] request The request to queue to the camera * - * This method queues a \a request allocated with createRequest() to the camera - * for capture. Once the request has been queued, the camera will notify its - * completion through the \ref requestCompleted signal. + * This method queues a \a request to the camera for capture. + * + * After allocating the request with createRequest(), the application shall + * fill it with at least one capture buffer before queuing it. Requests that + * contain no buffers are invalid and are rejected without being queued. + * + * Once the request has been queued, the camera will notify its completion + * through the \ref requestCompleted signal. * * Ownership of the request is transferred to the camera. It will be deleted * automatically after it completes. diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index e5c25d2c6988..9fc8c6845578 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -115,10 +115,20 @@ Buffer *Request::findBuffer(Stream *stream) const */ /** - * \brief Prepare the resources for the completion handler + * \brief Validate the request and prepare it for the completion handler + * + * Requests that contain no buffers are invalid and are rejected. + * + * \return 0 on success or a negative error code otherwise + * \retval -EINVAL The request is invalid */ int Request::prepare() { + if (!hasPendingBuffers()) { + LOG(Request, Error) << "Invalid request due to missing buffers"; + return -EINVAL; + } + for (auto const &pair : bufferMap_) { Buffer *buffer = pair.second; pending_.insert(buffer); From patchwork Wed Apr 17 13:58:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1030 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 72A8460DCD for ; Wed, 17 Apr 2019 15:58:21 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 7D27640004; Wed, 17 Apr 2019 13:58:20 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:57 +0200 Message-Id: <20190417135858.23914-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 7/8] libcamera: request: Expose the Stream to Buffers map X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:22 -0000 Add to the Request class a method to access the map of Stream to Buffer. With the introduction of multiple stream support, pipeline handler should be able to access the map of streams at request queueing time. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- include/libcamera/request.h | 1 + src/libcamera/request.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 0188bcab8383..58de6f00a554 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -32,6 +32,7 @@ public: Request(const Request &) = delete; Request &operator=(const Request &) = delete; + const std::map &buffers() const { return bufferMap_; } int setBuffers(const std::map &streamMap); Buffer *findBuffer(Stream *stream) const; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 9fc8c6845578..b215366baa7c 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -51,6 +51,16 @@ Request::Request(Camera *camera) { } +/** + * \fn Request::buffers() + * \brief Retrieve the request's streams to buffers map + * + * Return a reference to the map that associates each Stream part of the + * request to the Buffer the Stream output should be directed to. + * + * \return The map of Stream to Buffer + */ + /** * \brief Set the streams to capture with associated buffers * \param[in] streamMap The map of streams to buffers From patchwork Wed Apr 17 13:58:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 1031 Return-Path: Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0B97A60DCF for ; Wed, 17 Apr 2019 15:58:22 +0200 (CEST) X-Originating-IP: 2.224.242.101 Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 8D48140017; Wed, 17 Apr 2019 13:58:21 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 15:58:58 +0200 Message-Id: <20190417135858.23914-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190417135858.23914-1-jacopo@jmondi.org> References: <20190417135858.23914-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 8/8] libcamera: buffer: Store Request reference in Buffer X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Apr 2019 13:58:22 -0000 Add to the Buffer class methods to set and retrieve a reference to the Request instance the buffer is part of. As buffers might outlive the Request they are associated with, the reference is only temporary valid during the buffer completion interval (from when the buffer gets queued to Camera for processing, until it gets marked as completed). Signed-off-by: Jacopo Mondi Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- include/libcamera/buffer.h | 6 ++++++ src/libcamera/buffer.cpp | 25 ++++++++++++++++++++++++- src/libcamera/request.cpp | 3 +++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 0c844d126a27..8f9b42e39339 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -13,6 +13,7 @@ namespace libcamera { class BufferPool; +class Request; class Plane final { @@ -52,14 +53,18 @@ public: unsigned int sequence() const { return sequence_; } Status status() const { return status_; } std::vector &planes() { return planes_; } + Request *request() const { return request_; } private: friend class BufferPool; friend class PipelineHandler; + friend class Request; friend class V4L2Device; void cancel(); + void setRequest(Request *request) { request_ = request; } + unsigned int index_; unsigned int bytesused_; uint64_t timestamp_; @@ -67,6 +72,7 @@ private: Status status_; std::vector planes_; + Request *request_; }; class BufferPool final diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index e2d1cf04411e..8261ca41d62e 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -196,7 +196,7 @@ void *Plane::mem() */ Buffer::Buffer() - : index_(-1) + : index_(-1), request_(nullptr) { } @@ -248,6 +248,22 @@ Buffer::Buffer() * \return The buffer status */ +/** + * \fn Buffer::request() + * \brief Retrieve the request this buffer belongs to + * + * The intended callers of this method are buffer completion handlers that + * needs to associate a buffer to the request it belongs to. + * + * A Buffer is associated to a request by Request::prepare() and the + * association is valid until the buffer completes. The returned request + * pointer is valid only during that interval. + * + * \return The Request the Buffer belongs to, or nullptr if the buffer is + * either completed or not associated with a request + * \sa Buffer::setRequest() + */ + /** * \brief Mark a buffer as cancel by setting its status to BufferCancelled */ @@ -259,6 +275,13 @@ void Buffer::cancel() status_ = BufferCancelled; } +/** + * \fn Buffer::setRequest() + * \brief Set the request this buffer belongs to + * + * The intended callers are Request::prepare() and Request::completeBuffer(). + */ + /** * \class BufferPool * \brief A pool of buffers diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index b215366baa7c..290175f876b4 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -141,6 +141,7 @@ int Request::prepare() for (auto const &pair : bufferMap_) { Buffer *buffer = pair.second; + buffer->setRequest(this); pending_.insert(buffer); } @@ -177,6 +178,8 @@ bool Request::completeBuffer(Buffer *buffer) int ret = pending_.erase(buffer); ASSERT(ret == 1); + buffer->setRequest(nullptr); + return !hasPendingBuffers(); }