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; }