[{"id":20406,"web_url":"https://patchwork.libcamera.org/comment/20406/","msgid":"<YXY7jhyn85hnGZ2q@pendragon.ideasonboard.com>","date":"2021-10-25T05:07:26","subject":"Re: [libcamera-devel] [PATCH v6 3/7] android: camera_device:\n\tRefactor descriptor status and sendCaptureResults()","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Umang,\n\nThank you for the patch.\n\nOn Sat, Oct 23, 2021 at 04:02:58PM +0530, Umang Jain wrote:\n> Currently, we use Camera3RequestDescriptor::Status to determine:\n> - When the descriptor has been completely processed by HAL\n> - Whether any errors were encountered, during its processing\n> \n> Both of these are essential to know whether the descriptor is eligible\n> to call process_capture_results() through sendCaptureResults().\n> When a status(Success/Error) is set on the descriptor, it is ready to\n> be sent back via sendCaptureResults(). However, this might lead to\n> undesired results especially when sendCaptureResults() runs in a\n> different thread (for e.g. stream's post-processor async completion\n> slot).\n> \n> This patch decouples the descriptor status (Success/Error) from the\n> descriptor's completion status (pending or complete). The advantage\n> of this is we can set the completion status when the descriptor has\n> been processed fully by the layer and we can set the error status on\n> the descriptor wherever an error is encountered, throughout the\n> lifetime descriptor in the HAL layer.\n> \n> While at it, introduce a wrapper completeDescriptor() around\n> sendCaptureResults(). completeDescriptor() as the name suggests will\n> mark the descriptor as complete, so it is ready to be sent back.\n> The locking mechanism is moved from sendCaptureResults() to this wrapper\n> since the intention is to use completeDescriptor() in place of existing\n> sendCaptureResults() calls.\n> \n> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>\n> ---\n>  src/android/camera_device.cpp  | 33 ++++++++++++++++++---------------\n>  src/android/camera_device.h    |  1 +\n>  src/android/camera_request.cpp |  2 +-\n>  src/android/camera_request.h   |  7 ++++---\n>  4 files changed, 24 insertions(+), 19 deletions(-)\n> \n> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> index 806b4090..f4d4fb09 100644\n> --- a/src/android/camera_device.cpp\n> +++ b/src/android/camera_device.cpp\n> @@ -982,13 +982,13 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n>  \tMutexLocker stateLock(stateMutex_);\n>  \n>  \tif (state_ == State::Flushing) {\n> -\t\tabortRequest(descriptor.get());\n> +\t\tCamera3RequestDescriptor *rawDescriptor = descriptor.get();\n> +\t\tabortRequest(rawDescriptor);\n\nCould we move the abortRequest() call just before completeDescriptor(),\nto always operate with the descriptor already added to the queue ? It\nshould make no difference today, but consistent call patterns will make\nit easier to understand the code and the possible race conditions.\n\n>  \t\t{\n>  \t\t\tMutexLocker descriptorsLock(descriptorsMutex_);\n>  \t\t\tdescriptors_.push(std::move(descriptor));\n>  \t\t}\n> -\n> -\t\tsendCaptureResults();\n> +\t\tcompleteDescriptor(rawDescriptor);\n>  \n>  \t\treturn 0;\n>  \t}\n> @@ -1079,7 +1079,7 @@ void CameraDevice::requestComplete(Request *request)\n>  \t\t\t\t<< request->status();\n>  \n>  \t\tabortRequest(descriptor);\n> -\t\tsendCaptureResults();\n> +\t\tcompleteDescriptor(descriptor);\n>  \n>  \t\treturn;\n>  \t}\n> @@ -1117,6 +1117,7 @@ void CameraDevice::requestComplete(Request *request)\n>  \t}\n>  \n>  \t/* Handle post-processing. */\n> +\tbool hasPostProcessingErrors = false;\n>  \tfor (auto &buffer : descriptor->buffers_) {\n>  \t\tCameraStream *stream = buffer.stream;\n>  \n> @@ -1129,6 +1130,7 @@ void CameraDevice::requestComplete(Request *request)\n>  \t\t\tbuffer.status = Camera3RequestDescriptor::Status::Error;\n>  \t\t\tnotifyError(descriptor->frameNumber_, stream->camera3Stream(),\n>  \t\t\t\t    CAMERA3_MSG_ERROR_BUFFER);\n> +\t\t\thasPostProcessingErrors = true;\n\nYou can set\n\n\t\t\tdescriptor->status_ = Camera3RequestDescriptor::Status::Error;\n\nhere.\n\n>  \t\t\tcontinue;\n>  \t\t}\n>  \n> @@ -1143,29 +1145,32 @@ void CameraDevice::requestComplete(Request *request)\n>  \n>  \t\tif (ret) {\n>  \t\t\tbuffer.status = Camera3RequestDescriptor::Status::Error;\n> +\t\t\thasPostProcessingErrors = true;\n\nAnd here too.\n\n>  \t\t\tnotifyError(descriptor->frameNumber_, stream->camera3Stream(),\n>  \t\t\t\t    CAMERA3_MSG_ERROR_BUFFER);\n>  \t\t}\n>  \t}\n>  \n> -\tdescriptor->status_ = Camera3RequestDescriptor::Status::Success;\n> +\tif (hasPostProcessingErrors)\n> +\t\tdescriptor->status_ = Camera3RequestDescriptor::Status::Error;\n\nAnd then drop this.\n\n> +\n> +\tcompleteDescriptor(descriptor);\n> +}\n> +\n> +void CameraDevice::completeDescriptor(Camera3RequestDescriptor *descriptor)\n> +{\n> +\tMutexLocker lock(descriptorsMutex_);\n> +\tdescriptor->completeDescriptor();\n> +\n>  \tsendCaptureResults();\n>  }\n>  \n>  void CameraDevice::sendCaptureResults()\n>  {\n> -\tMutexLocker lock(descriptorsMutex_);\n>  \twhile (!descriptors_.empty() && !descriptors_.front()->isPending()) {\n>  \t\tauto descriptor = std::move(descriptors_.front());\n>  \t\tdescriptors_.pop();\n>  \n> -\t\t/*\n> -\t\t * \\todo Releasing and re-acquiring the critical section for\n> -\t\t * every request completion (grain-locking) might have an\n> -\t\t * impact on performance which should be measured.\n> -\t\t */\n> -\t\tlock.unlock();\n> -\n>  \t\tcamera3_capture_result_t captureResult = {};\n>  \n>  \t\tcaptureResult.frame_number = descriptor->frameNumber_;\n> @@ -1201,8 +1206,6 @@ void CameraDevice::sendCaptureResults()\n>  \t\t\tcaptureResult.partial_result = 1;\n>  \n>  \t\tcallbacks_->process_capture_result(callbacks_, &captureResult);\n> -\n> -\t\tlock.lock();\n>  \t}\n>  }\n>  \n> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> index 863cf414..e544f2bd 100644\n> --- a/src/android/camera_device.h\n> +++ b/src/android/camera_device.h\n> @@ -93,6 +93,7 @@ private:\n>  \tvoid notifyError(uint32_t frameNumber, camera3_stream_t *stream,\n>  \t\t\t camera3_error_msg_code code) const;\n>  \tint processControls(Camera3RequestDescriptor *descriptor);\n> +\tvoid completeDescriptor(Camera3RequestDescriptor *descriptor);\n>  \tvoid sendCaptureResults();\n>  \tstd::unique_ptr<CameraMetadata> getResultMetadata(\n>  \t\tconst Camera3RequestDescriptor &descriptor) const;\n> diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp\n> index faa85ada..16cf266f 100644\n> --- a/src/android/camera_request.cpp\n> +++ b/src/android/camera_request.cpp\n> @@ -36,7 +36,7 @@ Camera3RequestDescriptor::Camera3RequestDescriptor(\n>  \t\t\tstatic_cast<CameraStream *>(buffer.stream->priv);\n>  \n>  \t\tbuffers_.push_back({ stream, buffer.buffer, nullptr,\n> -\t\t\t\t     buffer.acquire_fence, Status::Pending });\n> +\t\t\t\t     buffer.acquire_fence, Status::Success });\n>  \t}\n>  \n>  \t/* Clone the controls associated with the camera3 request. */\n> diff --git a/src/android/camera_request.h b/src/android/camera_request.h\n> index 05dabf89..904886da 100644\n> --- a/src/android/camera_request.h\n> +++ b/src/android/camera_request.h\n> @@ -26,7 +26,6 @@ class Camera3RequestDescriptor\n>  {\n>  public:\n>  \tenum class Status {\n> -\t\tPending,\n>  \t\tSuccess,\n>  \t\tError,\n>  \t};\n> @@ -43,7 +42,8 @@ public:\n>  \t\t\t\t const camera3_capture_request_t *camera3Request);\n>  \t~Camera3RequestDescriptor();\n>  \n> -\tbool isPending() const { return status_ == Status::Pending; }\n> +\tbool isPending() const { return !complete_; }\n> +\tvoid completeDescriptor() { complete_ = true; }\n\nAs the function is a member of the Camera3RequestDescriptor class, I\nwouldn't repeat \"descriptor\" in the name. Given that the complete_\nmember is public, I'd actually drop the function and access complete_\ndirectly, the same way we access status_. If you prefer an accessor, I'd\nmake the complete_ member private, but that's probably overkill for now\ngiven that all other members are public.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n>  \tuint32_t frameNumber_ = 0;\n>  \n> @@ -53,7 +53,8 @@ public:\n>  \tstd::unique_ptr<CaptureRequest> request_;\n>  \tstd::unique_ptr<CameraMetadata> resultMetadata_;\n>  \n> -\tStatus status_ = Status::Pending;\n> +\tbool complete_ = false;\n> +\tStatus status_ = Status::Success;\n>  \n>  private:\n>  \tLIBCAMERA_DISABLE_COPY(Camera3RequestDescriptor)","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0561EBDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 25 Oct 2021 05:07:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 599A264872;\n\tMon, 25 Oct 2021 07:07:49 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D433560237\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 25 Oct 2021 07:07:47 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3BD1BE0A;\n\tMon, 25 Oct 2021 07:07:47 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"bYeAxHxs\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1635138467;\n\tbh=27iJkC0HZOy4vrA5H4KeYViTwfNDjcGRhWInL7iZl3k=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=bYeAxHxsvJR7itO5I6dp4T+8mh3FH81Cc5zsFlqZG3q2u2TX/QTRssNJ6jauc6jmu\n\tlCpj3I7ARHXw3ECwW3IfbvnSL7s4P7cyt7XU49gN/9WrZ0tqmuvcQQkuW5dwG9n8Ep\n\t3t2uv+gOF1CAKkCvO3qpIil43vZCs2dOop0yI01s=","Date":"Mon, 25 Oct 2021 08:07:26 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<YXY7jhyn85hnGZ2q@pendragon.ideasonboard.com>","References":"<20211023103302.152769-1-umang.jain@ideasonboard.com>\n\t<20211023103302.152769-4-umang.jain@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20211023103302.152769-4-umang.jain@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v6 3/7] android: camera_device:\n\tRefactor descriptor status and sendCaptureResults()","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":20411,"web_url":"https://patchwork.libcamera.org/comment/20411/","msgid":"<CAO5uPHODKmr4sYHctoTNxJeRtN0=T1TFLUSn272V27g-uwmRkg@mail.gmail.com>","date":"2021-10-25T05:38:19","subject":"Re: [libcamera-devel] [PATCH v6 3/7] android: camera_device:\n\tRefactor descriptor status and sendCaptureResults()","submitter":{"id":63,"url":"https://patchwork.libcamera.org/api/people/63/","name":"Hirokazu Honda","email":"hiroh@chromium.org"},"content":"Hi Umang,\n\nOn Mon, Oct 25, 2021 at 2:07 PM Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> Hi Umang,\n>\n> Thank you for the patch.\n>\n> On Sat, Oct 23, 2021 at 04:02:58PM +0530, Umang Jain wrote:\n> > Currently, we use Camera3RequestDescriptor::Status to determine:\n> > - When the descriptor has been completely processed by HAL\n> > - Whether any errors were encountered, during its processing\n> >\n> > Both of these are essential to know whether the descriptor is eligible\n> > to call process_capture_results() through sendCaptureResults().\n> > When a status(Success/Error) is set on the descriptor, it is ready to\n> > be sent back via sendCaptureResults(). However, this might lead to\n> > undesired results especially when sendCaptureResults() runs in a\n> > different thread (for e.g. stream's post-processor async completion\n> > slot).\n> >\n> > This patch decouples the descriptor status (Success/Error) from the\n> > descriptor's completion status (pending or complete). The advantage\n> > of this is we can set the completion status when the descriptor has\n> > been processed fully by the layer and we can set the error status on\n> > the descriptor wherever an error is encountered, throughout the\n> > lifetime descriptor in the HAL layer.\n> >\n> > While at it, introduce a wrapper completeDescriptor() around\n> > sendCaptureResults(). completeDescriptor() as the name suggests will\n> > mark the descriptor as complete, so it is ready to be sent back.\n> > The locking mechanism is moved from sendCaptureResults() to this wrapper\n> > since the intention is to use completeDescriptor() in place of existing\n> > sendCaptureResults() calls.\n> >\n> > Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>\n> > ---\n> >  src/android/camera_device.cpp  | 33 ++++++++++++++++++---------------\n> >  src/android/camera_device.h    |  1 +\n> >  src/android/camera_request.cpp |  2 +-\n> >  src/android/camera_request.h   |  7 ++++---\n> >  4 files changed, 24 insertions(+), 19 deletions(-)\n> >\n> > diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> > index 806b4090..f4d4fb09 100644\n> > --- a/src/android/camera_device.cpp\n> > +++ b/src/android/camera_device.cpp\n> > @@ -982,13 +982,13 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n> >       MutexLocker stateLock(stateMutex_);\n> >\n> >       if (state_ == State::Flushing) {\n> > -             abortRequest(descriptor.get());\n> > +             Camera3RequestDescriptor *rawDescriptor = descriptor.get();\n> > +             abortRequest(rawDescriptor);\n>\n> Could we move the abortRequest() call just before completeDescriptor(),\n> to always operate with the descriptor already added to the queue ? It\n> should make no difference today, but consistent call patterns will make\n> it easier to understand the code and the possible race conditions.\n>\n> >               {\n> >                       MutexLocker descriptorsLock(descriptorsMutex_);\n> >                       descriptors_.push(std::move(descriptor));\n> >               }\n> > -\n> > -             sendCaptureResults();\n> > +             completeDescriptor(rawDescriptor);\n> >\n> >               return 0;\n> >       }\n> > @@ -1079,7 +1079,7 @@ void CameraDevice::requestComplete(Request *request)\n> >                               << request->status();\n> >\n> >               abortRequest(descriptor);\n> > -             sendCaptureResults();\n> > +             completeDescriptor(descriptor);\n> >\n> >               return;\n> >       }\n> > @@ -1117,6 +1117,7 @@ void CameraDevice::requestComplete(Request *request)\n> >       }\n> >\n> >       /* Handle post-processing. */\n> > +     bool hasPostProcessingErrors = false;\n> >       for (auto &buffer : descriptor->buffers_) {\n> >               CameraStream *stream = buffer.stream;\n> >\n> > @@ -1129,6 +1130,7 @@ void CameraDevice::requestComplete(Request *request)\n> >                       buffer.status = Camera3RequestDescriptor::Status::Error;\n> >                       notifyError(descriptor->frameNumber_, stream->camera3Stream(),\n> >                                   CAMERA3_MSG_ERROR_BUFFER);\n> > +                     hasPostProcessingErrors = true;\n>\n> You can set\n>\n>                         descriptor->status_ = Camera3RequestDescriptor::Status::Error;\n>\n> here.\n>\n> >                       continue;\n> >               }\n> >\n> > @@ -1143,29 +1145,32 @@ void CameraDevice::requestComplete(Request *request)\n> >\n> >               if (ret) {\n> >                       buffer.status = Camera3RequestDescriptor::Status::Error;\n> > +                     hasPostProcessingErrors = true;\n>\n> And here too.\n>\n> >                       notifyError(descriptor->frameNumber_, stream->camera3Stream(),\n> >                                   CAMERA3_MSG_ERROR_BUFFER);\n> >               }\n> >       }\n> >\n> > -     descriptor->status_ = Camera3RequestDescriptor::Status::Success;\n> > +     if (hasPostProcessingErrors)\n> > +             descriptor->status_ = Camera3RequestDescriptor::Status::Error;\n>\n> And then drop this.\n>\n> > +\n> > +     completeDescriptor(descriptor);\n> > +}\n> > +\n> > +void CameraDevice::completeDescriptor(Camera3RequestDescriptor *descriptor)\n> > +{\n> > +     MutexLocker lock(descriptorsMutex_);\n> > +     descriptor->completeDescriptor();\n> > +\n> >       sendCaptureResults();\n> >  }\n> >\n> >  void CameraDevice::sendCaptureResults()\n> >  {\n> > -     MutexLocker lock(descriptorsMutex_);\n\nJust note:\nWe may want to have an assertion to acquire lock.\nLooks like there is no way of doing this in std::mutex only.\nThe only way is to pass MutexLocker reference to here and\nASSERT(lock.owns_lock()).\n\nAnother brilliant way is to use thread annotation and annotate this\nfunction by REQUIRES().\nhttps://bugs.libcamera.org/show_bug.cgi?id=23\n\nChange looks good.\nReviewed-by: Hirokazu Honda <hiroh@chromium.org>\n\n> >       while (!descriptors_.empty() && !descriptors_.front()->isPending()) {\n> >               auto descriptor = std::move(descriptors_.front());\n> >               descriptors_.pop();\n> >\n> > -             /*\n> > -              * \\todo Releasing and re-acquiring the critical section for\n> > -              * every request completion (grain-locking) might have an\n> > -              * impact on performance which should be measured.\n> > -              */\n> > -             lock.unlock();\n> > -\n> >               camera3_capture_result_t captureResult = {};\n> >\n> >               captureResult.frame_number = descriptor->frameNumber_;\n> > @@ -1201,8 +1206,6 @@ void CameraDevice::sendCaptureResults()\n> >                       captureResult.partial_result = 1;\n> >\n> >               callbacks_->process_capture_result(callbacks_, &captureResult);\n> > -\n> > -             lock.lock();\n> >       }\n> >  }\n> >\n> > diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> > index 863cf414..e544f2bd 100644\n> > --- a/src/android/camera_device.h\n> > +++ b/src/android/camera_device.h\n> > @@ -93,6 +93,7 @@ private:\n> >       void notifyError(uint32_t frameNumber, camera3_stream_t *stream,\n> >                        camera3_error_msg_code code) const;\n> >       int processControls(Camera3RequestDescriptor *descriptor);\n> > +     void completeDescriptor(Camera3RequestDescriptor *descriptor);\n> >       void sendCaptureResults();\n> >       std::unique_ptr<CameraMetadata> getResultMetadata(\n> >               const Camera3RequestDescriptor &descriptor) const;\n> > diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp\n> > index faa85ada..16cf266f 100644\n> > --- a/src/android/camera_request.cpp\n> > +++ b/src/android/camera_request.cpp\n> > @@ -36,7 +36,7 @@ Camera3RequestDescriptor::Camera3RequestDescriptor(\n> >                       static_cast<CameraStream *>(buffer.stream->priv);\n> >\n> >               buffers_.push_back({ stream, buffer.buffer, nullptr,\n> > -                                  buffer.acquire_fence, Status::Pending });\n> > +                                  buffer.acquire_fence, Status::Success });\n> >       }\n> >\n> >       /* Clone the controls associated with the camera3 request. */\n> > diff --git a/src/android/camera_request.h b/src/android/camera_request.h\n> > index 05dabf89..904886da 100644\n> > --- a/src/android/camera_request.h\n> > +++ b/src/android/camera_request.h\n> > @@ -26,7 +26,6 @@ class Camera3RequestDescriptor\n> >  {\n> >  public:\n> >       enum class Status {\n> > -             Pending,\n> >               Success,\n> >               Error,\n> >       };\n> > @@ -43,7 +42,8 @@ public:\n> >                                const camera3_capture_request_t *camera3Request);\n> >       ~Camera3RequestDescriptor();\n> >\n> > -     bool isPending() const { return status_ == Status::Pending; }\n> > +     bool isPending() const { return !complete_; }\n> > +     void completeDescriptor() { complete_ = true; }\n>\n> As the function is a member of the Camera3RequestDescriptor class, I\n> wouldn't repeat \"descriptor\" in the name. Given that the complete_\n> member is public, I'd actually drop the function and access complete_\n> directly, the same way we access status_. If you prefer an accessor, I'd\n> make the complete_ member private, but that's probably overkill for now\n> given that all other members are public.\n>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n> >       uint32_t frameNumber_ = 0;\n> >\n> > @@ -53,7 +53,8 @@ public:\n> >       std::unique_ptr<CaptureRequest> request_;\n> >       std::unique_ptr<CameraMetadata> resultMetadata_;\n> >\n> > -     Status status_ = Status::Pending;\n> > +     bool complete_ = false;\n> > +     Status status_ = Status::Success;\n> >\n> >  private:\n> >       LIBCAMERA_DISABLE_COPY(Camera3RequestDescriptor)\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9E99CBF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 25 Oct 2021 05:38:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5FBCD64872;\n\tMon, 25 Oct 2021 07:38:32 +0200 (CEST)","from mail-ed1-x529.google.com (mail-ed1-x529.google.com\n\t[IPv6:2a00:1450:4864:20::529])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C42F360237\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 25 Oct 2021 07:38:31 +0200 (CEST)","by mail-ed1-x529.google.com with SMTP id g8so6347585edb.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 24 Oct 2021 22:38:31 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"F8PxPZB2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=qywqtwMQZQiGatMC4RVOn7DymH1yr175kfnGd81MtpQ=;\n\tb=F8PxPZB2K9zKXaMC/0iPJHsc3xPsvE7ssfBMup4Kkh13gXCSMuMFkvlQt84FmWh3+d\n\tAIRL0/EzDCVitNBvreQ1/cu/3mP9nb8nIAFo36By2CTAD/KTxYxFK8p+85F79eWdII3r\n\tC3a2LkDW9KNqXMEF1TY3rXJMcsMUuakmUZqMk=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=qywqtwMQZQiGatMC4RVOn7DymH1yr175kfnGd81MtpQ=;\n\tb=nQSnK8MgcsNGnjmse95Rcua6YFTGIJjgIapupSuCDqHzLAT2Xf+iL+b4EUFoZLSdBM\n\t7g2eR5fvHVjrIydVVtc9FCI7s9+ApmvfpcGK4PdEYVgrqCQczhACmkI/KmKjY+ql5Wn7\n\teIOYylKf7LZ2cWQVGs2oNhfQTyQV1CcI7y3PVjT6UmeptEWCZfYU/7tfiRgqrH61VoYE\n\tjkECWQdVPMUh1jFx4b2sR9XbvrXmEBAEuZk9EPDRl3BZHlAR63x0ixVPGc80rI7itxgd\n\tf7RBIViHFVR8uAv8Ii7GA+JU9AsoYdsPdMZwqQjY7yYAmYj3dhyBvd/xSEO9u1PwkXgZ\n\ttoLA==","X-Gm-Message-State":"AOAM530JAICsJUkvQ1Pr1kmKLWa4nEFMl8BDWB5SQuwSMn5j72x4J2jt\n\trmkhRmhx4reGMc05Hja/TEcs0rbY1REWAjKyBxEQ/g==","X-Google-Smtp-Source":"ABdhPJyuKF11wWijrAyrMVp/Rh+irvHuFo1nF0oybwVRzn23fPvz8fCLbybXzcUACue5M4be6Idyyg3kw48mqwJjSx4=","X-Received":"by 2002:a05:6402:26d3:: with SMTP id\n\tx19mr23743737edd.291.1635140311404; \n\tSun, 24 Oct 2021 22:38:31 -0700 (PDT)","MIME-Version":"1.0","References":"<20211023103302.152769-1-umang.jain@ideasonboard.com>\n\t<20211023103302.152769-4-umang.jain@ideasonboard.com>\n\t<YXY7jhyn85hnGZ2q@pendragon.ideasonboard.com>","In-Reply-To":"<YXY7jhyn85hnGZ2q@pendragon.ideasonboard.com>","From":"Hirokazu Honda <hiroh@chromium.org>","Date":"Mon, 25 Oct 2021 14:38:19 +0900","Message-ID":"<CAO5uPHODKmr4sYHctoTNxJeRtN0=T1TFLUSn272V27g-uwmRkg@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH v6 3/7] android: camera_device:\n\tRefactor descriptor status and sendCaptureResults()","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]