From patchwork Mon Sep 27 10:48:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13944 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 A8CA9C3243 for ; Mon, 27 Sep 2021 10:48:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7901869193; Mon, 27 Sep 2021 12:48:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="avuZCksG"; dkim-atps=neutral Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 520EF69189 for ; Mon, 27 Sep 2021 12:48:31 +0200 (CEST) Received: by mail-pl1-x631.google.com with SMTP id bb10so11507554plb.2 for ; Mon, 27 Sep 2021 03:48:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HPdtTWeFNk194YiGMW//3NWvGklNDVDINr9fGXGmR9M=; b=avuZCksGq7EG5SiZja88QL5B3QllorLJLZ3z83ryPbE/dbnZfXNaoQhdOh5OmGWhTM n6xoB39+0DzOZBKGAFBC+SnweEcRSJAUC2/S+xKzf1s2Uxhb1cOHqoYWfZNNaXT9NOrJ uDinq6WeCbM601QoBsb4SWdXHkvn5pV2ZQUK0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HPdtTWeFNk194YiGMW//3NWvGklNDVDINr9fGXGmR9M=; b=SV+s6MFPhZeFcBr2OejgrCep51wGrmktNyzmH/un0fhWKZfUJnGCuZfLgEdgZjqE3Q EL3xiO4tChhGfZ+po6KkAxUPeVkPGXK8+oIQ4E6dwQuHr2Na+MaFHfN5jGKSFDJ9E3PE csRG5S3Be7dKhxIhNLu3C9s+py4WCa6j2y/NnVPUSmBtgI/7UkjltZiEySsvJmcJneGn aVGj9TUPXRE2O1El9pVkjjMNDk/pvIkSkKDPrKNXmQV0DjBP6OzggpPYe1RnN44v2Ri/ qeT7keg/sfMr58vuK+8+0o10BGol52FgZyQSmalx6j3rJvfublSwvuPTsDhhrjeTKz1R tEVg== X-Gm-Message-State: AOAM531Gxu50FG4b5NG/hBcUSVVOak2x7ZmoqLnyvXwJhOGEvNzwVnr1 Fl9oT9jOXVdt9yLORCCyMOrM9/wJ9fUtvg== X-Google-Smtp-Source: ABdhPJw8Dk2G2Z1G2So1QLWwIwkK8mPoxr5ha+Dt2SB6arjyBtU8WaIAmgNSjkEErNGYIZ2eqQzSvA== X-Received: by 2002:a17:90b:3a8a:: with SMTP id om10mr18629898pjb.223.1632739709308; Mon, 27 Sep 2021 03:48:29 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:7cac:9967:6683:8845]) by smtp.gmail.com with ESMTPSA id b11sm18694452pge.57.2021.09.27.03.48.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 03:48:28 -0700 (PDT) From: Hirokazu Honda To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Sep 2021 19:48:20 +0900 Message-Id: <20210927104821.2526508-2-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 Subject: [libcamera-devel] [RFC PATCH 1/2] android: Introduce PlatformFrameBufferAllocator 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" PlatformFrameBufferAllocator allocates FrameBuffer(s) using cros::CameraBufferManager on ChromeOS and gralloc on non ChromeOS platform. The allocated FrameBuffer(s) are owned by PlatformFrameBufferAllocator an destroyed when PlatformFrameBufferAllocator is destroyed. Signed-off-by: Hirokazu Honda --- src/android/frame_buffer.h | 53 +++++++++++ src/android/mm/cros_frame_buffer.cpp | 85 +++++++++++++++++ src/android/mm/generic_frame_buffer.cpp | 116 ++++++++++++++++++++++++ src/android/mm/meson.build | 6 +- 4 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 src/android/frame_buffer.h create mode 100644 src/android/mm/cros_frame_buffer.cpp create mode 100644 src/android/mm/generic_frame_buffer.cpp diff --git a/src/android/frame_buffer.h b/src/android/frame_buffer.h new file mode 100644 index 00000000..6aafeaf3 --- /dev/null +++ b/src/android/frame_buffer.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * frame_buffer.h - Frame buffer allocating interface definition + */ +#ifndef __ANDROID_FRAME_BUFFER_H__ +#define __ANDROID_FRAME_BUFFER_H__ + +#include +#include + +#include +#include +#include +#include + +class CameraDevice; + +class PlatformFrameBufferAllocator : libcamera::Extensible +{ + LIBCAMERA_DECLARE_PRIVATE() + +public: + explicit PlatformFrameBufferAllocator(CameraDevice *const cameraDevice); + ~PlatformFrameBufferAllocator(); + + const std::vector> & + allocate(int halPixelFormat, + const libcamera::Size &size, + uint32_t usage, + size_t numBuffers); +}; + +#define PUBLIC_FRAME_BUFFER_IMPLEMENTATION \ +PlatformFrameBufferAllocator::PlatformFrameBufferAllocator( \ + CameraDevice *const cameraDevice) \ + : Extensible(std::make_unique(this, cameraDevice)) \ +{ \ +} \ +PlatformFrameBufferAllocator::~PlatformFrameBufferAllocator() \ +{ \ +} \ +const std::vector>& \ +PlatformFrameBufferAllocator::allocate(int halPixelFormat, \ + const libcamera::Size& size, \ + uint32_t usage, \ + size_t numBuffers) \ +{ \ + return _d()->allocate(halPixelFormat, size, usage, numBuffers); \ +} + +#endif /* __ANDROID_FRAME_BUFFER_H__ */ diff --git a/src/android/mm/cros_frame_buffer.cpp b/src/android/mm/cros_frame_buffer.cpp new file mode 100644 index 00000000..114c739b --- /dev/null +++ b/src/android/mm/cros_frame_buffer.cpp @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * cros_frame_buffer.cpp - allocate FrameBuffer for Chromium OS buffer backend + * using CameraBufferManager + */ + +#include "../frame_buffer.h" + +#include + +#include "cros-camera/camera_buffer_manager.h" + +#include "../camera_device.h" + +using namespace libcamera; + +LOG_DECLARE_CATEGORY(HAL) + +class PlatformFrameBufferAllocator::Private : public Extensible::Private +{ + LIBCAMERA_DECLARE_PUBLIC(PlatformFrameBufferAllocator) + +public: + Private([[maybe_unused]] PlatformFrameBufferAllocator *allocator, + [[maybe_unused]] CameraDevice *const cameraDevice) + { + } + + ~Private() = default; + + const std::vector> & + allocate(int halPixelFormat, + const libcamera::Size &size, + uint32_t usage, + size_t numBuffers); + +private: + std::vector> allocatedBuffers_; + std::vector allocatedHandles_; +}; + +const std::vector> & +PlatformFrameBufferAllocator::Private::allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage, + size_t numBuffers) +{ + ASSERT(allocatedBuffers_.empty()); + + std::vector> buffers; + for (size_t i = 0; i < numBuffers; ++i) { + cros::ScopedBufferHandle handle = + cros::CameraBufferManager::AllocateScopedBuffer( + size.width, size.height, halPixelFormat, usage); + if (!handle) { + LOG(HAL, Error) << "Failed allocate buffer_handle"; + return allocatedBuffers_; + } + + const size_t numPlanes = cros::CameraBufferManager::GetNumPlanes(*handle); + std::vector planes(numPlanes); + for (size_t j = 0; j < numPlanes; ++j) { + FileDescriptor fd{ (*handle)->data[0] }; + if (!fd.isValid()) { + LOG(HAL, Fatal) << "Invalid fd"; + return allocatedBuffers_; + } + + planes[j].fd = fd; + planes[j].offset = + cros::CameraBufferManager::GetPlaneOffset(*handle, j); + planes[j].length = + cros::CameraBufferManager::GetPlaneSize(*handle, j); + } + + buffers.push_back(std::make_unique(planes)); + allocatedHandles_.push_back(std::move(handle)); + } + + allocatedBuffers_ = std::move(buffers); + return allocatedBuffers_; +} + +PUBLIC_FRAME_BUFFER_IMPLEMENTATION diff --git a/src/android/mm/generic_frame_buffer.cpp b/src/android/mm/generic_frame_buffer.cpp new file mode 100644 index 00000000..b387d5a2 --- /dev/null +++ b/src/android/mm/generic_frame_buffer.cpp @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * generic_camera_buffer.cpp - allocate FrameBuffer for Generic Android frame + * buffer backend + */ + +#include "../frame_buffer.h" + +#include +#include + +#include +#include +#include + +#include "../camera_device.h" + +using namespace libcamera; + +LOG_DECLARE_CATEGORY(HAL) + +class PlatformFrameBufferAllocator::Private : public Extensible::Private +{ + LIBCAMERA_DECLARE_PUBLIC(PlatformFrameBufferAllocator) + +public: + Private([[maybe_unused]] PlatformFrameBufferAllocator *allocator, + CameraDevice *const cameraDevice) + : cameraDevice_(cameraDevice), + hardwareModule_(cameraDevice->camera3Device()->common.module) + { + ASSERT(!!hardwareModule_); + } + + ~Private() override; + + const std::vector> & + allocate(int halPixelFormat, + const libcamera::Size &size, + uint32_t usage, + size_t numBuffers); + +private: + const CameraDevice *const cameraDevice_; + struct hw_module_t *const hardwareModule_; + struct alloc_device_t *allocDevice_; + + std::vector> allocatedBuffers_; + std::vector bufferHandles_; +}; + +PlatformFrameBufferAllocator::Private::~Private() +{ + for (buffer_handle_t &handle : bufferHandles_) { + ASSERT(allocDevice_); + allocDevice_->free(allocDevice_, handle); + } + if (allocDevice_) + gralloc_close(allocDevice_); +} + +const std::vector> & +PlatformFrameBufferAllocator::Private::allocate( + int halPixelFormat, const libcamera::Size &size, uint32_t usage, + size_t numBuffers) +{ + ASSERT(allocatedBuffers_.empty()); + ASSERT(bufferHandles_.empty()); + ASSERT(!allocDevice_); + + int ret = gralloc_open(hardwareModule_, &allocDevice_); + if (ret) { + LOG(HAL, Error) << "gralloc_open() failed: " << ret; + return allocatedBuffers_; + } + + int stride = 0; + for (size_t i = 0; i < numBuffers; ++i) { + buffer_handle_t handle{}; + ret = allocDevice_->alloc(allocDevice_, size.width, size.height, + halPixelFormat, usage, &handle, &stride); + if (ret) { + LOG(HAL, Error) << "failed buffer allocating: " << ret; + return allocatedBuffers_; + } + + bufferHandles_.push_back(handle); + } + + const libcamera::PixelFormat pixelFormat = + cameraDevice_->capabilities()->toPixelFormat(halPixelFormat); + const auto &info = PixelFormatInfo::info(pixelFormat); + const unsigned int numPlanes = info.numPlanes(); + + allocatedBuffers_.reserve(numBuffers); + for (const buffer_handle_t &handle : bufferHandles_) { + std::vector planes(numPlanes); + size_t offset = 0; + for (size_t i = 0; i < numPlanes; ++i) { + planes[i].fd = FileDescriptor(handle->data[i]); + size_t planeSize = info.planeSize(size.height, i, stride); + + planes[i].offset = offset; + planes[i].length = planeSize; + offset += planeSize; + } + + allocatedBuffers_.push_back(std::make_unique(planes)); + } + + return allocatedBuffers_; +} + +PUBLIC_FRAME_BUFFER_IMPLEMENTATION diff --git a/src/android/mm/meson.build b/src/android/mm/meson.build index eeb5cc2e..d1ad64d9 100644 --- a/src/android/mm/meson.build +++ b/src/android/mm/meson.build @@ -2,8 +2,10 @@ platform = get_option('android_platform') if platform == 'generic' - android_hal_sources += files(['generic_camera_buffer.cpp']) + android_hal_sources += files(['generic_camera_buffer.cpp', + 'generic_frame_buffer.cpp']) elif platform == 'cros' - android_hal_sources += files(['cros_camera_buffer.cpp']) + android_hal_sources += files(['cros_camera_buffer.cpp', + 'cros_frame_buffer.cpp']) android_deps += [dependency('libcros_camera')] endif From patchwork Mon Sep 27 10:48:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hirokazu Honda X-Patchwork-Id: 13945 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 1163CC3243 for ; Mon, 27 Sep 2021 10:48:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CE93969196; Mon, 27 Sep 2021 12:48:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="WHtttgmc"; dkim-atps=neutral Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 221A46012C for ; Mon, 27 Sep 2021 12:48:33 +0200 (CEST) Received: by mail-pl1-x62d.google.com with SMTP id j15so10059946plh.7 for ; Mon, 27 Sep 2021 03:48:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9YQvZI94UmReHrH9Fuefm9vag2IyDcleBNQfU6/yotA=; b=WHtttgmcOVy0rfmMi7zrVMZt9iOkzUC1uvHnVCvO72sXJ8RrjlsrBlv6SpovUy6NKi 5s3LRIuQU1woDTUlvl3ntv9qBL71bDwhFt5GK0JJXw6g6FGUOR9uWDXbQEacYT0xw0nW ruFWSq0UQJdxZZtu9HKETZbaXfCnOJWoGDPdA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9YQvZI94UmReHrH9Fuefm9vag2IyDcleBNQfU6/yotA=; b=7Qt2IQMVlC0wnGEnvkGsjZ4n6JJM12tyc2ctvI2gdwxGf04YFrWrO1Cn7GRvvsPtG4 xt4YSgf7l4MWFOCXnwEo4jmN28niHHixaErvFSzrxbOxmZLVsdZhYwKxVdp97CKk1SDD hXnQk/U+9P+OAzXQ69iRoVAgufAHetFtBuLtkv33iO01NsqbAGmeOtHfopRNlCFM06Jv RP4AWn0fmBMcEVKPtZ2CPOGehfJIe45z5S9ZrdOJZRINcITtOXwcX6ehoN1D1wrk+mJ+ i8VVfenOeaosKUlVFERuRJU0D7wg6A/c/PMxpkzZMreoeUVsTAddwRbBLuom44Ftnd9O QX3g== X-Gm-Message-State: AOAM533LKuTmE2utDq8jECGsJlpqEbJJzxDADDJ6BWPfhiCUUn2oM5ve zNvBFuo3fLX67wr5QnyHIsi84vfllFEXuw== X-Google-Smtp-Source: ABdhPJxyiVe9vcRrV3Ae/Sm3ql22Jagk/8fSW2hhtWmM71UQbP2fpt9RT6QvCIri9V6dHo6hK2rgVg== X-Received: by 2002:a17:90b:4f8a:: with SMTP id qe10mr19113196pjb.5.1632739711326; Mon, 27 Sep 2021 03:48:31 -0700 (PDT) Received: from hiroh2.tok.corp.google.com ([2401:fa00:8f:203:7cac:9967:6683:8845]) by smtp.gmail.com with ESMTPSA id b11sm18694452pge.57.2021.09.27.03.48.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Sep 2021 03:48:30 -0700 (PDT) From: Hirokazu Honda 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 Subject: [libcamera-devel] [RFC PATCH 2/2] android: Send alternative stream configuration if no buffer to be sent exists 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 request given in processCaptureRequest() can contain only streams that are resolved CameraStream::Type::Mapped. In the case, no buffer is sent to a native camera. This fixes the issue by looking for the stream to be requested and alternatively sending a buffer for the stream to a camera. However, the substitute stream is Direct and a buffer needs to be provided by a HAL client. So we have to allocate a buffer in Android HAL adaptation layer using PlatformFrameBufferAllocator. Signed-off-by: Hirokazu Honda --- src/android/camera_device.cpp | 50 +++++++++++++++++++++++++++++------ src/android/camera_device.h | 4 +++ src/android/camera_stream.cpp | 37 ++++++++++++++++++++++---- src/android/camera_stream.h | 10 +++++-- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index a693dcbe..5887e85e 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -724,10 +724,14 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) for (const auto &streamConfig : streamConfigs) { config->addConfiguration(streamConfig.config); + CameraStream *mappedStream = nullptr; for (auto &stream : streamConfig.streams) { streams_.emplace_back(this, config.get(), stream.type, - stream.stream, config->size() - 1); + stream.stream, mappedStream, + config->size() - 1); stream.stream->priv = static_cast(&streams_.back()); + if (stream.type == CameraStream::Type::Direct) + mappedStream = &streams_.back(); } } @@ -969,6 +973,8 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques LOG(HAL, Debug) << "Queueing request " << descriptor.request_->cookie() << " with " << descriptor.buffers_.size() << " streams"; + + std::set addedStreams; for (unsigned int i = 0; i < descriptor.buffers_.size(); ++i) { const camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i]; camera3_stream *camera3Stream = camera3Buffer.stream; @@ -1018,6 +1024,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * once it has been processed. */ buffer = cameraStream->getBuffer(); + descriptor.internalBuffers_[cameraStream] = buffer; LOG(HAL, Debug) << ss.str() << " (internal)"; break; } @@ -1029,6 +1036,37 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques descriptor.request_->addBuffer(cameraStream->stream(), buffer, camera3Buffer.acquire_fence); + addedStreams.insert(cameraStream->stream()); + } + + 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); + if (cameraStream->type() != CameraStream::Type::Mapped) + continue; + if (addedStreams.find(cameraStream->stream()) != addedStreams.end()) + continue; + + CameraStream *mappedStream = cameraStream->mappedStream(); + if (!mappedStream) { + LOG(HAL, Error) + << "Could not find mappedStream for (" + << camera3Stream->width << "x" + << camera3Stream->height << ")" + << "[" << utils::hex(camera3Stream->format) << "]"; + return -EINVAL; + } + + ASSERT(mappedStream->type() == CameraStream::Type::Direct); + FrameBuffer *mappedBuffer = mappedStream->getBuffer(); + if (!mappedBuffer) { + LOG(HAL, Error) << "Failed getting a buffer"; + return -EINVAL; + } + + descriptor.internalBuffers_[mappedStream] = mappedBuffer; + descriptor.request_->addBuffer(mappedStream->stream(), mappedBuffer, -1); } /* @@ -1180,13 +1218,6 @@ void CameraDevice::requestComplete(Request *request) int ret = cameraStream->process(*src, *buffer.buffer, descriptor.settings_, resultMetadata.get()); - /* - * Return the FrameBuffer to the CameraStream now that we're - * done processing it. - */ - if (cameraStream->type() == CameraStream::Type::Internal) - cameraStream->putBuffer(src); - if (ret) { buffer.status = CAMERA3_BUFFER_STATUS_ERROR; notifyError(descriptor.frameNumber_, buffer.stream, @@ -1194,6 +1225,9 @@ void CameraDevice::requestComplete(Request *request) } } + for (auto &[stream, buffer] : descriptor.internalBuffers_) + stream->putBuffer(buffer); + captureResult.result = resultMetadata->get(); callbacks_->process_capture_result(callbacks_, &captureResult); } diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 296c2f18..74d8150b 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -84,6 +85,7 @@ private: std::vector> frameBuffers_; CameraMetadata settings_; std::unique_ptr request_; + std::map internalBuffers_; }; enum class State { @@ -118,6 +120,8 @@ private: std::unique_ptr config_; CameraCapabilities capabilities_; + std::unique_ptr frame_buffer_allocator_; + std::map> requestTemplates_; const camera3_callback_ops_t *callbacks_; diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index e30c7ee4..fc2e82cd 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -18,6 +18,7 @@ #include "camera_capabilities.h" #include "camera_device.h" #include "camera_metadata.h" +#include "frame_buffer.h" using namespace libcamera; @@ -46,10 +47,14 @@ LOG_DECLARE_CATEGORY(HAL) CameraStream::CameraStream(CameraDevice *const cameraDevice, CameraConfiguration *config, Type type, - camera3_stream_t *camera3Stream, unsigned int index) + camera3_stream_t *camera3Stream, + CameraStream *const mappedStream, + unsigned int index) : cameraDevice_(cameraDevice), config_(config), type_(type), - camera3Stream_(camera3Stream), index_(index) + camera3Stream_(camera3Stream), mappedStream_(mappedStream), + index_(index) { + ASSERT(type_ != Type::Mapped || !!mappedStream); } const StreamConfiguration &CameraStream::configuration() const @@ -134,8 +139,30 @@ int CameraStream::process(const FrameBuffer &source, FrameBuffer *CameraStream::getBuffer() { - if (!allocator_) - return nullptr; + if (!mutex_) { + ASSERT(type_ == Type::Direct); + ASSERT(!allocator_); + mutex_ = std::make_unique(); + platform_allocator_ = std::make_unique(cameraDevice_); + const StreamConfiguration &config = configuration(); + size_t numBuffers = config.bufferCount; + const int halPixelFormat = camera3Stream_->format; + const uint32_t usage = camera3Stream_->usage; + LOG(HAL, Error) << "getBuffer@@@@@ " << numBuffers; + // numBuffers is 4 (=config.bufferCount) is not enough sadly... + // Should we dynamically allocate? + numBuffers = 20; + const auto &buffers = platform_allocator_->allocate( + halPixelFormat, config.size, usage, numBuffers); + if (buffers.empty() || buffers.size() != numBuffers) { + LOG(HAL, Error) << "Failed allocating FrameBuffers"; + return nullptr; + } + + buffers_.reserve(numBuffers); + for (const auto &frameBuffer : buffers) + buffers_.push_back(frameBuffer.get()); + } std::lock_guard locker(*mutex_); @@ -143,7 +170,7 @@ FrameBuffer *CameraStream::getBuffer() LOG(HAL, Error) << "Buffer underrun"; return nullptr; } - + LOG(HAL, Error) << buffers_.size(); FrameBuffer *buffer = buffers_.back(); buffers_.pop_back(); diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 2dab6c3a..c8eee908 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -15,10 +15,11 @@ #include #include -#include #include #include +#include "frame_buffer.h" + class CameraDevice; class CameraMetadata; class PostProcessor; @@ -110,12 +111,14 @@ public: }; CameraStream(CameraDevice *const cameraDevice, libcamera::CameraConfiguration *config, Type type, - camera3_stream_t *camera3Stream, unsigned int index); + camera3_stream_t *camera3Stream, + CameraStream *const mappedStream, unsigned int index); Type type() const { return type_; } const camera3_stream_t &camera3Stream() const { return *camera3Stream_; } const libcamera::StreamConfiguration &configuration() const; libcamera::Stream *stream() const; + CameraStream *mappedStream() const { return mappedStream_; } int configure(); int process(const libcamera::FrameBuffer &source, @@ -130,10 +133,13 @@ private: const libcamera::CameraConfiguration *config_; const Type type_; camera3_stream_t *camera3Stream_; + CameraStream *const mappedStream_; const unsigned int index_; std::unique_ptr allocator_; + std::unique_ptr platform_allocator_; std::vector buffers_; + std::vector> frameBuffers_; /* * The class has to be MoveConstructible as instances are stored in * an std::vector in CameraDevice.