Patch Detail
Show a patch.
GET /api/1.1/patches/13945/?format=api
{ "id": 13945, "url": "https://patchwork.libcamera.org/api/1.1/patches/13945/?format=api", "web_url": "https://patchwork.libcamera.org/patch/13945/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20210927104821.2526508-3-hiroh@chromium.org>", "date": "2021-09-27T10:48:21", "name": "[libcamera-devel,RFC,2/2] android: Send alternative stream configuration if no buffer to be sent exists", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "b11624d78b5fe7e8e68128701513c665a290c1a2", "submitter": { "id": 63, "url": "https://patchwork.libcamera.org/api/1.1/people/63/?format=api", "name": "Hirokazu Honda", "email": "hiroh@chromium.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/13945/mbox/", "series": [ { "id": 2572, "url": "https://patchwork.libcamera.org/api/1.1/series/2572/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2572", "date": "2021-09-27T10:48:19", "name": "android: Fix the issue with Type::Mapped only request", "version": 1, "mbox": "https://patchwork.libcamera.org/series/2572/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/13945/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/13945/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 1163CC3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Sep 2021 10:48:35 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CE93969196;\n\tMon, 27 Sep 2021 12:48:34 +0200 (CEST)", "from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com\n\t[IPv6:2607:f8b0:4864:20::62d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 221A46012C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Sep 2021 12:48:33 +0200 (CEST)", "by mail-pl1-x62d.google.com with SMTP id j15so10059946plh.7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Sep 2021 03:48:33 -0700 (PDT)", "from hiroh2.tok.corp.google.com\n\t([2401:fa00:8f:203:7cac:9967:6683:8845])\n\tby smtp.gmail.com with ESMTPSA id\n\tb11sm18694452pge.57.2021.09.27.03.48.29\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 27 Sep 2021 03:48:30 -0700 (PDT)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"WHtttgmc\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=9YQvZI94UmReHrH9Fuefm9vag2IyDcleBNQfU6/yotA=;\n\tb=WHtttgmcOVy0rfmMi7zrVMZt9iOkzUC1uvHnVCvO72sXJ8RrjlsrBlv6SpovUy6NKi\n\t5s3LRIuQU1woDTUlvl3ntv9qBL71bDwhFt5GK0JJXw6g6FGUOR9uWDXbQEacYT0xw0nW\n\truFWSq0UQJdxZZtu9HKETZbaXfCnOJWoGDPdA=", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=9YQvZI94UmReHrH9Fuefm9vag2IyDcleBNQfU6/yotA=;\n\tb=7Qt2IQMVlC0wnGEnvkGsjZ4n6JJM12tyc2ctvI2gdwxGf04YFrWrO1Cn7GRvvsPtG4\n\txt4YSgf7l4MWFOCXnwEo4jmN28niHHixaErvFSzrxbOxmZLVsdZhYwKxVdp97CKk1SDD\n\thXnQk/U+9P+OAzXQ69iRoVAgufAHetFtBuLtkv33iO01NsqbAGmeOtHfopRNlCFM06Jv\n\tRP4AWn0fmBMcEVKPtZ2CPOGehfJIe45z5S9ZrdOJZRINcITtOXwcX6ehoN1D1wrk+mJ+\n\ti8VVfenOeaosKUlVFERuRJU0D7wg6A/c/PMxpkzZMreoeUVsTAddwRbBLuom44Ftnd9O\n\tQX3g==", "X-Gm-Message-State": "AOAM533LKuTmE2utDq8jECGsJlpqEbJJzxDADDJ6BWPfhiCUUn2oM5ve\n\tzNvBFuo3fLX67wr5QnyHIsi84vfllFEXuw==", "X-Google-Smtp-Source": "ABdhPJxyiVe9vcRrV3Ae/Sm3ql22Jagk/8fSW2hhtWmM71UQbP2fpt9RT6QvCIri9V6dHo6hK2rgVg==", "X-Received": "by 2002:a17:90b:4f8a:: with SMTP id\n\tqe10mr19113196pjb.5.1632739711326; \n\tMon, 27 Sep 2021 03:48:31 -0700 (PDT)", "From": "Hirokazu Honda <hiroh@chromium.org>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Mon, 27 Sep 2021 19:48:21 +0900", "Message-Id": "<20210927104821.2526508-3-hiroh@chromium.org>", "X-Mailer": "git-send-email 2.33.0.685.g46640cef36-goog", "In-Reply-To": "<20210927104821.2526508-1-hiroh@chromium.org>", "References": "<20210927104821.2526508-1-hiroh@chromium.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [RFC PATCH 2/2] android: Send alternative stream\n\tconfiguration if no buffer to be sent exists", "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": "A request given in processCaptureRequest() can contain only streams\nthat are resolved CameraStream::Type::Mapped. In the case, no buffer\nis sent to a native camera. This fixes the issue by looking for the\nstream to be requested and alternatively sending a buffer for the\nstream to a camera.\n\nHowever, the substitute stream is Direct and a buffer needs to be\nprovided by a HAL client. So we have to allocate a buffer in\nAndroid HAL adaptation layer using PlatformFrameBufferAllocator.\n\nSigned-off-by: Hirokazu Honda <hiroh@chromium.org>\n---\n src/android/camera_device.cpp | 50 +++++++++++++++++++++++++++++------\n src/android/camera_device.h | 4 +++\n src/android/camera_stream.cpp | 37 ++++++++++++++++++++++----\n src/android/camera_stream.h | 10 +++++--\n 4 files changed, 86 insertions(+), 15 deletions(-)", "diff": "diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\nindex a693dcbe..5887e85e 100644\n--- a/src/android/camera_device.cpp\n+++ b/src/android/camera_device.cpp\n@@ -724,10 +724,14 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)\n \tfor (const auto &streamConfig : streamConfigs) {\n \t\tconfig->addConfiguration(streamConfig.config);\n \n+\t\tCameraStream *mappedStream = nullptr;\n \t\tfor (auto &stream : streamConfig.streams) {\n \t\t\tstreams_.emplace_back(this, config.get(), stream.type,\n-\t\t\t\t\t stream.stream, config->size() - 1);\n+\t\t\t\t\t stream.stream, mappedStream,\n+\t\t\t\t\t config->size() - 1);\n \t\t\tstream.stream->priv = static_cast<void *>(&streams_.back());\n+\t\t\tif (stream.type == CameraStream::Type::Direct)\n+\t\t\t\tmappedStream = &streams_.back();\n \t\t}\n \t}\n \n@@ -969,6 +973,8 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n \n \tLOG(HAL, Debug) << \"Queueing request \" << descriptor.request_->cookie()\n \t\t\t<< \" with \" << descriptor.buffers_.size() << \" streams\";\n+\n+\tstd::set<Stream *> addedStreams;\n \tfor (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) {\n \t\tconst camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i];\n \t\tcamera3_stream *camera3Stream = camera3Buffer.stream;\n@@ -1018,6 +1024,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n \t\t\t * once it has been processed.\n \t\t\t */\n \t\t\tbuffer = cameraStream->getBuffer();\n+\t\t\tdescriptor.internalBuffers_[cameraStream] = buffer;\n \t\t\tLOG(HAL, Debug) << ss.str() << \" (internal)\";\n \t\t\tbreak;\n \t\t}\n@@ -1029,6 +1036,37 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n \n \t\tdescriptor.request_->addBuffer(cameraStream->stream(), buffer,\n \t\t\t\t\t\tcamera3Buffer.acquire_fence);\n+\t\taddedStreams.insert(cameraStream->stream());\n+\t}\n+\n+\tfor (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) {\n+\t\tconst camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i];\n+\t\tcamera3_stream *camera3Stream = camera3Buffer.stream;\n+\t\tCameraStream *cameraStream = static_cast<CameraStream *>(camera3Stream->priv);\n+\t\tif (cameraStream->type() != CameraStream::Type::Mapped)\n+\t\t\tcontinue;\n+\t\tif (addedStreams.find(cameraStream->stream()) != addedStreams.end())\n+\t\t\tcontinue;\n+\n+\t\tCameraStream *mappedStream = cameraStream->mappedStream();\n+\t\tif (!mappedStream) {\n+\t\t\tLOG(HAL, Error)\n+\t\t\t\t<< \"Could not find mappedStream for (\"\n+\t\t\t\t<< camera3Stream->width << \"x\"\n+\t\t\t\t<< camera3Stream->height << \")\"\n+\t\t\t\t<< \"[\" << utils::hex(camera3Stream->format) << \"]\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tASSERT(mappedStream->type() == CameraStream::Type::Direct);\n+\t\tFrameBuffer *mappedBuffer = mappedStream->getBuffer();\n+\t\tif (!mappedBuffer) {\n+\t\t\tLOG(HAL, Error) << \"Failed getting a buffer\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tdescriptor.internalBuffers_[mappedStream] = mappedBuffer;\n+\t\tdescriptor.request_->addBuffer(mappedStream->stream(), mappedBuffer, -1);\n \t}\n \n \t/*\n@@ -1180,13 +1218,6 @@ void CameraDevice::requestComplete(Request *request)\n \t\tint ret = cameraStream->process(*src, *buffer.buffer,\n \t\t\t\t\t\tdescriptor.settings_,\n \t\t\t\t\t\tresultMetadata.get());\n-\t\t/*\n-\t\t * Return the FrameBuffer to the CameraStream now that we're\n-\t\t * done processing it.\n-\t\t */\n-\t\tif (cameraStream->type() == CameraStream::Type::Internal)\n-\t\t\tcameraStream->putBuffer(src);\n-\n \t\tif (ret) {\n \t\t\tbuffer.status = CAMERA3_BUFFER_STATUS_ERROR;\n \t\t\tnotifyError(descriptor.frameNumber_, buffer.stream,\n@@ -1194,6 +1225,9 @@ void CameraDevice::requestComplete(Request *request)\n \t\t}\n \t}\n \n+\tfor (auto &[stream, buffer] : descriptor.internalBuffers_)\n+\t\tstream->putBuffer(buffer);\n+\n \tcaptureResult.result = resultMetadata->get();\n \tcallbacks_->process_capture_result(callbacks_, &captureResult);\n }\ndiff --git a/src/android/camera_device.h b/src/android/camera_device.h\nindex 296c2f18..74d8150b 100644\n--- a/src/android/camera_device.h\n+++ b/src/android/camera_device.h\n@@ -21,6 +21,7 @@\n \n #include <libcamera/camera.h>\n #include <libcamera/framebuffer.h>\n+#include <libcamera/framebuffer_allocator.h>\n #include <libcamera/geometry.h>\n #include <libcamera/pixel_format.h>\n #include <libcamera/request.h>\n@@ -84,6 +85,7 @@ private:\n \t\tstd::vector<std::unique_ptr<libcamera::FrameBuffer>> frameBuffers_;\n \t\tCameraMetadata settings_;\n \t\tstd::unique_ptr<CaptureRequest> request_;\n+\t\tstd::map<CameraStream *, libcamera::FrameBuffer *> internalBuffers_;\n \t};\n \n \tenum class State {\n@@ -118,6 +120,8 @@ private:\n \tstd::unique_ptr<libcamera::CameraConfiguration> config_;\n \tCameraCapabilities capabilities_;\n \n+\tstd::unique_ptr<libcamera::FrameBufferAllocator> frame_buffer_allocator_;\n+\n \tstd::map<unsigned int, std::unique_ptr<CameraMetadata>> requestTemplates_;\n \tconst camera3_callback_ops_t *callbacks_;\n \ndiff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp\nindex e30c7ee4..fc2e82cd 100644\n--- a/src/android/camera_stream.cpp\n+++ b/src/android/camera_stream.cpp\n@@ -18,6 +18,7 @@\n #include \"camera_capabilities.h\"\n #include \"camera_device.h\"\n #include \"camera_metadata.h\"\n+#include \"frame_buffer.h\"\n \n using namespace libcamera;\n \n@@ -46,10 +47,14 @@ LOG_DECLARE_CATEGORY(HAL)\n \n CameraStream::CameraStream(CameraDevice *const cameraDevice,\n \t\t\t CameraConfiguration *config, Type type,\n-\t\t\t camera3_stream_t *camera3Stream, unsigned int index)\n+\t\t\t camera3_stream_t *camera3Stream,\n+\t\t\t CameraStream *const mappedStream,\n+\t\t\t unsigned int index)\n \t: cameraDevice_(cameraDevice), config_(config), type_(type),\n-\t camera3Stream_(camera3Stream), index_(index)\n+\t camera3Stream_(camera3Stream), mappedStream_(mappedStream),\n+\t index_(index)\n {\n+\tASSERT(type_ != Type::Mapped || !!mappedStream);\n }\n \n const StreamConfiguration &CameraStream::configuration() const\n@@ -134,8 +139,30 @@ int CameraStream::process(const FrameBuffer &source,\n \n FrameBuffer *CameraStream::getBuffer()\n {\n-\tif (!allocator_)\n-\t\treturn nullptr;\n+\tif (!mutex_) {\n+\t\tASSERT(type_ == Type::Direct);\n+\t\tASSERT(!allocator_);\n+\t\tmutex_ = std::make_unique<std::mutex>();\n+\t\tplatform_allocator_ = std::make_unique<PlatformFrameBufferAllocator>(cameraDevice_);\n+\t\tconst StreamConfiguration &config = configuration();\n+\t\tsize_t numBuffers = config.bufferCount;\n+\t\tconst int halPixelFormat = camera3Stream_->format;\n+\t\tconst uint32_t usage = camera3Stream_->usage;\n+\t\tLOG(HAL, Error) << \"getBuffer@@@@@ \" << numBuffers;\n+\t\t// numBuffers is 4 (=config.bufferCount) is not enough sadly...\n+\t\t// Should we dynamically allocate?\n+\t\tnumBuffers = 20;\n+\t\tconst auto &buffers = platform_allocator_->allocate(\n+\t\t\thalPixelFormat, config.size, usage, numBuffers);\n+\t\tif (buffers.empty() || buffers.size() != numBuffers) {\n+\t\t\tLOG(HAL, Error) << \"Failed allocating FrameBuffers\";\n+\t\t\treturn nullptr;\n+\t\t}\n+\n+\t\tbuffers_.reserve(numBuffers);\n+\t\tfor (const auto &frameBuffer : buffers)\n+\t\t\tbuffers_.push_back(frameBuffer.get());\n+\t}\n \n \tstd::lock_guard<std::mutex> locker(*mutex_);\n \n@@ -143,7 +170,7 @@ FrameBuffer *CameraStream::getBuffer()\n \t\tLOG(HAL, Error) << \"Buffer underrun\";\n \t\treturn nullptr;\n \t}\n-\n+\tLOG(HAL, Error) << buffers_.size();\n \tFrameBuffer *buffer = buffers_.back();\n \tbuffers_.pop_back();\n \ndiff --git a/src/android/camera_stream.h b/src/android/camera_stream.h\nindex 2dab6c3a..c8eee908 100644\n--- a/src/android/camera_stream.h\n+++ b/src/android/camera_stream.h\n@@ -15,10 +15,11 @@\n \n #include <libcamera/camera.h>\n #include <libcamera/framebuffer.h>\n-#include <libcamera/framebuffer_allocator.h>\n #include <libcamera/geometry.h>\n #include <libcamera/pixel_format.h>\n \n+#include \"frame_buffer.h\"\n+\n class CameraDevice;\n class CameraMetadata;\n class PostProcessor;\n@@ -110,12 +111,14 @@ public:\n \t};\n \tCameraStream(CameraDevice *const cameraDevice,\n \t\t libcamera::CameraConfiguration *config, Type type,\n-\t\t camera3_stream_t *camera3Stream, unsigned int index);\n+\t\t camera3_stream_t *camera3Stream,\n+\t\t CameraStream *const mappedStream, unsigned int index);\n \n \tType type() const { return type_; }\n \tconst camera3_stream_t &camera3Stream() const { return *camera3Stream_; }\n \tconst libcamera::StreamConfiguration &configuration() const;\n \tlibcamera::Stream *stream() const;\n+\tCameraStream *mappedStream() const { return mappedStream_; }\n \n \tint configure();\n \tint process(const libcamera::FrameBuffer &source,\n@@ -130,10 +133,13 @@ private:\n \tconst libcamera::CameraConfiguration *config_;\n \tconst Type type_;\n \tcamera3_stream_t *camera3Stream_;\n+\tCameraStream *const mappedStream_;\n \tconst unsigned int index_;\n \n \tstd::unique_ptr<libcamera::FrameBufferAllocator> allocator_;\n+\tstd::unique_ptr<PlatformFrameBufferAllocator> platform_allocator_;\n \tstd::vector<libcamera::FrameBuffer *> buffers_;\n+\tstd::vector<std::unique_ptr<libcamera::FrameBuffer>> frameBuffers_;\n \t/*\n \t * The class has to be MoveConstructible as instances are stored in\n \t * an std::vector in CameraDevice.\n", "prefixes": [ "libcamera-devel", "RFC", "2/2" ] }