From patchwork Fri Aug 5 13:53:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 16976 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 B904FC3275 for ; Fri, 5 Aug 2022 13:53:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7921763330; Fri, 5 Aug 2022 15:53:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1659707603; bh=W6NC1ak50tjRO4caGdKFpzqz8LNPSrx/DA8vaqvBstc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=bBh4tBu5QiFpr4hJPW/RebuRq9/+vK87oUvOZA0bkKRVSglGDBM67oTKfA2swXQ8+ yxbCwlvFRBeouunFDzm3OYL6Xy3/6+AHJYsj+uRogBPkxxPJSKJbpdhAfUFigQhivm okiPuOmSil0yvZemgnCn79MNaEbOWizsI6Bby6bw5xWiJE8Sl+LB8LcyAJK2q6A1tz UUDsVArc4BXFHpQp8SwlVImh5yoyFuUN8kdfWtkAdtanUJPbG+AiT1TTt6sioBlyhw W/j5NHFkwl7XspzjUqN8SN6sqaLKcRaQdniCxctKsQF6dTas/axmhH6eebVmpF3XwU vCcxUBphNWoBA== Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::225]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 32D45603E4 for ; Fri, 5 Aug 2022 15:53:22 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by mail.gandi.net (Postfix) with ESMTPSA id ECAD51C0006; Fri, 5 Aug 2022 13:53:20 +0000 (UTC) To: libcamera-devel@lists.libcamera.org Date: Fri, 5 Aug 2022 15:53:03 +0200 Message-Id: <20220805135312.47497-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220805135312.47497-1-jacopo@jmondi.org> References: <20220805135312.47497-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 01/10] libcamera: request: Add support for error flags 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: , X-Patchwork-Original-From: Jacopo Mondi via libcamera-devel From: Jacopo Mondi Reply-To: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Paul Elder Add error flags to the Request to indicate non-fatal errors. Applications should check the error() state of the Request to determine if any fault occurred while processing the request. Initially, a single error flag ControlError is added to allow a pipeline handler to report a failure to set controls on a hardware device while processing the request. ControlError occurs when a Request was asked to set a control and the pipeline handler attempted to do so, but it was rejected by the kernel. Signed-off-by: Paul Elder Signed-off-by: Kieran Bingham Signed-off-by: Jacopo Mondi Reviewed-by: Umang Jain --- include/libcamera/internal/request.h | 4 ++ include/libcamera/request.h | 9 ++++ src/libcamera/request.cpp | 72 ++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 9dadd6c60361..76cc32f73f9c 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -42,6 +42,8 @@ public: void prepare(std::chrono::milliseconds timeout = 0ms); Signal<> prepared; + void setError(Errors error); + private: friend class PipelineHandler; friend std::ostream &operator<<(std::ostream &out, const Request &r); @@ -59,6 +61,8 @@ private: std::unordered_set pending_; std::map> notifiers_; std::unique_ptr timer_; + + Errors errors_; }; } /* namespace libcamera */ diff --git a/include/libcamera/request.h b/include/libcamera/request.h index dffde1536cad..3304da31200d 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -43,6 +44,13 @@ public: ReuseBuffers = (1 << 0), }; + enum ErrorFlag { + NoError = 0, + ControlError = (1 << 0), + }; + + using Errors = Flags; + using BufferMap = std::map; Request(Camera *camera, uint64_t cookie = 0); @@ -60,6 +68,7 @@ public: uint32_t sequence() const; uint64_t cookie() const { return cookie_; } Status status() const { return status_; } + Errors error() const; bool hasPendingBuffers() const; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index d2af1d2212ad..9a808f19fc03 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -162,6 +162,7 @@ void Request::Private::cancel() */ void Request::Private::reuse() { + errors_ = Request::NoError; sequence_ = 0; cancelled_ = false; prepared_ = false; @@ -284,6 +285,21 @@ void Request::Private::notifierActivated(FrameBuffer *buffer) emitPrepareCompleted(); } +/** + * \brief Update the error flags of the Request + * \param[in] error Error flags to apply on the Request + * + * Flag \a error in the Request which will get reported to the application when + * the Request completes. + * + * Setting an error flag does not cause a Request to fail, and once set it can + * only be cleared by the application destroying the Request or calling reuse(). + */ +void Request::Private::setError(Errors error) +{ + errors_ |= error; +} + void Request::Private::timeout() { /* A timeout can only happen if there are fences not yet signalled. */ @@ -318,6 +334,25 @@ void Request::Private::timeout() * Reuse the buffers that were previously added by addBuffer() */ +/** + * \enum Request::ErrorFlag + * Flags to report errors on a completed request + * + * \var Request::NoError + * No error. The Request completed succesfully and all its buffer contain + * valid data + * + * \var Request::ControlError + * Control Error. At least one control was not applied correctly to the camera. + * The application should compare the metadata to the requested control values + * to check which controls weren't applied. + */ + +/** + * \typedef Request::Errors + * The error state of the request defined by \a Request::ErrorFlag + */ + /** * \typedef Request::BufferMap * \brief A map of Stream to FrameBuffer pointers @@ -552,14 +587,43 @@ uint32_t Request::sequence() const * \brief Retrieve the request completion status * * The request status indicates whether the request has completed successfully - * or with an error. When requests are created and before they complete the - * request status is set to RequestPending, and is updated at completion time - * to RequestComplete. If a request is cancelled at capture stop before it has - * completed, its status is set to RequestCancelled. + * or has been cancelled before being processed. + * + * Requests are created with their status set to RequestPending. When + * a Request is successfully processed and completed by the Camera its + * status is set to RequestComplete. If a Request is cancelled before + * being processed, for example because the Camera has been stopped + * before the request is completed, its status is set to RequestCancelled. + * + * Successfully completed requests can complete with errors. Applications shall + * inspect the error mask returned by Request::error() before accessing buffers + * and data associated with a completed request. * * \return The request completion status */ +/** + * \brief Retrieve the mask of error flags associated with a completed request + * + * The request could complete with errors, which indicate failures in + * completing correctly parts of the request submitted by the application. + * + * The possible failure reasons are defined by the error flags defined + * by Request::ErrorFlag and application are expected to retrieve the + * mask of error flags by using this function before accessing the + * buffers and data associated with a completed request. + * + * Error conditions reported through this function do not change the + * request completion status retrieved through Request::status() which + * indicates if the Request has been processed or not. + * + * \return A mask of error identifier with which the request was completed + */ +Request::Errors Request::error() const +{ + return _d()->errors_; +} + /** * \brief Check if a request has buffers yet to be completed *