Patch Detail
Show a patch.
GET /api/patches/13755/?format=api
{ "id": 13755, "url": "https://patchwork.libcamera.org/api/patches/13755/?format=api", "web_url": "https://patchwork.libcamera.org/patch/13755/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210907195704.338079-7-umang.jain@ideasonboard.com>", "date": "2021-09-07T19:57:04", "name": "[libcamera-devel,v1,6/6] android: camera_stream: Run post-processor in a separate thread", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "d54932a388d887583ee350ee5d53dadf01afa900", "submitter": { "id": 86, "url": "https://patchwork.libcamera.org/api/people/86/?format=api", "name": "Umang Jain", "email": "umang.jain@ideasonboard.com" }, "delegate": { "id": 12, "url": "https://patchwork.libcamera.org/api/users/12/?format=api", "username": "uajain", "first_name": "Umang", "last_name": "Jain", "email": "umang.jain@ideasonboard.com" }, "mbox": "https://patchwork.libcamera.org/patch/13755/mbox/", "series": [ { "id": 2493, "url": "https://patchwork.libcamera.org/api/series/2493/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2493", "date": "2021-09-07T19:56:58", "name": "Async post-processor", "version": 1, "mbox": "https://patchwork.libcamera.org/series/2493/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/13755/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/13755/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9F56EBDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 7 Sep 2021 19:57:32 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6F91B6916F;\n\tTue, 7 Sep 2021 21:57:32 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B4C646916C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 7 Sep 2021 21:57:30 +0200 (CEST)", "from perceval.ideasonboard.com (unknown [103.251.226.2])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id A198E499;\n\tTue, 7 Sep 2021 21:57:29 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"SwHjuvOC\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1631044650;\n\tbh=izciIO8uRaoT5jeJakvr4co67CIHwdBvEhRVlTOIgYo=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=SwHjuvOCHqNEkxf52JoC7AdTrd5C2o1CLwjkOTJHd2bAO2ISNvQyke/IqU2P6H7us\n\tVZ56Umaeyy0dgJCXWiyx2VEG+J386geqB0Wbw7StqaVnUN20pPi+4RaCgzKumcL/yQ\n\tFIRHLQt9FtTXgSQqxOqMHnHyDomZrfcBL1pDLWds=", "From": "Umang Jain <umang.jain@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Wed, 8 Sep 2021 01:27:04 +0530", "Message-Id": "<20210907195704.338079-7-umang.jain@ideasonboard.com>", "X-Mailer": "git-send-email 2.31.1", "In-Reply-To": "<20210907195704.338079-1-umang.jain@ideasonboard.com>", "References": "<20210907195704.338079-1-umang.jain@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [PATCH v1 6/6] android: camera_stream: Run\n\tpost-processor in a separate thread", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "In CameraStream, introduce a new private PostProcessorWorker\nclass derived from Object. A instance of PostProcessorWorker\nis moved to a separate thread instance which will be responsible\nto run the post-processor.\n\nRunning PostProcessor asynchronously should entail that all the\ndata context needed by the PostProcessor should remain valid for\nthe entire duration of its run. Most of the context preserving\npart has been addressed inthe previous patch, we just need to\nensure the source framebuffer data that comes via Camera::Request,\nshould remain valid for the entire duration of post-processing\nrunning asynchronously. In order to so, we maintain a separate\ncopy of the framebuffer data and add it to the Camera3RequestDescriptor\nin which we preserve rest of the context.\n\nSigned-off-by: Umang Jain <umang.jain@ideasonboard.com>\n---\n src/android/camera_device.cpp | 18 +++++++++++++++++-\n src/android/camera_device.h | 4 ++++\n src/android/camera_stream.cpp | 15 ++++++++++++++-\n src/android/camera_stream.h | 26 ++++++++++++++++++++++++++\n 4 files changed, 61 insertions(+), 2 deletions(-)", "diff": "diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\nindex 8741678d..5a442fb9 100644\n--- a/src/android/camera_device.cpp\n+++ b/src/android/camera_device.cpp\n@@ -1173,6 +1173,21 @@ void CameraDevice::requestComplete(Request *request)\n \t\t\treturn;\n \t\t}\n \n+\t\tFrameBuffer *source = src;\n+\t\tif (cameraStream->type() != CameraStream::Type::Internal) {\n+\t\t\t/*\n+\t\t\t * The source buffer is owned by Request object which\n+\t\t\t * can be reused for future capture request. Since\n+\t\t\t * post-processor will run asynchrnously, we need to\n+\t\t\t * copy the source buffer and use it as source buffer.\n+\t\t\t */\n+\t\t\tfor (const auto &plane : src->planes())\n+\t\t\t\tdescriptor.srcPlanes_.push_back(plane);\n+\t\t\tdescriptor.srcFramebuffer_ =\n+\t\t\t\tstd::make_unique<FrameBuffer>(descriptor.srcPlanes_);\n+\t\t\tsource = descriptor.srcFramebuffer_.get();\n+\t\t}\n+\n \t\tstd::unique_ptr<Camera3RequestDescriptor> reqDescriptor =\n \t\t\tstd::make_unique<Camera3RequestDescriptor>();\n \t\t*reqDescriptor = std::move(descriptor);\n@@ -1186,7 +1201,7 @@ void CameraDevice::requestComplete(Request *request)\n \t\t\t\t\t\t\t metadata);\n \t\t\t});\n \n-\t\tint ret = cameraStream->process(src, currentDescriptor->destBuffer_.get(),\n+\t\tint ret = cameraStream->process(source, currentDescriptor->destBuffer_.get(),\n \t\t\t\t\t\tcurrentDescriptor->settings_,\n \t\t\t\t\t\tmetadata);\n \t\treturn;\n@@ -1260,6 +1275,7 @@ void CameraDevice::streamProcessingComplete(CameraStream *cameraStream,\n \n void CameraDevice::sendQueuedCaptureResults()\n {\n+\tMutexLocker lock(queuedDescriptorsMutex_);\n \twhile (!queuedDescriptor_.empty()) {\n \t\tstd::unique_ptr<Camera3RequestDescriptor> &d = queuedDescriptor_.front();\n \t\tif (d->status_ != Camera3RequestDescriptor::NOT_FINISHED) {\ndiff --git a/src/android/camera_device.h b/src/android/camera_device.h\nindex 330c69a3..87ae00ab 100644\n--- a/src/android/camera_device.h\n+++ b/src/android/camera_device.h\n@@ -100,6 +100,9 @@ private:\n \t\tcamera3_capture_result_t captureResult_;\n \t\tlibcamera::FrameBuffer *internalBuffer_;\n \t\tcompletionStatus status_;\n+\n+\t\tstd::unique_ptr<libcamera::FrameBuffer> srcFramebuffer_;\n+\t\tstd::vector<libcamera::FrameBuffer::Plane> srcPlanes_;\n \t};\n \n \tenum class State {\n@@ -147,6 +150,7 @@ private:\n \tlibcamera::Mutex descriptorsMutex_; /* Protects descriptors_. */\n \tstd::map<uint64_t, Camera3RequestDescriptor> descriptors_;\n \n+\tlibcamera::Mutex queuedDescriptorsMutex_; /* Protects queuedDescriptor_. */\n \tstd::deque<std::unique_ptr<Camera3RequestDescriptor>> queuedDescriptor_;\n \n \tstd::string maker_;\ndiff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp\nindex 1939cb9c..6a2c1f5b 100644\n--- a/src/android/camera_stream.cpp\n+++ b/src/android/camera_stream.cpp\n@@ -55,6 +55,15 @@ CameraStream::CameraStream(CameraDevice *const cameraDevice,\n \t\t * is what we instantiate here.\n \t\t */\n \t\tpostProcessor_ = std::make_unique<PostProcessorJpeg>(cameraDevice_);\n+\t\tppWorker_ = std::make_unique<PostProcessorWorker>(postProcessor_.get());\n+\n+\t\tthread_ = std::make_unique<libcamera::Thread>();\n+\t\tppWorker_->moveToThread(thread_.get());\n+\t\t/*\n+\t\t * \\todo: Class is MoveConstructible, so where to stop thread\n+\t\t * if we don't user-defined destructor?\n+\t\t */\n+\t\tthread_->start();\n \t}\n \n \tif (type == Type::Internal) {\n@@ -108,7 +117,11 @@ int CameraStream::process(const FrameBuffer *source,\n \tif (!postProcessor_)\n \t\treturn 0;\n \n-\treturn postProcessor_->process(source, destBuffer, requestMetadata, resultMetadata);\n+\tppWorker_->invokeMethod(&PostProcessorWorker::process,\n+\t\t\t\tConnectionTypeQueued, source, destBuffer,\n+\t\t\t\trequestMetadata, resultMetadata);\n+\n+\treturn 0;\n }\n \n void CameraStream::handlePostProcessing(PostProcessor::Status status)\ndiff --git a/src/android/camera_stream.h b/src/android/camera_stream.h\nindex ad03e4cf..d8ce0972 100644\n--- a/src/android/camera_stream.h\n+++ b/src/android/camera_stream.h\n@@ -13,7 +13,9 @@\n \n #include <hardware/camera3.h>\n \n+#include <libcamera/base/object.h>\n #include <libcamera/base/signal.h>\n+#include <libcamera/base/thread.h>\n \n #include <libcamera/camera.h>\n #include <libcamera/framebuffer.h>\n@@ -23,6 +25,7 @@\n \n #include \"post_processor.h\"\n \n+class CameraBuffer;\n class CameraDevice;\n class CameraMetadata;\n \n@@ -135,6 +138,27 @@ public:\n \tlibcamera::Signal<ProcessStatus> processComplete;\n \n private:\n+\tclass PostProcessorWorker : public libcamera::Object\n+\t{\n+\tpublic:\n+\t\tPostProcessorWorker(PostProcessor *postProcessor)\n+\t\t{\n+\t\t\tpostProcessor_ = postProcessor;\n+\t\t}\n+\n+\t\tvoid process(const libcamera::FrameBuffer *source,\n+\t\t\t CameraBuffer *destination,\n+\t\t\t const CameraMetadata &requestMetadata,\n+\t\t\t CameraMetadata *resultMetadata)\n+\t\t{\n+\t\t\tpostProcessor_->process(source, destination,\n+\t\t\t\t\t\trequestMetadata, resultMetadata);\n+\t\t}\n+\n+\tprivate:\n+\t\tPostProcessor *postProcessor_;\n+\t};\n+\n \tvoid handlePostProcessing(PostProcessor::Status status);\n \n \tCameraDevice *const cameraDevice_;\n@@ -151,6 +175,8 @@ private:\n \t */\n \tstd::unique_ptr<std::mutex> mutex_;\n \tstd::unique_ptr<PostProcessor> postProcessor_;\n+\tstd::unique_ptr<PostProcessorWorker> ppWorker_;\n+\tstd::unique_ptr<libcamera::Thread> thread_;\n };\n \n #endif /* __ANDROID_CAMERA_STREAM__ */\n", "prefixes": [ "libcamera-devel", "v1", "6/6" ] }