[libcamera-devel] [PATCH v3 09/10] android: camera_device: Send capture results inspecting the descriptor
Jacopo Mondi
jacopo at jmondi.org
Tue Sep 21 13:46:18 CEST 2021
Hi Umang,
On Mon, Sep 20, 2021 at 11:07:51PM +0530, Umang Jain wrote:
> A Camera3RequestDescriptors is constructed and queued to descriptors_
> queue as soon as an (incoming) capture request is received on the
> libcamera HAL. The capture request is picked up by HAL, in order to run
> it to completion. At completion, CameraDevice::requestComplete() gets
> invoked and capture results are populated and ready to be sent back
> to the framework.
>
> All the data and framebuffers associated with the request are alive
> and encapsulated inside this Camera3RequestDescriptor descriptor.
> By inspecting the ProcessStatus on the descriptor, we can now send
> capture results via the process_capture_result() callback.
>
> Hence, introduce a new private member function sendCaptureResults()
> which will be responsible to send capture results back to the
> framework by inspecting the descriptor on the queue. In subsequent
> commit, when the post processsor shall run async, sendCaptureResults()
> can be called from the post-processor's thread for e.g.
> streamProcessComplete() hence, introduce the mutex lock to avoid the
> races.
>
> Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> ---
> src/android/camera_device.cpp | 47 +++++++++++++++++++++++++----------
> src/android/camera_device.h | 4 +++
> 2 files changed, 38 insertions(+), 13 deletions(-)
>
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 4658e881..16ecdfc5 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -1078,7 +1078,7 @@ void CameraDevice::requestComplete(Request *request)
> * The buffer status is set to OK and later changed to ERROR if
> * post-processing/compression fails.
> */
> - camera3_capture_result_t captureResult = {};
> + camera3_capture_result_t &captureResult = descriptor->captureResult_;
> captureResult.frame_number = descriptor->frameNumber_;
> captureResult.num_output_buffers = descriptor->buffers_.size();
> for (camera3_stream_buffer_t &buffer : descriptor->buffers_) {
> @@ -1156,26 +1156,25 @@ void CameraDevice::requestComplete(Request *request)
> continue;
> }
>
> + if (cameraStream->type() == CameraStream::Type::Internal)
> + descriptor->internalBuffer_ = src;
> +
> descriptor->status_ = Camera3RequestDescriptor::ProcessStatus::Processing;
>
> cameraStream->process(src, *buffer.buffer, descriptor);
> -
> - /*
> - * Return the FrameBuffer to the CameraStream now that we're
> - * done processing it.
> - */
> - if (cameraStream->type() == CameraStream::Type::Internal)
> - cameraStream->putBuffer(src);
> + return;
> }
>
> - captureResult.result = descriptor->resultMetadata_->get();
> - callbacks_->process_capture_result(callbacks_, &captureResult);
> -
> - descriptors_.pop_front();
> + /*
> + * Mark the status on the descriptor as success as no processing
> + * is neeeded.
> + */
> + descriptor->status_ = Camera3RequestDescriptor::ProcessStatus::Success;
> + sendCaptureResults();
> }
>
>
> -void CameraDevice::streamProcessingComplete([[maybe_unused]] CameraStream *cameraStream,
> +void CameraDevice::streamProcessingComplete(CameraStream *cameraStream,
> Camera3RequestDescriptor *request)
> {
> if (request->status_ == Camera3RequestDescriptor::ProcessStatus::Error) {
> @@ -1190,6 +1189,28 @@ void CameraDevice::streamProcessingComplete([[maybe_unused]] CameraStream *camer
> CAMERA3_MSG_ERROR_BUFFER);
> }
> }
> +
> + /*
> + * Return the FrameBuffer to the CameraStream now that we're
> + * done processing it.
> + */
> + if (cameraStream->type() == CameraStream::Type::Internal)
> + cameraStream->putBuffer(request->internalBuffer_);
> +
> + sendCaptureResults();
> +}
> +
> +void CameraDevice::sendCaptureResults()
> +{
> + Camera3RequestDescriptor *d = descriptors_.front().get();
If I'm not mistaken, in case a request that doesn't need
post-processing will complete while the post-processed one is still
being worked on, this could lead to a completion order inversion
processCaptureRequest(n)
descriptors.push(n)
processCaptureRequest(n+1)
descriptors.push(n+1)
equestComplete(n)
postProcess(n) -----------> process(n)
|
.... ...
|
requestComplete(n+1) |
sendCaptureResult(n+1) |
d = descriptors.front() |
process_capture_res(n) |
|
sendCaptureResult(n) <----------------
d = descritpros.front()
process_capture_res(n + 1)
> + if (d->status_ == Camera3RequestDescriptor::ProcessStatus::Processing ||
> + d->status_ == Camera3RequestDescriptor::ProcessStatus::None)
> + return;
> +
> + MutexLocker lock(descriptorsMutex_);
> + d->captureResult_.result = d->resultMetadata_->get();
> + callbacks_->process_capture_result(callbacks_, &(d->captureResult_));
> + descriptors_.pop_front();
> }
>
> std::string CameraDevice::logPrefix() const
> diff --git a/src/android/camera_device.h b/src/android/camera_device.h
> index 60c134dc..0bd570a1 100644
> --- a/src/android/camera_device.h
> +++ b/src/android/camera_device.h
> @@ -56,6 +56,9 @@ struct Camera3RequestDescriptor {
> std::unique_ptr<CaptureRequest> request_;
> std::unique_ptr<CameraMetadata> resultMetadata_;
>
> + camera3_capture_result_t captureResult_ = {};
> + libcamera::FrameBuffer *internalBuffer_;
> +
> ProcessStatus status_;
> };
>
> @@ -118,6 +121,7 @@ private:
> int processControls(Camera3RequestDescriptor *descriptor);
> std::unique_ptr<CameraMetadata> getResultMetadata(
> const Camera3RequestDescriptor *descriptor) const;
> + void sendCaptureResults();
>
> unsigned int id_;
> camera3_device_t camera3Device_;
> --
> 2.31.1
>
More information about the libcamera-devel
mailing list