[{"id":20009,"web_url":"https://patchwork.libcamera.org/comment/20009/","msgid":"<20210929185026.33ix6smqeb72kon6@uno.localdomain>","date":"2021-09-29T18:50:26","subject":"Re: [libcamera-devel] [PATCH v4 4/4] android: camera_device: Send\n\tcapture results by inspecting the queue","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Umang,\n\nOn Wed, Sep 29, 2021 at 07:00:30PM +0530, Umang Jain wrote:\n> There is a possibility that an out-of-order completion of capture\n> request happens by calling process_capture_result() directly on error\n> paths. The framework expects that errors should be notified as soon as\n> possible, but the request completion order should remain intact.\n> An existing instance of this is abortRequest(), which sends the capture\n> results on flushing state, without considering order-of-completion.\n>\n> Since we have a queue of Camera3RequestDescriptor tracking each\n> capture request placed by framework to libcamera HAL, we should be only\n> sending back capture results from a single location, by inspecting\n> the queue. As per the patch, this now happens in\n> CameraDevice::sendCaptureResults().\n>\n> Each descriptor is now equipped with its own status to denote whether\n> the capture request is complete and ready to send back to the framework\n\nready to be sent\n\n> or needs to be waited upon. This ensures that the order of completion is\n> respected for the requests.\n>\n> Since we are fixing out-of-order request completion in abortRequest(),\n> change the function to read from the Camera3RequestDescriptor directly,\n> instead of camera3_capture_request_t. The descriptor should have all the\n> information necessary to set the request buffers' state to error.\n>\n> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Reviewed-by: Hirokazu Honda <hiroh@chromium.org>\n> ---\n>  src/android/camera_device.cpp | 59 ++++++++++++++++++++++++-----------\n>  src/android/camera_device.h   | 14 ++++++++-\n>  2 files changed, 54 insertions(+), 19 deletions(-)\n>\n> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> index 45350563..38c64bb7 100644\n> --- a/src/android/camera_device.cpp\n> +++ b/src/android/camera_device.cpp\n> @@ -860,25 +860,25 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)\n>  \treturn 0;\n>  }\n>\n> -void CameraDevice::abortRequest(camera3_capture_request_t *request) const\n> +void CameraDevice::abortRequest(Camera3RequestDescriptor *descriptor) const\n>  {\n> -\tnotifyError(request->frame_number, nullptr, CAMERA3_MSG_ERROR_REQUEST);\n> +\tnotifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_REQUEST);\n>\n> -\tcamera3_capture_result_t result = {};\n> -\tresult.num_output_buffers = request->num_output_buffers;\n> -\tresult.frame_number = request->frame_number;\n> +\tcamera3_capture_result_t &result = descriptor->captureResult_;\n> +\tresult.num_output_buffers = descriptor->buffers_.size();\n> +\tresult.frame_number = descriptor->frameNumber_;\n>  \tresult.partial_result = 0;\n>\n>  \tstd::vector<camera3_stream_buffer_t> resultBuffers(result.num_output_buffers);\n>  \tfor (auto [i, buffer] : utils::enumerate(resultBuffers)) {\n> -\t\tbuffer = request->output_buffers[i];\n> -\t\tbuffer.release_fence = request->output_buffers[i].acquire_fence;\n> +\t\tbuffer = descriptor->buffers_[i];\n> +\t\tbuffer.release_fence = descriptor->buffers_[i].acquire_fence;\n>  \t\tbuffer.acquire_fence = -1;\n>  \t\tbuffer.status = CAMERA3_BUFFER_STATUS_ERROR;\n>  \t}\n>  \tresult.output_buffers = resultBuffers.data();\n>\n> -\tcallbacks_->process_capture_result(callbacks_, &result);\n> +\tdescriptor->status_ = Camera3RequestDescriptor::Status::Error;\n>  }\n>\n>  bool CameraDevice::isValidRequest(camera3_capture_request_t *camera3Request) const\n> @@ -1050,13 +1050,21 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n>  \t\treturn ret;\n>\n>  \t/*\n> -\t * If flush is in progress abort the request. If the camera has been\n> -\t * stopped we have to re-start it to be able to process the request.\n> +\t * If flush is in progress set the request status to error and place it\n> +\t * on the queue to be later completed. If the camera has been stopped we\n> +\t * have to re-start it to be able to process the request.\n>  \t */\n>  \tMutexLocker stateLock(stateMutex_);\n>\n>  \tif (state_ == State::Flushing) {\n> -\t\tabortRequest(camera3Request);\n> +\t\tabortRequest(descriptor.get());\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> +\n>  \t\treturn 0;\n>  \t}\n>\n> @@ -1116,7 +1124,7 @@ void CameraDevice::requestComplete(Request *request)\n>  \t * The buffer status is set to OK and later changed to ERROR if\n>  \t * post-processing/compression fails.\n>  \t */\n> -\tcamera3_capture_result_t captureResult = {};\n> +\tcamera3_capture_result_t &captureResult = descriptor->captureResult_;\n>  \tcaptureResult.frame_number = descriptor->frameNumber_;\n>  \tcaptureResult.num_output_buffers = descriptor->buffers_.size();\n>  \tfor (camera3_stream_buffer_t &buffer : descriptor->buffers_) {\n> @@ -1166,10 +1174,9 @@ void CameraDevice::requestComplete(Request *request)\n>  \t\t\tbuffer.status = CAMERA3_BUFFER_STATUS_ERROR;\n>  \t\t}\n>\n> -\t\tcallbacks_->process_capture_result(callbacks_, &captureResult);\n> +\t\tdescriptor->status_ = Camera3RequestDescriptor::Status::Error;\n> +\t\tsendCaptureResults();\n>\n> -\t\tMutexLocker descriptorsLock(descriptorsMutex_);\n> -\t\tdescriptors_.pop();\n>  \t\treturn;\n>  \t}\n>\n> @@ -1235,10 +1242,26 @@ void CameraDevice::requestComplete(Request *request)\n>  \t}\n>\n>  \tcaptureResult.result = resultMetadata->get();\n> -\tcallbacks_->process_capture_result(callbacks_, &captureResult);\n> +\tdescriptor->status_ = Camera3RequestDescriptor::Status::Success;\n> +\tsendCaptureResults();\n> +}\n>\n> -\tMutexLocker descriptorsLock(descriptorsMutex_);\n> -\tdescriptors_.pop();\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 Measure performance impact of grain locking here against\n> +\t\t * coarse locking.\n\nI find this a bit hard to parse. Maybe\n\n\t\t * \\todo Releasing and re-acquiring the critical\n                 * section for every request completion might have an\n                 * impact on performaces which should be measured.\n\nUp to you, really.\n\nAll minors might be optionally fixed when applying\n\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\n> +\t\t */\n> +\t\tlock.unlock();\n> +\t\tcallbacks_->process_capture_result(callbacks_,\n> +\t\t\t\t\t\t   &descriptor->captureResult_);\n> +\t\tlock.lock();\n> +\t}\n>  }\n>\n>  std::string CameraDevice::logPrefix() const\n> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> index 85497921..b7d774fe 100644\n> --- a/src/android/camera_device.h\n> +++ b/src/android/camera_device.h\n> @@ -74,17 +74,28 @@ private:\n>  \tCameraDevice(unsigned int id, std::shared_ptr<libcamera::Camera> camera);\n>\n>  \tstruct Camera3RequestDescriptor {\n> +\t\tenum class Status {\n> +\t\t\tPending,\n> +\t\t\tSuccess,\n> +\t\t\tError,\n> +\t\t};\n> +\n>  \t\tCamera3RequestDescriptor() = default;\n>  \t\t~Camera3RequestDescriptor() = default;\n>  \t\tCamera3RequestDescriptor(libcamera::Camera *camera,\n>  \t\t\t\t\t const camera3_capture_request_t *camera3Request);\n>  \t\tCamera3RequestDescriptor &operator=(Camera3RequestDescriptor &&) = default;\n>\n> +\t\tbool isPending() const { return status_ == Status::Pending; }\n> +\n>  \t\tuint32_t frameNumber_ = 0;\n>  \t\tstd::vector<camera3_stream_buffer_t> buffers_;\n>  \t\tstd::vector<std::unique_ptr<libcamera::FrameBuffer>> frameBuffers_;\n>  \t\tCameraMetadata settings_;\n>  \t\tstd::unique_ptr<CaptureRequest> request_;\n> +\n> +\t\tcamera3_capture_result_t captureResult_ = {};\n> +\t\tStatus status_ = Status::Pending;\n>  \t};\n>\n>  \tenum class State {\n> @@ -99,12 +110,13 @@ private:\n>  \tcreateFrameBuffer(const buffer_handle_t camera3buffer,\n>  \t\t\t  libcamera::PixelFormat pixelFormat,\n>  \t\t\t  const libcamera::Size &size);\n> -\tvoid abortRequest(camera3_capture_request_t *request) const;\n> +\tvoid abortRequest(Camera3RequestDescriptor *descriptor) const;\n>  \tbool isValidRequest(camera3_capture_request_t *request) const;\n>  \tvoid notifyShutter(uint32_t frameNumber, uint64_t timestamp);\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 sendCaptureResults();\n>  \tstd::unique_ptr<CameraMetadata> getResultMetadata(\n>  \t\tconst Camera3RequestDescriptor &descriptor) const;\n>\n> --\n> 2.31.0\n>","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 E026EBDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 29 Sep 2021 18:49:42 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 117A8691AC;\n\tWed, 29 Sep 2021 20:49:42 +0200 (CEST)","from relay11.mail.gandi.net (relay11.mail.gandi.net\n\t[217.70.178.231])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8EA9769185\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 29 Sep 2021 20:49:40 +0200 (CEST)","(Authenticated sender: jacopo@jmondi.org)\n\tby relay11.mail.gandi.net (Postfix) with ESMTPSA id 0CEC7100004;\n\tWed, 29 Sep 2021 18:49:39 +0000 (UTC)"],"Date":"Wed, 29 Sep 2021 20:50:26 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<20210929185026.33ix6smqeb72kon6@uno.localdomain>","References":"<20210929133030.401961-1-umang.jain@ideasonboard.com>\n\t<20210929133030.401961-5-umang.jain@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210929133030.401961-5-umang.jain@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 4/4] android: camera_device: Send\n\tcapture results by inspecting the queue","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":20010,"web_url":"https://patchwork.libcamera.org/comment/20010/","msgid":"<a68189ed-9379-497e-8b54-1babb40fa37f@ideasonboard.com>","date":"2021-09-30T05:13:58","subject":"Re: [libcamera-devel] [PATCH v4 4/4] android: camera_device: Send\n\tcapture results by inspecting the queue","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Jacopo\n\nOn 9/30/21 12:20 AM, Jacopo Mondi wrote:\n> Hi Umang,\n>\n> On Wed, Sep 29, 2021 at 07:00:30PM +0530, Umang Jain wrote:\n>> There is a possibility that an out-of-order completion of capture\n>> request happens by calling process_capture_result() directly on error\n>> paths. The framework expects that errors should be notified as soon as\n>> possible, but the request completion order should remain intact.\n>> An existing instance of this is abortRequest(), which sends the capture\n>> results on flushing state, without considering order-of-completion.\n>>\n>> Since we have a queue of Camera3RequestDescriptor tracking each\n>> capture request placed by framework to libcamera HAL, we should be only\n>> sending back capture results from a single location, by inspecting\n>> the queue. As per the patch, this now happens in\n>> CameraDevice::sendCaptureResults().\n>>\n>> Each descriptor is now equipped with its own status to denote whether\n>> the capture request is complete and ready to send back to the framework\n> ready to be sent\n>\n>> or needs to be waited upon. This ensures that the order of completion is\n>> respected for the requests.\n>>\n>> Since we are fixing out-of-order request completion in abortRequest(),\n>> change the function to read from the Camera3RequestDescriptor directly,\n>> instead of camera3_capture_request_t. The descriptor should have all the\n>> information necessary to set the request buffers' state to error.\n>>\n>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>\n>> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>> Reviewed-by: Hirokazu Honda <hiroh@chromium.org>\n>> ---\n>>   src/android/camera_device.cpp | 59 ++++++++++++++++++++++++-----------\n>>   src/android/camera_device.h   | 14 ++++++++-\n>>   2 files changed, 54 insertions(+), 19 deletions(-)\n>>\n>> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n>> index 45350563..38c64bb7 100644\n>> --- a/src/android/camera_device.cpp\n>> +++ b/src/android/camera_device.cpp\n>> @@ -860,25 +860,25 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)\n>>   \treturn 0;\n>>   }\n>>\n>> -void CameraDevice::abortRequest(camera3_capture_request_t *request) const\n>> +void CameraDevice::abortRequest(Camera3RequestDescriptor *descriptor) const\n>>   {\n>> -\tnotifyError(request->frame_number, nullptr, CAMERA3_MSG_ERROR_REQUEST);\n>> +\tnotifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_REQUEST);\n>>\n>> -\tcamera3_capture_result_t result = {};\n>> -\tresult.num_output_buffers = request->num_output_buffers;\n>> -\tresult.frame_number = request->frame_number;\n>> +\tcamera3_capture_result_t &result = descriptor->captureResult_;\n>> +\tresult.num_output_buffers = descriptor->buffers_.size();\n>> +\tresult.frame_number = descriptor->frameNumber_;\n>>   \tresult.partial_result = 0;\n>>\n>>   \tstd::vector<camera3_stream_buffer_t> resultBuffers(result.num_output_buffers);\n>>   \tfor (auto [i, buffer] : utils::enumerate(resultBuffers)) {\n>> -\t\tbuffer = request->output_buffers[i];\n>> -\t\tbuffer.release_fence = request->output_buffers[i].acquire_fence;\n>> +\t\tbuffer = descriptor->buffers_[i];\n>> +\t\tbuffer.release_fence = descriptor->buffers_[i].acquire_fence;\n>>   \t\tbuffer.acquire_fence = -1;\n>>   \t\tbuffer.status = CAMERA3_BUFFER_STATUS_ERROR;\n>>   \t}\n>>   \tresult.output_buffers = resultBuffers.data();\n>>\n>> -\tcallbacks_->process_capture_result(callbacks_, &result);\n>> +\tdescriptor->status_ = Camera3RequestDescriptor::Status::Error;\n>>   }\n>>\n>>   bool CameraDevice::isValidRequest(camera3_capture_request_t *camera3Request) const\n>> @@ -1050,13 +1050,21 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n>>   \t\treturn ret;\n>>\n>>   \t/*\n>> -\t * If flush is in progress abort the request. If the camera has been\n>> -\t * stopped we have to re-start it to be able to process the request.\n>> +\t * If flush is in progress set the request status to error and place it\n>> +\t * on the queue to be later completed. If the camera has been stopped we\n>> +\t * have to re-start it to be able to process the request.\n>>   \t */\n>>   \tMutexLocker stateLock(stateMutex_);\n>>\n>>   \tif (state_ == State::Flushing) {\n>> -\t\tabortRequest(camera3Request);\n>> +\t\tabortRequest(descriptor.get());\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>> +\n>>   \t\treturn 0;\n>>   \t}\n>>\n>> @@ -1116,7 +1124,7 @@ void CameraDevice::requestComplete(Request *request)\n>>   \t * The buffer status is set to OK and later changed to ERROR if\n>>   \t * post-processing/compression fails.\n>>   \t */\n>> -\tcamera3_capture_result_t captureResult = {};\n>> +\tcamera3_capture_result_t &captureResult = descriptor->captureResult_;\n>>   \tcaptureResult.frame_number = descriptor->frameNumber_;\n>>   \tcaptureResult.num_output_buffers = descriptor->buffers_.size();\n>>   \tfor (camera3_stream_buffer_t &buffer : descriptor->buffers_) {\n>> @@ -1166,10 +1174,9 @@ void CameraDevice::requestComplete(Request *request)\n>>   \t\t\tbuffer.status = CAMERA3_BUFFER_STATUS_ERROR;\n>>   \t\t}\n>>\n>> -\t\tcallbacks_->process_capture_result(callbacks_, &captureResult);\n>> +\t\tdescriptor->status_ = Camera3RequestDescriptor::Status::Error;\n>> +\t\tsendCaptureResults();\n>>\n>> -\t\tMutexLocker descriptorsLock(descriptorsMutex_);\n>> -\t\tdescriptors_.pop();\n>>   \t\treturn;\n>>   \t}\n>>\n>> @@ -1235,10 +1242,26 @@ void CameraDevice::requestComplete(Request *request)\n>>   \t}\n>>\n>>   \tcaptureResult.result = resultMetadata->get();\n>> -\tcallbacks_->process_capture_result(callbacks_, &captureResult);\n>> +\tdescriptor->status_ = Camera3RequestDescriptor::Status::Success;\n>> +\tsendCaptureResults();\n>> +}\n>>\n>> -\tMutexLocker descriptorsLock(descriptorsMutex_);\n>> -\tdescriptors_.pop();\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 Measure performance impact of grain locking here against\n>> +\t\t * coarse locking.\n> I find this a bit hard to parse. Maybe\n>\n> \t\t * \\todo Releasing and re-acquiring the critical\n>                   * section for every request completion might have an\n>                   * impact on performaces which should be measured.\n\ns/performaces/performance/\n\nI have updated to:\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>\n> Up to you, really.\n>\n> All minors might be optionally fixed when applying\n>\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\n\nThanks!\n\n>\n>> +\t\t */\n>> +\t\tlock.unlock();\n>> +\t\tcallbacks_->process_capture_result(callbacks_,\n>> +\t\t\t\t\t\t   &descriptor->captureResult_);\n>> +\t\tlock.lock();\n>> +\t}\n>>   }\n>>\n>>   std::string CameraDevice::logPrefix() const\n>> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n>> index 85497921..b7d774fe 100644\n>> --- a/src/android/camera_device.h\n>> +++ b/src/android/camera_device.h\n>> @@ -74,17 +74,28 @@ private:\n>>   \tCameraDevice(unsigned int id, std::shared_ptr<libcamera::Camera> camera);\n>>\n>>   \tstruct Camera3RequestDescriptor {\n>> +\t\tenum class Status {\n>> +\t\t\tPending,\n>> +\t\t\tSuccess,\n>> +\t\t\tError,\n>> +\t\t};\n>> +\n>>   \t\tCamera3RequestDescriptor() = default;\n>>   \t\t~Camera3RequestDescriptor() = default;\n>>   \t\tCamera3RequestDescriptor(libcamera::Camera *camera,\n>>   \t\t\t\t\t const camera3_capture_request_t *camera3Request);\n>>   \t\tCamera3RequestDescriptor &operator=(Camera3RequestDescriptor &&) = default;\n>>\n>> +\t\tbool isPending() const { return status_ == Status::Pending; }\n>> +\n>>   \t\tuint32_t frameNumber_ = 0;\n>>   \t\tstd::vector<camera3_stream_buffer_t> buffers_;\n>>   \t\tstd::vector<std::unique_ptr<libcamera::FrameBuffer>> frameBuffers_;\n>>   \t\tCameraMetadata settings_;\n>>   \t\tstd::unique_ptr<CaptureRequest> request_;\n>> +\n>> +\t\tcamera3_capture_result_t captureResult_ = {};\n>> +\t\tStatus status_ = Status::Pending;\n>>   \t};\n>>\n>>   \tenum class State {\n>> @@ -99,12 +110,13 @@ private:\n>>   \tcreateFrameBuffer(const buffer_handle_t camera3buffer,\n>>   \t\t\t  libcamera::PixelFormat pixelFormat,\n>>   \t\t\t  const libcamera::Size &size);\n>> -\tvoid abortRequest(camera3_capture_request_t *request) const;\n>> +\tvoid abortRequest(Camera3RequestDescriptor *descriptor) const;\n>>   \tbool isValidRequest(camera3_capture_request_t *request) const;\n>>   \tvoid notifyShutter(uint32_t frameNumber, uint64_t timestamp);\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 sendCaptureResults();\n>>   \tstd::unique_ptr<CameraMetadata> getResultMetadata(\n>>   \t\tconst Camera3RequestDescriptor &descriptor) const;\n>>\n>> --\n>> 2.31.0\n>>","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 417AABDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Sep 2021 05:14:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7EE76691AA;\n\tThu, 30 Sep 2021 07:14:05 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D8475602DC\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Sep 2021 07:14:02 +0200 (CEST)","from [192.168.1.104] (unknown [103.251.226.9])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0853E2A8;\n\tThu, 30 Sep 2021 07:14:01 +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=\"bB23ukhQ\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632978842;\n\tbh=b4zpEslN1RjVdPfmqQW1NXzA6c5I1gnb46tO+z8Wa+M=;\n\th=Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=bB23ukhQTBBbt6n2hER/nqCIbP8DZMuafs4R2ciGcadW8txjRJ8k80KB7XjMxDC78\n\t7cdjpZvjjqUQvSLcz8hzC8E4fRTo94yV4ZJD6sxx8ZzVbuXfs65Qf/7MBuL0898vto\n\tdEdA9adOSTut5RwQMkmsaJJvWGTBV3t2GSHw7Xs8=","To":"Jacopo Mondi <jacopo@jmondi.org>","References":"<20210929133030.401961-1-umang.jain@ideasonboard.com>\n\t<20210929133030.401961-5-umang.jain@ideasonboard.com>\n\t<20210929185026.33ix6smqeb72kon6@uno.localdomain>","From":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<a68189ed-9379-497e-8b54-1babb40fa37f@ideasonboard.com>","Date":"Thu, 30 Sep 2021 10:43:58 +0530","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.10.2","MIME-Version":"1.0","In-Reply-To":"<20210929185026.33ix6smqeb72kon6@uno.localdomain>","Content-Type":"text/plain; charset=utf-8; format=flowed","Content-Transfer-Encoding":"8bit","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH v4 4/4] android: camera_device: Send\n\tcapture results by inspecting the queue","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>"}}]