From patchwork Mon Sep 20 17:37:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13865 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 B7F12BF01C for ; Mon, 20 Sep 2021 17:38:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 703C16918F; Mon, 20 Sep 2021 19:38:05 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="KrV8sAYT"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 672E269186 for ; Mon, 20 Sep 2021 19:38:03 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DA01045E; Mon, 20 Sep 2021 19:38:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159482; bh=FM6KatmqxksAPaqxymkPkM8yUHUKLUwkCWcEhriHQFY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KrV8sAYTZ1qPrH7CN7fXBX9vxKgzHOfuv9jgWaAioFr+eLHi/5F2e65EVgmKigGN3 HCN0oEdQh2vjzc8PjwqIK1ETP7O3ymJNsveyUKIn3LIhbjxb1noDqahoJcz2F240yV G83ET4aySIqxRWpAik3IiO0Q9bUqRP3r7G7BvdmY= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:43 +0530 Message-Id: <20210920173752.1346190-2-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 01/10] android: camera_worker: Use Camera3RequestDescriptor as cookie 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Use Camera3RequestDescriptor as cookie for the Capture Request. The cookie is used to lookup descriptors map in CameraDevice::requestComplete(). The map will be transformed to a queue in subsequent commit. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 3 ++- src/android/camera_worker.cpp | 6 +++--- src/android/camera_worker.h | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index ab31bdda..f461e14c 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -244,7 +244,8 @@ CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor( * Create the CaptureRequest, stored as a unique_ptr<> to tie its * lifetime to the descriptor. */ - request_ = std::make_unique(camera); + request_ = std::make_unique(camera, + reinterpret_cast(this)); } /* diff --git a/src/android/camera_worker.cpp b/src/android/camera_worker.cpp index 91313183..3e18de21 100644 --- a/src/android/camera_worker.cpp +++ b/src/android/camera_worker.cpp @@ -27,10 +27,10 @@ LOG_DECLARE_CATEGORY(HAL) * by the CameraWorker which queues it to the libcamera::Camera after handling * fences. */ -CaptureRequest::CaptureRequest(Camera *camera) - : camera_(camera) +CaptureRequest::CaptureRequest(Camera *camera, uint64_t cookie) + : camera_(camera), cookie_(cookie) { - request_ = camera_->createRequest(reinterpret_cast(this)); + request_ = camera_->createRequest(cookie_); } void CaptureRequest::addBuffer(Stream *stream, FrameBuffer *buffer, int fence) diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h index 67ae50bd..3432d1fd 100644 --- a/src/android/camera_worker.h +++ b/src/android/camera_worker.h @@ -22,7 +22,7 @@ class CameraDevice; class CaptureRequest { public: - CaptureRequest(libcamera::Camera *camera); + CaptureRequest(libcamera::Camera *camera, uint64_t cookie); const std::vector &fences() const { return acquireFences_; } libcamera::ControlList &controls() { return request_->controls(); } @@ -30,7 +30,7 @@ public: { return request_->metadata(); } - unsigned long cookie() const { return request_->cookie(); } + unsigned long cookie() const { return cookie_; } void addBuffer(libcamera::Stream *stream, libcamera::FrameBuffer *buffer, int fence); @@ -40,6 +40,7 @@ private: libcamera::Camera *camera_; std::vector acquireFences_; std::unique_ptr request_; + uint64_t cookie_; }; class CameraWorker : private libcamera::Thread From patchwork Mon Sep 20 17:37:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13866 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 581F5BF01C for ; Mon, 20 Sep 2021 17:38:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 16BFB69191; Mon, 20 Sep 2021 19:38:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cvkzhpfs"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1168A69189 for ; Mon, 20 Sep 2021 19:38:05 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0A0713058; Mon, 20 Sep 2021 19:38:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159484; bh=XVQt9uonzQXaBEPksRJEfGUehrZ3CroApZEdsp7mFxE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cvkzhpfshlVPot8rsHVfKQzqCk/UQgSYKjP661bTWBb2Gr3HSlyybo+AW+C+LozqP iQEXuUdUJOTqijpszzFHNHd5eFeDdDTQPL4uNX5DHx2Q9OeGFULU6gkzSUPuP/a4yR 9Y2YsK8W0aMwif9kXRrnyYDJywZALFxrXI2H3XDw= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:44 +0530 Message-Id: <20210920173752.1346190-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 02/10] android: camera_device: Transform descriptors_ map to queue 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The descriptors_ map hold Camera3RequestDescriptor(s) which are per-capture request placed by the framework to libcamera HAL. CameraDevice::requestComplete() looks for the descriptor for which the camera request has been completed and removes it from the map. However, this approach has its limitations going forwards. In subsequent commits, the post-processing operation which happens in requestComplete() synchronously, is going to be run asynchronously. Therefore, instead of a map for descriptors, a queue makes more sense going forwards and the framework expects capture results to be received in the same order as they were queued. When the async processing is completed, the descriptor queue is inspected to send back the capture results and then de-queued. This helps to maintain the order of sending back the capture results whilst preventing unnecessary complexity of using a map. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart --- src/android/camera_device.cpp | 89 ++++++++++++++++++----------------- src/android/camera_device.h | 5 +- 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index f461e14c..0562c225 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -926,7 +926,9 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * The descriptor and the associated memory reserved here are freed * at request complete time. */ - Camera3RequestDescriptor descriptor(camera_.get(), camera3Request); + std::unique_ptr descriptor = + std::make_unique(camera_.get(), + camera3Request); /* * \todo The Android request model is incremental, settings passed in @@ -937,12 +939,12 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques if (camera3Request->settings) lastSettings_ = camera3Request->settings; else - descriptor.settings_ = lastSettings_; + descriptor->settings_ = lastSettings_; - LOG(HAL, Debug) << "Queueing request " << descriptor.request_->cookie() - << " with " << descriptor.buffers_.size() << " streams"; - for (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) { - const camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i]; + LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie() + << " with " << descriptor->buffers_.size() << " streams"; + for (unsigned int i = 0; i < descriptor->buffers_.size(); ++i) { + const camera3_stream_buffer_t &camera3Buffer = descriptor->buffers_[i]; camera3_stream *camera3Stream = camera3Buffer.stream; CameraStream *cameraStream = static_cast(camera3Stream->priv); @@ -977,7 +979,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques buffer = createFrameBuffer(*camera3Buffer.buffer, cameraStream->configuration().pixelFormat, cameraStream->configuration().size); - descriptor.frameBuffers_.emplace_back(buffer); + descriptor->frameBuffers_.emplace_back(buffer); LOG(HAL, Debug) << ss.str() << " (direct)"; break; @@ -999,7 +1001,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques return -ENOMEM; } - descriptor.request_->addBuffer(cameraStream->stream(), buffer, + descriptor->request_->addBuffer(cameraStream->stream(), buffer, camera3Buffer.acquire_fence); } @@ -1007,7 +1009,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * Translate controls from Android to libcamera and queue the request * to the CameraWorker thread. */ - int ret = processControls(&descriptor); + int ret = processControls(descriptor.get()); if (ret) return ret; @@ -1035,11 +1037,11 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques state_ = State::Running; } - worker_.queueRequest(descriptor.request_.get()); + worker_.queueRequest(descriptor->request_.get()); { MutexLocker descriptorsLock(descriptorsMutex_); - descriptors_[descriptor.request_->cookie()] = std::move(descriptor); + descriptors_.push_back(std::move(descriptor)); } return 0; @@ -1047,26 +1049,22 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques void CameraDevice::requestComplete(Request *request) { - decltype(descriptors_)::node_type node; - { - MutexLocker descriptorsLock(descriptorsMutex_); - auto it = descriptors_.find(request->cookie()); - if (it == descriptors_.end()) { - /* - * \todo Clarify if the Camera has to be closed on - * ERROR_DEVICE and possibly demote the Fatal to simple - * Error. - */ - notifyError(0, nullptr, CAMERA3_MSG_ERROR_DEVICE); - LOG(HAL, Fatal) - << "Unknown request: " << request->cookie(); + if (descriptors_.empty()) + return; - return; - } + Camera3RequestDescriptor *descriptor = descriptors_.front().get(); + if (descriptor->request_->cookie() != request->cookie()) { + /* + * \todo Clarify if the Camera has to be closed on + * ERROR_DEVICE and possibly demote the Fatal to simple + * Error. + */ + notifyError(0, nullptr, CAMERA3_MSG_ERROR_DEVICE); + LOG(HAL, Fatal) + << "Unknown request: " << request->cookie(); - node = descriptors_.extract(it); + return; } - Camera3RequestDescriptor &descriptor = node.mapped(); /* * Prepare the capture result for the Android camera stack. @@ -1075,14 +1073,14 @@ void CameraDevice::requestComplete(Request *request) * post-processing/compression fails. */ camera3_capture_result_t captureResult = {}; - captureResult.frame_number = descriptor.frameNumber_; - captureResult.num_output_buffers = descriptor.buffers_.size(); - for (camera3_stream_buffer_t &buffer : descriptor.buffers_) { + captureResult.frame_number = descriptor->frameNumber_; + captureResult.num_output_buffers = descriptor->buffers_.size(); + for (camera3_stream_buffer_t &buffer : descriptor->buffers_) { buffer.acquire_fence = -1; buffer.release_fence = -1; buffer.status = CAMERA3_BUFFER_STATUS_OK; } - captureResult.output_buffers = descriptor.buffers_.data(); + captureResult.output_buffers = descriptor->buffers_.data(); captureResult.partial_result = 1; /* @@ -1094,14 +1092,15 @@ void CameraDevice::requestComplete(Request *request) << " not successfully completed: " << request->status(); - notifyError(descriptor.frameNumber_, nullptr, + notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_REQUEST); captureResult.partial_result = 0; - for (camera3_stream_buffer_t &buffer : descriptor.buffers_) + for (camera3_stream_buffer_t &buffer : descriptor->buffers_) buffer.status = CAMERA3_BUFFER_STATUS_ERROR; callbacks_->process_capture_result(callbacks_, &captureResult); + descriptors_.pop_front(); return; } @@ -1113,10 +1112,10 @@ void CameraDevice::requestComplete(Request *request) */ uint64_t sensorTimestamp = static_cast(request->metadata() .get(controls::SensorTimestamp)); - notifyShutter(descriptor.frameNumber_, sensorTimestamp); + notifyShutter(descriptor->frameNumber_, sensorTimestamp); LOG(HAL, Debug) << "Request " << request->cookie() << " completed with " - << descriptor.buffers_.size() << " streams"; + << descriptor->buffers_.size() << " streams"; /* * Generate the metadata associated with the captured buffers. @@ -1126,14 +1125,14 @@ void CameraDevice::requestComplete(Request *request) */ std::unique_ptr resultMetadata = getResultMetadata(descriptor); if (!resultMetadata) { - notifyError(descriptor.frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT); + notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_RESULT); /* The camera framework expects an empty metadata pack on error. */ resultMetadata = std::make_unique(0, 0); } /* Handle any JPEG compression. */ - for (camera3_stream_buffer_t &buffer : descriptor.buffers_) { + for (camera3_stream_buffer_t &buffer : descriptor->buffers_) { CameraStream *cameraStream = static_cast(buffer.stream->priv); @@ -1144,13 +1143,13 @@ void CameraDevice::requestComplete(Request *request) if (!src) { LOG(HAL, Error) << "Failed to find a source stream buffer"; buffer.status = CAMERA3_BUFFER_STATUS_ERROR; - notifyError(descriptor.frameNumber_, buffer.stream, + notifyError(descriptor->frameNumber_, buffer.stream, CAMERA3_MSG_ERROR_BUFFER); continue; } int ret = cameraStream->process(*src, *buffer.buffer, - descriptor.settings_, + descriptor->settings_, resultMetadata.get()); /* * Return the FrameBuffer to the CameraStream now that we're @@ -1161,13 +1160,15 @@ void CameraDevice::requestComplete(Request *request) if (ret) { buffer.status = CAMERA3_BUFFER_STATUS_ERROR; - notifyError(descriptor.frameNumber_, buffer.stream, + notifyError(descriptor->frameNumber_, buffer.stream, CAMERA3_MSG_ERROR_BUFFER); } } captureResult.result = resultMetadata->get(); callbacks_->process_capture_result(callbacks_, &captureResult); + + descriptors_.pop_front(); } std::string CameraDevice::logPrefix() const @@ -1203,10 +1204,10 @@ void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream, * Produce a set of fixed result metadata. */ std::unique_ptr -CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) const +CameraDevice::getResultMetadata(const Camera3RequestDescriptor *descriptor) const { - const ControlList &metadata = descriptor.request_->metadata(); - const CameraMetadata &settings = descriptor.settings_; + const ControlList &metadata = descriptor->request_->metadata(); + const CameraMetadata &settings = descriptor->settings_; camera_metadata_ro_entry_t entry; bool found; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index a5576927..9c895b25 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -7,6 +7,7 @@ #ifndef __ANDROID_CAMERA_DEVICE_H__ #define __ANDROID_CAMERA_DEVICE_H__ +#include #include #include #include @@ -103,7 +104,7 @@ private: camera3_error_msg_code code); int processControls(Camera3RequestDescriptor *descriptor); std::unique_ptr getResultMetadata( - const Camera3RequestDescriptor &descriptor) const; + const Camera3RequestDescriptor *descriptor) const; unsigned int id_; camera3_device_t camera3Device_; @@ -123,7 +124,7 @@ private: std::vector streams_; libcamera::Mutex descriptorsMutex_; /* Protects descriptors_. */ - std::map descriptors_; + std::deque> descriptors_; std::string maker_; std::string model_; From patchwork Mon Sep 20 17:37:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13867 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 E4DF1BF01C for ; Mon, 20 Sep 2021 17:38:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 79BBB69195; Mon, 20 Sep 2021 19:38:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="E1F1FbIX"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 243AA69186 for ; Mon, 20 Sep 2021 19:38:07 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E792C45E; Mon, 20 Sep 2021 19:38:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159486; bh=AZ4shfI1j7wIHYA95PZCNq1+UvawRpNzWjF54317iuc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E1F1FbIXCkeiLssdXRiilu5eaCsr+co5KTt7XKlmiuZAKaz7X5Aim1/668DRkngSH feRiHqtfcOFBDPRz50rZ2Njd03AGvguP0xm+RkWDD6R2yOTTpONt9Cov7zRaUcOoJv gYDf+7Z/KQqgUdrA4ywMLXWbcyF5kaSUFUJinbdE= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:45 +0530 Message-Id: <20210920173752.1346190-4-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 03/10] android: camera_stream: Pass FrameBuffer pointer instead of reference 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Pass the libcamera::FrameBuffer pointer to the post-processor instead of passing it by reference. Passing by reference is fine as long as the post processing is done synchronously. However in subsequent commits, the post processing is planned to be moved to a separate thread. The reference argument (in current case 'source') is copied when we will try to invoke a method on separate thread (which will run the post-processor) using Object::invokeMethod(). As the 'source' is an instance of FrameBuffer class, which is restricted by LIBCAMERA_DISABLE_COPY_AND_MOVE, passing the reference to Object::invokeMethod() will try to copy it. Hence to avoid this copy, pass in the FrameBuffer pointer instead of reference. This requires changes to the existing PostProcessor interface and all its implemented classes. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 2 +- src/android/camera_stream.cpp | 2 +- src/android/camera_stream.h | 2 +- src/android/jpeg/encoder.h | 2 +- src/android/jpeg/encoder_libjpeg.cpp | 4 ++-- src/android/jpeg/encoder_libjpeg.h | 2 +- src/android/jpeg/post_processor_jpeg.cpp | 4 ++-- src/android/jpeg/post_processor_jpeg.h | 4 ++-- src/android/jpeg/thumbnailer.cpp | 4 ++-- src/android/jpeg/thumbnailer.h | 2 +- src/android/post_processor.h | 2 +- src/android/yuv/post_processor_yuv.cpp | 18 +++++++++--------- src/android/yuv/post_processor_yuv.h | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 0562c225..cc078fe4 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1148,7 +1148,7 @@ void CameraDevice::requestComplete(Request *request) continue; } - int ret = cameraStream->process(*src, *buffer.buffer, + int ret = cameraStream->process(src, *buffer.buffer, descriptor->settings_, resultMetadata.get()); /* diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index 0f5ae947..0fed5382 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -98,7 +98,7 @@ int CameraStream::configure() return 0; } -int CameraStream::process(const FrameBuffer &source, +int CameraStream::process(const FrameBuffer *source, buffer_handle_t camera3Dest, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata) diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 2dab6c3a..5c232cb6 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -118,7 +118,7 @@ public: libcamera::Stream *stream() const; int configure(); - int process(const libcamera::FrameBuffer &source, + int process(const libcamera::FrameBuffer *source, buffer_handle_t camera3Dest, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata); diff --git a/src/android/jpeg/encoder.h b/src/android/jpeg/encoder.h index a28522f4..7b6140e7 100644 --- a/src/android/jpeg/encoder.h +++ b/src/android/jpeg/encoder.h @@ -18,7 +18,7 @@ public: virtual ~Encoder() = default; virtual int configure(const libcamera::StreamConfiguration &cfg) = 0; - virtual int encode(const libcamera::FrameBuffer &source, + virtual int encode(const libcamera::FrameBuffer *source, libcamera::Span destination, libcamera::Span exifData, unsigned int quality) = 0; diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index 21a3b33d..3114ed4b 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -178,10 +178,10 @@ void EncoderLibJpeg::compressNV(const std::vector> &planes) } } -int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, +int EncoderLibJpeg::encode(const FrameBuffer *source, Span dest, Span exifData, unsigned int quality) { - MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); + MappedFrameBuffer frame(source, MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { LOG(JPEG, Error) << "Failed to map FrameBuffer : " << strerror(frame.error()); diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 45ffbd7f..ae4e1e32 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -22,7 +22,7 @@ public: ~EncoderLibJpeg(); int configure(const libcamera::StreamConfiguration &cfg) override; - int encode(const libcamera::FrameBuffer &source, + int encode(const libcamera::FrameBuffer *source, libcamera::Span destination, libcamera::Span exifData, unsigned int quality) override; diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index ef2d98cc..cb45f86b 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -50,7 +50,7 @@ int PostProcessorJpeg::configure(const StreamConfiguration &inCfg, return encoder_->configure(inCfg); } -void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source, +void PostProcessorJpeg::generateThumbnail(const FrameBuffer *source, const Size &targetSize, unsigned int quality, std::vector *thumbnail) @@ -97,7 +97,7 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source, } } -int PostProcessorJpeg::process(const FrameBuffer &source, +int PostProcessorJpeg::process(const FrameBuffer *source, CameraBuffer *destination, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata) diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h index 6fd31022..c4b2e9ef 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -22,13 +22,13 @@ public: int configure(const libcamera::StreamConfiguration &incfg, const libcamera::StreamConfiguration &outcfg) override; - int process(const libcamera::FrameBuffer &source, + int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata) override; private: - void generateThumbnail(const libcamera::FrameBuffer &source, + void generateThumbnail(const libcamera::FrameBuffer *source, const libcamera::Size &targetSize, unsigned int quality, std::vector *thumbnail); diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp index 1fab8072..ffac6a15 100644 --- a/src/android/jpeg/thumbnailer.cpp +++ b/src/android/jpeg/thumbnailer.cpp @@ -37,11 +37,11 @@ void Thumbnailer::configure(const Size &sourceSize, PixelFormat pixelFormat) valid_ = true; } -void Thumbnailer::createThumbnail(const FrameBuffer &source, +void Thumbnailer::createThumbnail(const FrameBuffer *source, const Size &targetSize, std::vector *destination) { - MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); + MappedFrameBuffer frame(source, MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { LOG(Thumbnailer, Error) << "Failed to map FrameBuffer : " diff --git a/src/android/jpeg/thumbnailer.h b/src/android/jpeg/thumbnailer.h index 4d086c49..0f3caf40 100644 --- a/src/android/jpeg/thumbnailer.h +++ b/src/android/jpeg/thumbnailer.h @@ -19,7 +19,7 @@ public: void configure(const libcamera::Size &sourceSize, libcamera::PixelFormat pixelFormat); - void createThumbnail(const libcamera::FrameBuffer &source, + void createThumbnail(const libcamera::FrameBuffer *source, const libcamera::Size &targetSize, std::vector *dest); const libcamera::PixelFormat &pixelFormat() const { return pixelFormat_; } diff --git a/src/android/post_processor.h b/src/android/post_processor.h index ab2b2c60..61dfb6d4 100644 --- a/src/android/post_processor.h +++ b/src/android/post_processor.h @@ -21,7 +21,7 @@ public: virtual int configure(const libcamera::StreamConfiguration &inCfg, const libcamera::StreamConfiguration &outCfg) = 0; - virtual int process(const libcamera::FrameBuffer &source, + virtual int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata) = 0; diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp index 7b3b4960..0a874886 100644 --- a/src/android/yuv/post_processor_yuv.cpp +++ b/src/android/yuv/post_processor_yuv.cpp @@ -49,7 +49,7 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg, return 0; } -int PostProcessorYuv::process(const FrameBuffer &source, +int PostProcessorYuv::process(const FrameBuffer *source, CameraBuffer *destination, [[maybe_unused]] const CameraMetadata &requestMetadata, [[maybe_unused]] CameraMetadata *metadata) @@ -57,7 +57,7 @@ int PostProcessorYuv::process(const FrameBuffer &source, if (!isValidBuffers(source, *destination)) return -EINVAL; - const MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read); + const MappedFrameBuffer sourceMapped(source, MappedFrameBuffer::MapFlag::Read); if (!sourceMapped.isValid()) { LOG(YUV, Error) << "Failed to mmap camera frame buffer"; return -EINVAL; @@ -83,12 +83,12 @@ int PostProcessorYuv::process(const FrameBuffer &source, return 0; } -bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source, +bool PostProcessorYuv::isValidBuffers(const FrameBuffer *source, const CameraBuffer &destination) const { - if (source.planes().size() != 2) { + if (source->planes().size() != 2) { LOG(YUV, Error) << "Invalid number of source planes: " - << source.planes().size(); + << source->planes().size(); return false; } if (destination.numPlanes() != 2) { @@ -97,12 +97,12 @@ bool PostProcessorYuv::isValidBuffers(const FrameBuffer &source, return false; } - if (source.planes()[0].length < sourceLength_[0] || - source.planes()[1].length < sourceLength_[1]) { + if (source->planes()[0].length < sourceLength_[0] || + source->planes()[1].length < sourceLength_[1]) { LOG(YUV, Error) << "The source planes lengths are too small, actual size: {" - << source.planes()[0].length << ", " - << source.planes()[1].length + << source->planes()[0].length << ", " + << source->planes()[1].length << "}, expected size: {" << sourceLength_[0] << ", " << sourceLength_[1] << "}"; diff --git a/src/android/yuv/post_processor_yuv.h b/src/android/yuv/post_processor_yuv.h index f8b1ba23..44a04113 100644 --- a/src/android/yuv/post_processor_yuv.h +++ b/src/android/yuv/post_processor_yuv.h @@ -20,13 +20,13 @@ public: int configure(const libcamera::StreamConfiguration &incfg, const libcamera::StreamConfiguration &outcfg) override; - int process(const libcamera::FrameBuffer &source, + int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, const CameraMetadata &requestMetadata, CameraMetadata *metadata) override; private: - bool isValidBuffers(const libcamera::FrameBuffer &source, + bool isValidBuffers(const libcamera::FrameBuffer *source, const CameraBuffer &destination) const; void calculateLengths(const libcamera::StreamConfiguration &inCfg, const libcamera::StreamConfiguration &outCfg); From patchwork Mon Sep 20 17:37:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13868 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 52AC3BF01C for ; Mon, 20 Sep 2021 17:38:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0A9706918E; Mon, 20 Sep 2021 19:38:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="OQKuGvq7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4454F69193 for ; Mon, 20 Sep 2021 19:38:09 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E33F045E; Mon, 20 Sep 2021 19:38:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159489; bh=LAi8gk29ROf52/Gv1fBFmEI1Bsw+/93HLXQ0pkKSPAs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OQKuGvq7y9FUSFYzwo2ryv4Lm+ukp0VI8481UOfwWpnXHCYOjgcZ5jAtP2PoMS4F9 gq89Qqi3lIKY5ALQ/MrRbIlqcDkhP8f8BgpWzO499XxP6xqTPzSIhputYvR5pg1yDt oZn8hijBVSXZx+d3/KqUBMVsvr/UPZFVSm242spY= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:46 +0530 Message-Id: <20210920173752.1346190-5-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 04/10] camera_device: Remove private scope of Camera3RequestDescriptor 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Camera3RequestDescriptor is a utility structure that groups information about a capture request. It can be and will be extended to preserve the context of a capture overall. Since the context of a capture needs to be shared among other classes (for e.g. CameraStream) having a private definition of the struct doesn't help. Hence, de-scope the structure so that it can be shared with other components (through references or pointers). Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 2 +- src/android/camera_device.h | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index cc078fe4..3d6a2bed 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -220,7 +220,7 @@ bool validateCropRotate(const camera3_stream_configuration_t &streamList) * later re-used at request complete time to notify the framework. */ -CameraDevice::Camera3RequestDescriptor::Camera3RequestDescriptor( +Camera3RequestDescriptor::Camera3RequestDescriptor( Camera *camera, const camera3_capture_request_t *camera3Request) { frameNumber_ = camera3Request->frame_number; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 9c895b25..59d6cd39 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -34,6 +34,21 @@ #include "jpeg/encoder.h" struct CameraConfigData; + +struct Camera3RequestDescriptor { + Camera3RequestDescriptor() = default; + ~Camera3RequestDescriptor() = default; + Camera3RequestDescriptor(libcamera::Camera *camera, + const camera3_capture_request_t *camera3Request); + Camera3RequestDescriptor &operator=(Camera3RequestDescriptor &&) = default; + + uint32_t frameNumber_ = 0; + std::vector buffers_; + std::vector> frameBuffers_; + CameraMetadata settings_; + std::unique_ptr request_; +}; + class CameraDevice : protected libcamera::Loggable { public: @@ -72,20 +87,6 @@ private: CameraDevice(unsigned int id, std::shared_ptr camera); - struct Camera3RequestDescriptor { - Camera3RequestDescriptor() = default; - ~Camera3RequestDescriptor() = default; - Camera3RequestDescriptor(libcamera::Camera *camera, - const camera3_capture_request_t *camera3Request); - Camera3RequestDescriptor &operator=(Camera3RequestDescriptor &&) = default; - - uint32_t frameNumber_ = 0; - std::vector buffers_; - std::vector> frameBuffers_; - CameraMetadata settings_; - std::unique_ptr request_; - }; - enum class State { Stopped, Flushing, From patchwork Mon Sep 20 17:37:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13869 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 0971DBF01C for ; Mon, 20 Sep 2021 17:38:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8D46569192; Mon, 20 Sep 2021 19:38:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="L8fEnt+L"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1BADF69186 for ; Mon, 20 Sep 2021 19:38:11 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 29CB445E; Mon, 20 Sep 2021 19:38:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159490; bh=3mnJFgNfPkK7W75ia59SaYjzKYVr84p1f8A8s0Hprhk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L8fEnt+LERMX2HtMjY9F6VMZUxqwkDrIwATBcwv3dCCds7j33U69N+8Bd15lhuROF ki4xMISyPrmh+PFTJAwiYUGxxPYhwvUYxsGMzR0hDhLFOD99ZGbxUA9B3Flw+Ac9eS NoJi2TQ9WcGgQA9VPRFtSOlWju6L4kJUxGYkz7dQ= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:47 +0530 Message-Id: <20210920173752.1346190-6-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 05/10] android: camera_device: Store results metadata into Camera3RequestDescriptor 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Store metadata which is sent as capture results into the Camera3RequestDescriptor. This is will remove the need to send the result metadata pointer separately to CameraStream::process(). In the subsequent commit, a Camera3RequestDescriptor pointer will be passed to CameraStream::process() and the result metadata can be directly accessed from there. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 6 ++++-- src/android/camera_device.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 3d6a2bed..1ae4ac73 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1131,6 +1131,8 @@ void CameraDevice::requestComplete(Request *request) resultMetadata = std::make_unique(0, 0); } + descriptor->resultMetadata_ = std::move(resultMetadata); + /* Handle any JPEG compression. */ for (camera3_stream_buffer_t &buffer : descriptor->buffers_) { CameraStream *cameraStream = @@ -1150,7 +1152,7 @@ void CameraDevice::requestComplete(Request *request) int ret = cameraStream->process(src, *buffer.buffer, descriptor->settings_, - resultMetadata.get()); + descriptor->resultMetadata_.get()); /* * Return the FrameBuffer to the CameraStream now that we're * done processing it. @@ -1165,7 +1167,7 @@ void CameraDevice::requestComplete(Request *request) } } - captureResult.result = resultMetadata->get(); + captureResult.result = descriptor->resultMetadata_->get(); callbacks_->process_capture_result(callbacks_, &captureResult); descriptors_.pop_front(); diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 59d6cd39..b2871e52 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -47,6 +47,7 @@ struct Camera3RequestDescriptor { std::vector> frameBuffers_; CameraMetadata settings_; std::unique_ptr request_; + std::unique_ptr resultMetadata_; }; class CameraDevice : protected libcamera::Loggable From patchwork Mon Sep 20 17:37:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13870 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 BB2AFBF01C for ; Mon, 20 Sep 2021 17:38:15 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 71D376918F; Mon, 20 Sep 2021 19:38:15 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="YNG17aqv"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2341C6918F for ; Mon, 20 Sep 2021 19:38:13 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E80A345E; Mon, 20 Sep 2021 19:38:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159492; bh=MWmXhXrT2ZZjg1SG7A81WLvgNDlDwkV89K89gzYaHwE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YNG17aqvCr0iZN1BXcIZXASbM1YYI6qogoSqYnxH9tIZiX1/+Lh3N50tS9WctkIHE 17Y0UM3x1E4Y4n0z3BVdBQIsoPE84H1cABdzZDyck8ugQAKpDwPedlrvpb38jvji67 cJQ7oaCMEm3tYM1A+LKRIhKlTLDVhMfn7DCzhIzY= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:48 +0530 Message-Id: <20210920173752.1346190-7-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 06/10] android: camera_stream: Plumb process() with Camera3RequestDescriptor 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Data (or broader context) required for post processing of a camera request is saved via Camera3RequestDescriptor. Instead of passing individual arguments to CameraStream::process(), pass the Camera3RequestDescriptor pointer to it. All the arguments necessary to run the post-processor can be accessed from the descriptor. In subsequent commits, we will prepare the post-processor to run asynchronously. Hence, it will require the Camera3RequestDescriptor pointer to be emitted back in the post-processing completion handler to finally complete the request (i.e. sending the capture results back to the framework). Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 5 ++--- src/android/camera_stream.cpp | 5 ++--- src/android/camera_stream.h | 5 +++-- src/android/jpeg/post_processor_jpeg.cpp | 5 +++-- src/android/jpeg/post_processor_jpeg.h | 3 +-- src/android/post_processor.h | 5 +++-- src/android/yuv/post_processor_yuv.cpp | 3 +-- src/android/yuv/post_processor_yuv.h | 3 +-- 8 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 1ae4ac73..fa462368 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1150,9 +1150,8 @@ void CameraDevice::requestComplete(Request *request) continue; } - int ret = cameraStream->process(src, *buffer.buffer, - descriptor->settings_, - descriptor->resultMetadata_.get()); + int ret = cameraStream->process(src, *buffer.buffer, descriptor); + /* * Return the FrameBuffer to the CameraStream now that we're * done processing it. diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index 0fed5382..d494f5d5 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -100,8 +100,7 @@ int CameraStream::configure() int CameraStream::process(const FrameBuffer *source, buffer_handle_t camera3Dest, - const CameraMetadata &requestMetadata, - CameraMetadata *resultMetadata) + Camera3RequestDescriptor *request) { if (!postProcessor_) return 0; @@ -118,7 +117,7 @@ int CameraStream::process(const FrameBuffer *source, return -EINVAL; } - return postProcessor_->process(source, &dest, requestMetadata, resultMetadata); + return postProcessor_->process(source, &dest, request); } FrameBuffer *CameraStream::getBuffer() diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 5c232cb6..68789700 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -23,6 +23,8 @@ class CameraDevice; class CameraMetadata; class PostProcessor; +struct Camera3RequestDescriptor; + class CameraStream { public: @@ -120,8 +122,7 @@ public: int configure(); int process(const libcamera::FrameBuffer *source, buffer_handle_t camera3Dest, - const CameraMetadata &requestMetadata, - CameraMetadata *resultMetadata); + Camera3RequestDescriptor *request); libcamera::FrameBuffer *getBuffer(); void putBuffer(libcamera::FrameBuffer *buffer); diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index cb45f86b..31f68330 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -99,14 +99,15 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer *source, int PostProcessorJpeg::process(const FrameBuffer *source, CameraBuffer *destination, - const CameraMetadata &requestMetadata, - CameraMetadata *resultMetadata) + Camera3RequestDescriptor *request) { if (!encoder_) return 0; ASSERT(destination->numPlanes() == 1); + const CameraMetadata &requestMetadata = request->settings_; + CameraMetadata *resultMetadata = request->resultMetadata_.get(); camera_metadata_ro_entry_t entry; int ret; diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h index c4b2e9ef..d49c8d2b 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -24,8 +24,7 @@ public: const libcamera::StreamConfiguration &outcfg) override; int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, - const CameraMetadata &requestMetadata, - CameraMetadata *resultMetadata) override; + Camera3RequestDescriptor *request) override; private: void generateThumbnail(const libcamera::FrameBuffer *source, diff --git a/src/android/post_processor.h b/src/android/post_processor.h index 61dfb6d4..bdd6afe7 100644 --- a/src/android/post_processor.h +++ b/src/android/post_processor.h @@ -14,6 +14,8 @@ class CameraMetadata; +struct Camera3RequestDescriptor; + class PostProcessor { public: @@ -23,8 +25,7 @@ public: const libcamera::StreamConfiguration &outCfg) = 0; virtual int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, - const CameraMetadata &requestMetadata, - CameraMetadata *resultMetadata) = 0; + Camera3RequestDescriptor *request) = 0; }; #endif /* __ANDROID_POST_PROCESSOR_H__ */ diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp index 0a874886..5e18caee 100644 --- a/src/android/yuv/post_processor_yuv.cpp +++ b/src/android/yuv/post_processor_yuv.cpp @@ -51,8 +51,7 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg, int PostProcessorYuv::process(const FrameBuffer *source, CameraBuffer *destination, - [[maybe_unused]] const CameraMetadata &requestMetadata, - [[maybe_unused]] CameraMetadata *metadata) + [[maybe_unused]] Camera3RequestDescriptor *request) { if (!isValidBuffers(source, *destination)) return -EINVAL; diff --git a/src/android/yuv/post_processor_yuv.h b/src/android/yuv/post_processor_yuv.h index 44a04113..eddd1086 100644 --- a/src/android/yuv/post_processor_yuv.h +++ b/src/android/yuv/post_processor_yuv.h @@ -22,8 +22,7 @@ public: const libcamera::StreamConfiguration &outcfg) override; int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, - const CameraMetadata &requestMetadata, - CameraMetadata *metadata) override; + Camera3RequestDescriptor *context) override; private: bool isValidBuffers(const libcamera::FrameBuffer *source, From patchwork Mon Sep 20 17:37:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13871 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 184E3BF01C for ; Mon, 20 Sep 2021 17:38:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D92A369191; Mon, 20 Sep 2021 19:38:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="hvZt05rg"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0501D69188 for ; Mon, 20 Sep 2021 19:38:15 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ED54A45E; Mon, 20 Sep 2021 19:38:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159494; bh=otjbcXFzfV0R3vWLVQjawlrwWfIpS2GtnJkv5aBbcHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hvZt05rgNsC24DqKcxfSGlJWQ9EUddRKUX4Y+khsSnH+RH9BPq2N6urlI3Ge7taoB HXnTEYfpzyO3iDKP+kDVZ2N8dlcGL4iCeu+Uwod0IiM74VaCcPZulpKGpZZmVGt220 tJbm3rQX+k140F4ZQUS1TqaWohiAmIPJ9zAE7GMw= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:49 +0530 Message-Id: <20210920173752.1346190-8-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 07/10] android: post_processor: Notify post processing completion status 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" We should be able to know if post-processing has been completed successfully or encountered some errors. This commit introduces a Signal<> that will notify that the post-processing has been completed. If the post processing was successful, status on the request descriptor will be set to Camera3RequestDescriptor::ProcessStatus::Success. The signal will be required when the post-processor is meant to run asynchronously (in subsequent commits) and capture results need to be sent back to the framework from the signal's slot instead. Signed-off-by: Umang Jain --- src/android/camera_device.cpp | 18 ++++++++++++++++++ src/android/camera_device.h | 11 +++++++++++ src/android/camera_stream.cpp | 15 ++++++++++++++- src/android/camera_stream.h | 2 ++ src/android/jpeg/post_processor_jpeg.cpp | 10 +++++++++- src/android/post_processor.h | 4 ++++ src/android/yuv/post_processor_yuv.cpp | 16 ++++++++++++++-- 7 files changed, 72 insertions(+), 4 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index fa462368..e2de4012 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -246,6 +246,12 @@ Camera3RequestDescriptor::Camera3RequestDescriptor( */ request_ = std::make_unique(camera, reinterpret_cast(this)); + + /* + * Denotes the post-processing status required by any stream. It is set + * to ProcessStatus::Success if processing is successful. + */ + status_ = ProcessStatus::None; } /* @@ -1150,6 +1156,8 @@ void CameraDevice::requestComplete(Request *request) continue; } + descriptor->status_ = Camera3RequestDescriptor::ProcessStatus::Processing; + int ret = cameraStream->process(src, *buffer.buffer, descriptor); /* @@ -1172,6 +1180,16 @@ void CameraDevice::requestComplete(Request *request) descriptors_.pop_front(); } + +void CameraDevice::streamProcessingComplete([[maybe_unused]] CameraStream *cameraStream, + [[maybe_unused]] Camera3RequestDescriptor *request) +{ + /* + * \todo Stream processing is completed hence, check for errors and + * if any, mark the corresponding buffer with CAMERA3_BUFFER_STATUS_ERROR. + */ +} + std::string CameraDevice::logPrefix() const { return "'" + camera_->id() + "'"; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index b2871e52..60c134dc 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -36,6 +36,13 @@ struct CameraConfigData; struct Camera3RequestDescriptor { + enum class ProcessStatus { + None, + Processing, + Success, + Error + }; + Camera3RequestDescriptor() = default; ~Camera3RequestDescriptor() = default; Camera3RequestDescriptor(libcamera::Camera *camera, @@ -48,6 +55,8 @@ struct Camera3RequestDescriptor { CameraMetadata settings_; std::unique_ptr request_; std::unique_ptr resultMetadata_; + + ProcessStatus status_; }; class CameraDevice : protected libcamera::Loggable @@ -79,6 +88,8 @@ public: int configureStreams(camera3_stream_configuration_t *stream_list); int processCaptureRequest(camera3_capture_request_t *request); void requestComplete(libcamera::Request *request); + void streamProcessingComplete(CameraStream *cameraStream, + Camera3RequestDescriptor *request); protected: std::string logPrefix() const override; diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index d494f5d5..70471959 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -81,6 +81,9 @@ int CameraStream::configure() int ret = postProcessor_->configure(configuration(), output); if (ret) return ret; + + postProcessor_->processComplete.connect( + this, &CameraStream::handleProcessComplete); } if (allocator_) { @@ -102,8 +105,11 @@ int CameraStream::process(const FrameBuffer *source, buffer_handle_t camera3Dest, Camera3RequestDescriptor *request) { - if (!postProcessor_) + if (!postProcessor_) { + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + handleProcessComplete(request); return 0; + } /* * \todo Buffer mapping and processing should be moved to a @@ -114,12 +120,19 @@ int CameraStream::process(const FrameBuffer *source, PROT_READ | PROT_WRITE); if (!dest.isValid()) { LOG(HAL, Error) << "Failed to map android blob buffer"; + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + handleProcessComplete(request); return -EINVAL; } return postProcessor_->process(source, &dest, request); } +void CameraStream::handleProcessComplete(Camera3RequestDescriptor *request) +{ + cameraDevice_->streamProcessingComplete(this, request); +} + FrameBuffer *CameraStream::getBuffer() { if (!allocator_) diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 68789700..f8ad6245 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -127,6 +127,8 @@ public: void putBuffer(libcamera::FrameBuffer *buffer); private: + void handleProcessComplete(Camera3RequestDescriptor *request); + CameraDevice *const cameraDevice_; const libcamera::CameraConfiguration *config_; const Type type_; diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 31f68330..87252acd 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -101,8 +101,11 @@ int PostProcessorJpeg::process(const FrameBuffer *source, CameraBuffer *destination, Camera3RequestDescriptor *request) { - if (!encoder_) + if (!encoder_) { + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + processComplete.emit(request); return 0; + } ASSERT(destination->numPlanes() == 1); @@ -197,6 +200,8 @@ int PostProcessorJpeg::process(const FrameBuffer *source, exif.data(), quality); if (jpeg_size < 0) { LOG(JPEG, Error) << "Failed to encode stream image"; + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + processComplete.emit(request); return jpeg_size; } @@ -211,5 +216,8 @@ int PostProcessorJpeg::process(const FrameBuffer *source, /* Update the JPEG result Metadata. */ resultMetadata->addEntry(ANDROID_JPEG_SIZE, jpeg_size); + request->status_ = Camera3RequestDescriptor::ProcessStatus::Success; + processComplete.emit(request); + return 0; } diff --git a/src/android/post_processor.h b/src/android/post_processor.h index bdd6afe7..f639b237 100644 --- a/src/android/post_processor.h +++ b/src/android/post_processor.h @@ -7,6 +7,8 @@ #ifndef __ANDROID_POST_PROCESSOR_H__ #define __ANDROID_POST_PROCESSOR_H__ +#include + #include #include @@ -26,6 +28,8 @@ public: virtual int process(const libcamera::FrameBuffer *source, CameraBuffer *destination, Camera3RequestDescriptor *request) = 0; + + libcamera::Signal processComplete; }; #endif /* __ANDROID_POST_PROCESSOR_H__ */ diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp index 5e18caee..b144649a 100644 --- a/src/android/yuv/post_processor_yuv.cpp +++ b/src/android/yuv/post_processor_yuv.cpp @@ -18,6 +18,8 @@ #include "libcamera/internal/formats.h" #include "libcamera/internal/mapped_framebuffer.h" +#include "../camera_device.h" + using namespace libcamera; LOG_DEFINE_CATEGORY(YUV) @@ -51,14 +53,19 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg, int PostProcessorYuv::process(const FrameBuffer *source, CameraBuffer *destination, - [[maybe_unused]] Camera3RequestDescriptor *request) + Camera3RequestDescriptor *request) { - if (!isValidBuffers(source, *destination)) + if (!isValidBuffers(source, *destination)) { + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + processComplete.emit(request); return -EINVAL; + } const MappedFrameBuffer sourceMapped(source, MappedFrameBuffer::MapFlag::Read); if (!sourceMapped.isValid()) { LOG(YUV, Error) << "Failed to mmap camera frame buffer"; + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + processComplete.emit(request); return -EINVAL; } @@ -76,9 +83,14 @@ int PostProcessorYuv::process(const FrameBuffer *source, libyuv::FilterMode::kFilterBilinear); if (ret) { LOG(YUV, Error) << "Failed NV12 scaling: " << ret; + request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; + processComplete.emit(request); return -EINVAL; } + request->status_ = Camera3RequestDescriptor::ProcessStatus::Success; + processComplete.emit(request); + return 0; } From patchwork Mon Sep 20 17:37:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13872 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 A4F97BF01C for ; Mon, 20 Sep 2021 17:38:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6BCCD6919A; Mon, 20 Sep 2021 19:38:18 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WjTd72QG"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B2C436918A for ; Mon, 20 Sep 2021 19:38:16 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B39CE45E; Mon, 20 Sep 2021 19:38:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159496; bh=NodJbV49AofcC4UIUTM3F8u44WF85VPPDRG5zjG7GA4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WjTd72QGDgWqnGt9jQvwSkO+VqhfAGHJo4mM+tbTWztxiKKYng/2aTC6o1lbJEYUZ qozoWN6JvBJ852CbrOH778EuY+9cirbmOam1SeASl4cGRwjFEzkvVYIyL/yX1aW8nl peaM5KF/iMpU7H2QdlfZuxbaIqxPfQ0JvnLXZ+HY= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:50 +0530 Message-Id: <20210920173752.1346190-9-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 08/10] android: camera_stream: Drop return value for process() 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" CameraStream::process() is invoked by CameraDevice::requestComplete() in case any post-processing is required for the camera stream. The failure or success is checked via the value returned by CameraStream::process(). Now that the post-processor notifies about the post-processing completion operation and sets the ProcessStatus on the Camera3RequestDescriptor passed to it, we can drop the return value of CameraStream::process() in favour of reading the process status set on the descriptor in the PostProcessor::processComplete's slot. Signed-off-by: Umang Jain --- src/android/camera_device.cpp | 26 +++++++++++++----------- src/android/camera_stream.cpp | 12 +++++------ src/android/camera_stream.h | 6 +++--- src/android/jpeg/post_processor_jpeg.cpp | 12 +++++------ src/android/jpeg/post_processor_jpeg.h | 6 +++--- src/android/post_processor.h | 6 +++--- src/android/yuv/post_processor_yuv.cpp | 14 ++++++------- src/android/yuv/post_processor_yuv.h | 6 +++--- 8 files changed, 43 insertions(+), 45 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index e2de4012..4658e881 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1158,7 +1158,7 @@ void CameraDevice::requestComplete(Request *request) descriptor->status_ = Camera3RequestDescriptor::ProcessStatus::Processing; - int ret = cameraStream->process(src, *buffer.buffer, descriptor); + cameraStream->process(src, *buffer.buffer, descriptor); /* * Return the FrameBuffer to the CameraStream now that we're @@ -1166,12 +1166,6 @@ void CameraDevice::requestComplete(Request *request) */ if (cameraStream->type() == CameraStream::Type::Internal) cameraStream->putBuffer(src); - - if (ret) { - buffer.status = CAMERA3_BUFFER_STATUS_ERROR; - notifyError(descriptor->frameNumber_, buffer.stream, - CAMERA3_MSG_ERROR_BUFFER); - } } captureResult.result = descriptor->resultMetadata_->get(); @@ -1182,12 +1176,20 @@ void CameraDevice::requestComplete(Request *request) void CameraDevice::streamProcessingComplete([[maybe_unused]] CameraStream *cameraStream, - [[maybe_unused]] Camera3RequestDescriptor *request) + Camera3RequestDescriptor *request) { - /* - * \todo Stream processing is completed hence, check for errors and - * if any, mark the corresponding buffer with CAMERA3_BUFFER_STATUS_ERROR. - */ + if (request->status_ == Camera3RequestDescriptor::ProcessStatus::Error) { + for (camera3_stream_buffer_t &buffer : request->buffers_) { + CameraStream *cs = static_cast(buffer.stream->priv); + + if (cs->camera3Stream().format != HAL_PIXEL_FORMAT_BLOB) + continue; + + buffer.status = CAMERA3_BUFFER_STATUS_ERROR; + notifyError(request->frameNumber_, buffer.stream, + CAMERA3_MSG_ERROR_BUFFER); + } + } } std::string CameraDevice::logPrefix() const diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index 70471959..c18c7041 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -101,14 +101,14 @@ int CameraStream::configure() return 0; } -int CameraStream::process(const FrameBuffer *source, - buffer_handle_t camera3Dest, - Camera3RequestDescriptor *request) +void CameraStream::process(const FrameBuffer *source, + buffer_handle_t camera3Dest, + Camera3RequestDescriptor *request) { if (!postProcessor_) { request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; handleProcessComplete(request); - return 0; + return; } /* @@ -122,10 +122,10 @@ int CameraStream::process(const FrameBuffer *source, LOG(HAL, Error) << "Failed to map android blob buffer"; request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; handleProcessComplete(request); - return -EINVAL; + return; } - return postProcessor_->process(source, &dest, request); + postProcessor_->process(source, &dest, request); } void CameraStream::handleProcessComplete(Camera3RequestDescriptor *request) diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index f8ad6245..d4ec5c25 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -120,9 +120,9 @@ public: libcamera::Stream *stream() const; int configure(); - int process(const libcamera::FrameBuffer *source, - buffer_handle_t camera3Dest, - Camera3RequestDescriptor *request); + void process(const libcamera::FrameBuffer *source, + buffer_handle_t camera3Dest, + Camera3RequestDescriptor *request); libcamera::FrameBuffer *getBuffer(); void putBuffer(libcamera::FrameBuffer *buffer); diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp index 87252acd..19eb7983 100644 --- a/src/android/jpeg/post_processor_jpeg.cpp +++ b/src/android/jpeg/post_processor_jpeg.cpp @@ -97,14 +97,14 @@ void PostProcessorJpeg::generateThumbnail(const FrameBuffer *source, } } -int PostProcessorJpeg::process(const FrameBuffer *source, - CameraBuffer *destination, - Camera3RequestDescriptor *request) +void PostProcessorJpeg::process(const FrameBuffer *source, + CameraBuffer *destination, + Camera3RequestDescriptor *request) { if (!encoder_) { request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; processComplete.emit(request); - return 0; + return; } ASSERT(destination->numPlanes() == 1); @@ -202,7 +202,7 @@ int PostProcessorJpeg::process(const FrameBuffer *source, LOG(JPEG, Error) << "Failed to encode stream image"; request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; processComplete.emit(request); - return jpeg_size; + return; } /* Fill in the JPEG blob header. */ @@ -218,6 +218,4 @@ int PostProcessorJpeg::process(const FrameBuffer *source, request->status_ = Camera3RequestDescriptor::ProcessStatus::Success; processComplete.emit(request); - - return 0; } diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h index d49c8d2b..e9938919 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -22,9 +22,9 @@ public: int configure(const libcamera::StreamConfiguration &incfg, const libcamera::StreamConfiguration &outcfg) override; - int process(const libcamera::FrameBuffer *source, - CameraBuffer *destination, - Camera3RequestDescriptor *request) override; + void process(const libcamera::FrameBuffer *source, + CameraBuffer *destination, + Camera3RequestDescriptor *request) override; private: void generateThumbnail(const libcamera::FrameBuffer *source, diff --git a/src/android/post_processor.h b/src/android/post_processor.h index f639b237..48ddd8ac 100644 --- a/src/android/post_processor.h +++ b/src/android/post_processor.h @@ -25,9 +25,9 @@ public: virtual int configure(const libcamera::StreamConfiguration &inCfg, const libcamera::StreamConfiguration &outCfg) = 0; - virtual int process(const libcamera::FrameBuffer *source, - CameraBuffer *destination, - Camera3RequestDescriptor *request) = 0; + virtual void process(const libcamera::FrameBuffer *source, + CameraBuffer *destination, + Camera3RequestDescriptor *request) = 0; libcamera::Signal processComplete; }; diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp index b144649a..09838aa5 100644 --- a/src/android/yuv/post_processor_yuv.cpp +++ b/src/android/yuv/post_processor_yuv.cpp @@ -51,14 +51,14 @@ int PostProcessorYuv::configure(const StreamConfiguration &inCfg, return 0; } -int PostProcessorYuv::process(const FrameBuffer *source, - CameraBuffer *destination, - Camera3RequestDescriptor *request) +void PostProcessorYuv::process(const FrameBuffer *source, + CameraBuffer *destination, + Camera3RequestDescriptor *request) { if (!isValidBuffers(source, *destination)) { request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; processComplete.emit(request); - return -EINVAL; + return; } const MappedFrameBuffer sourceMapped(source, MappedFrameBuffer::MapFlag::Read); @@ -66,7 +66,7 @@ int PostProcessorYuv::process(const FrameBuffer *source, LOG(YUV, Error) << "Failed to mmap camera frame buffer"; request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; processComplete.emit(request); - return -EINVAL; + return; } int ret = libyuv::NV12Scale(sourceMapped.planes()[0].data(), @@ -85,13 +85,11 @@ int PostProcessorYuv::process(const FrameBuffer *source, LOG(YUV, Error) << "Failed NV12 scaling: " << ret; request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; processComplete.emit(request); - return -EINVAL; + return; } request->status_ = Camera3RequestDescriptor::ProcessStatus::Success; processComplete.emit(request); - - return 0; } bool PostProcessorYuv::isValidBuffers(const FrameBuffer *source, diff --git a/src/android/yuv/post_processor_yuv.h b/src/android/yuv/post_processor_yuv.h index eddd1086..32e5b60d 100644 --- a/src/android/yuv/post_processor_yuv.h +++ b/src/android/yuv/post_processor_yuv.h @@ -20,9 +20,9 @@ public: int configure(const libcamera::StreamConfiguration &incfg, const libcamera::StreamConfiguration &outcfg) override; - int process(const libcamera::FrameBuffer *source, - CameraBuffer *destination, - Camera3RequestDescriptor *context) override; + void process(const libcamera::FrameBuffer *source, + CameraBuffer *destination, + Camera3RequestDescriptor *context) override; private: bool isValidBuffers(const libcamera::FrameBuffer *source, From patchwork Mon Sep 20 17:37:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13873 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 7B01FBF01C for ; Mon, 20 Sep 2021 17:38:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3AE5269190; Mon, 20 Sep 2021 19:38:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="IpDitSvj"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6034969199 for ; Mon, 20 Sep 2021 19:38:18 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5CB0A45E; Mon, 20 Sep 2021 19:38:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159498; bh=nLP58YsDKIF7yn5cRXa8rn+Hp3N35MqBoz+xB0SL5u4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IpDitSvjIrqDaAx6x+sPbd+loqW0s49XeQHxV6NKzKvvCtpmjOHuGigSaU25V3u18 tnoBnRm0IW1oRRdPj2LpA/Dpwb//Vd3w4BFBgrlvBj/+3EGr1tK0/dHJfci28pL3OQ 186V6JOxvq82pDdvyN/QbQV31iGxmqK3FkYc1xxs= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:51 +0530 Message-Id: <20210920173752.1346190-10-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 09/10] android: camera_device: Send capture results inspecting the descriptor 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 --- 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 (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 request_; std::unique_ptr resultMetadata_; + camera3_capture_result_t captureResult_ = {}; + libcamera::FrameBuffer *internalBuffer_; + ProcessStatus status_; }; @@ -118,6 +121,7 @@ private: int processControls(Camera3RequestDescriptor *descriptor); std::unique_ptr getResultMetadata( const Camera3RequestDescriptor *descriptor) const; + void sendCaptureResults(); unsigned int id_; camera3_device_t camera3Device_; From patchwork Mon Sep 20 17:37:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 13874 X-Patchwork-Delegate: umang.jain@ideasonboard.com 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 0564BBF01C for ; Mon, 20 Sep 2021 17:38:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AF2686918E; Mon, 20 Sep 2021 19:38:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lUyrnocf"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 36B356918F for ; Mon, 20 Sep 2021 19:38:20 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.251.226.144]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2FEA745E; Mon, 20 Sep 2021 19:38:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1632159500; bh=0TR32C93mMbOXb1KbT3dgwFoknIVPBIG8oc9sLKNYUQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lUyrnocfHkZrfkUxRVoIA9lLQLh+XRSbqwRIN9qdY250NllpJj5zv9y9+xMorn9dq fBpRb/npwk7S5rGbxB2Uf0kr9qbxALIdyFG8fQpmrtacdwx/tMNQoqNIgR9cStN7z3 LRKwj7VKC/edj9JqxUSCpSpXNr48fLWIdaNfHtQM= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Sep 2021 23:07:52 +0530 Message-Id: <20210920173752.1346190-11-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210920173752.1346190-1-umang.jain@ideasonboard.com> References: <20210920173752.1346190-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 10/10] android: camera_stream: Run post processor in a thread 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This commit makes the post processor run in a separate thread. To enable the move to a separate thread, he post processor needs to be inherited from libcamera::Object and use the Object::moveToThread() API to execute the move. A user defined destructor is introduced to stop the thread for cleanup. Since CameraStream is move-constructible and compiler implicitly generates its constructor, defining a destructor will prevent the compiler from adding an implicitly-declared move constructor. Therefore, we need to explicitly add a move constructor as well. Also, the destination buffer for post-processing needs to be alive and stored as a part of overall context, hence a CameraBuffer unique-pointer member is introduced in the Camera3RequestDescriptor struct. --- /* \todo Use ConnectionTypeQueued instead of ConnectionTypeBlocking */ --- Signed-off-by: Umang Jain --- src/android/camera_device.h | 2 ++ src/android/camera_stream.cpp | 29 +++++++++++++++++++++-------- src/android/camera_stream.h | 5 +++++ src/android/post_processor.h | 3 ++- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 0bd570a1..e3f3fe7c 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -27,6 +27,7 @@ #include #include +#include "camera_buffer.h" #include "camera_capabilities.h" #include "camera_metadata.h" #include "camera_stream.h" @@ -55,6 +56,7 @@ struct Camera3RequestDescriptor { CameraMetadata settings_; std::unique_ptr request_; std::unique_ptr resultMetadata_; + std::unique_ptr destBuffer_; camera3_capture_result_t captureResult_ = {}; libcamera::FrameBuffer *internalBuffer_; diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index c18c7041..6578ce09 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -55,6 +55,9 @@ CameraStream::CameraStream(CameraDevice *const cameraDevice, * is what we instantiate here. */ postProcessor_ = std::make_unique(cameraDevice_); + thread_ = std::make_unique(); + postProcessor_->moveToThread(thread_.get()); + thread_->start(); } if (type == Type::Internal) { @@ -63,6 +66,14 @@ CameraStream::CameraStream(CameraDevice *const cameraDevice, } } +CameraStream::~CameraStream() +{ + if (thread_) { + thread_->exit(); + thread_->wait(); + } +} + const StreamConfiguration &CameraStream::configuration() const { return config_->at(index_); @@ -111,21 +122,23 @@ void CameraStream::process(const FrameBuffer *source, return; } - /* - * \todo Buffer mapping and processing should be moved to a - * separate thread. - */ const StreamConfiguration &output = configuration(); - CameraBuffer dest(camera3Dest, formats::MJPEG, output.size, - PROT_READ | PROT_WRITE); - if (!dest.isValid()) { + std::unique_ptr dest = + std::make_unique(camera3Dest, formats::MJPEG, + output.size, PROT_READ | PROT_WRITE); + + if (!dest->isValid()) { LOG(HAL, Error) << "Failed to map android blob buffer"; request->status_ = Camera3RequestDescriptor::ProcessStatus::Error; handleProcessComplete(request); return; } + request->destBuffer_ = std::move(dest); - postProcessor_->process(source, &dest, request); + /* \todo Use ConnectionTypeQueued instead of ConnectionTypeBlocking */ + postProcessor_->invokeMethod(&PostProcessor::process, + ConnectionTypeBlocking, source, + request->destBuffer_.get(), request); } void CameraStream::handleProcessComplete(Camera3RequestDescriptor *request) diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index d4ec5c25..42db72d8 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -13,6 +13,8 @@ #include +#include + #include #include #include @@ -113,6 +115,8 @@ public: CameraStream(CameraDevice *const cameraDevice, libcamera::CameraConfiguration *config, Type type, camera3_stream_t *camera3Stream, unsigned int index); + CameraStream(CameraStream &&other) = default; + ~CameraStream(); Type type() const { return type_; } const camera3_stream_t &camera3Stream() const { return *camera3Stream_; } @@ -143,6 +147,7 @@ private: */ std::unique_ptr mutex_; std::unique_ptr postProcessor_; + std::unique_ptr thread_; }; #endif /* __ANDROID_CAMERA_STREAM__ */ diff --git a/src/android/post_processor.h b/src/android/post_processor.h index 48ddd8ac..fdfd52d3 100644 --- a/src/android/post_processor.h +++ b/src/android/post_processor.h @@ -7,6 +7,7 @@ #ifndef __ANDROID_POST_PROCESSOR_H__ #define __ANDROID_POST_PROCESSOR_H__ +#include #include #include @@ -18,7 +19,7 @@ class CameraMetadata; struct Camera3RequestDescriptor; -class PostProcessor +class PostProcessor : public libcamera::Object { public: virtual ~PostProcessor() = default;