From patchwork Mon Jul 20 22:42:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8893 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 1B6BDC2E67 for ; Mon, 20 Jul 2020 22:42:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 56A8A605C6; Tue, 21 Jul 2020 00:42:39 +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="Plh3sJek"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 633CD60554 for ; Tue, 21 Jul 2020 00:42:37 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D0B6F563; Tue, 21 Jul 2020 00:42:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284957; bh=d1o20GUpXdd+g4xj2BYIhLaUMX9Oe9GZzEWjnPvXOe0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Plh3sJekRKDwB3zh4HuVdiu6eRFWPMAIHzkHWkhkcCDREpbc2NAUJyYrVh9w2ru/O FCLolSZWV1KnR8S7eBklcAp56f+8XQuVjwP4HP96GC0XkVzV4MNL1mHObs0UOwT043 k02c7OhC/XE9r57nsZf992R/PxdyftiSn5C6yTlk= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:25 +0100 Message-Id: <20200720224232.153717-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 1/8] libcamera: buffer: Create a MappedFrameBuffer 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" Provide a MappedFrameBuffer helper class which will map all of the Planes within a FrameBuffer and provide CPU addressable pointers for those planes. Mappings are removed upon destruction. Signed-off-by: Kieran Bingham --- This introduces an automatically mapping/unmapping MappedFrameBuffer object, with a move constructor (essential to prevent un-desirable unmapping). include/libcamera/buffer.h | 23 ++++++++++++++++++++ src/libcamera/buffer.cpp | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 6bb2e4f8558f..881d736da2db 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -71,6 +71,29 @@ private: unsigned int cookie_; }; +class MappedFrameBuffer { +public: + MappedFrameBuffer(const FrameBuffer *buffer, int flags); + ~MappedFrameBuffer(); + + /* Move constructor only, copying is not permitted. */ + MappedFrameBuffer(MappedFrameBuffer &&rhs); + + struct MappedPlane { + void *address; + size_t length; + }; + + bool isValid() const { return valid_; } + int error() const { return error_; } + const std::vector &maps() const { return maps_; } + +private: + int error_; + bool valid_; + std::vector maps_; +}; + } /* namespace libcamera */ #endif /* __LIBCAMERA_BUFFER_H__ */ diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 1a1d4bac7aed..28b43d937f57 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -290,4 +290,47 @@ int FrameBuffer::copyFrom(const FrameBuffer *src) return 0; } +/** + * \brief Map all planes of a FrameBuffer + * \param[in] src Buffer to be mapped + * \param[in] flags Protection flags to apply to map + * + * Construct an object to map a frame buffer for CPU access. + * The flags are passed directly to mmap and should be either PROT_READ, + * PROT_WRITE, or a bitwise-or combination of both. + */ +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags) + : error_(0) +{ + maps_.reserve(buffer->planes().size()); + + for (const FrameBuffer::Plane &plane : buffer->planes()) { + void *address = mmap(nullptr, plane.length, flags, + MAP_SHARED, plane.fd.fd(), 0); + + if (address == MAP_FAILED) { + error_ = -errno; + LOG(Buffer, Error) << "Failed to mmap plane"; + continue; + } + + maps_.push_back({address, plane.length}); + } + + valid_ = buffer->planes().size() == maps_.size(); +} + +MappedFrameBuffer::~MappedFrameBuffer() +{ + for (MappedPlane map : maps_) + munmap(map.address, map.length); +} + +MappedFrameBuffer::MappedFrameBuffer(MappedFrameBuffer &&rhs) +{ + error_ = rhs.error_; + valid_ = rhs.valid_; + maps_ = std::move(rhs.maps_); +} + } /* namespace libcamera */ From patchwork Mon Jul 20 22:42:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8894 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 4C5BBC0109 for ; Mon, 20 Jul 2020 22:42:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A2B4660832; Tue, 21 Jul 2020 00:42:39 +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="CHnfuP0r"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9CFF0605BF for ; Tue, 21 Jul 2020 00:42:37 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 351199E7; Tue, 21 Jul 2020 00:42:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284957; bh=CLF294+7yp0YKFvWJKqrht+70tMu+jd9WOdQcaMoClg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CHnfuP0rkKWuxhGLtoBgIApEbgReh4ej28Kjui9g1xnz28rRGsFGcGiqXdfR/ULAi NxindD1tUh6tOm13JQKa1KyZ5fHAApw36wgy57BkNHh7eXcGXlQ9CThz7hExz1+yga Ga9/R6ovyTpR00CLwNRJjIPorgS+l5x838R0a4n4= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:26 +0100 Message-Id: <20200720224232.153717-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 2/8] libcamera: buffer: Convert copyFrom to use MappedFrameBuffer 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" Utilise the new MappedFrameBuffer helper to handle all mapping and unmapping of the copyFrom helper function. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- This shows how the MappedFrameBuffer can then be utilised, even though I believe this particular copyFrom() function is expected to disappear sometime soon. src/libcamera/buffer.cpp | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index 28b43d937f57..af5345b91195 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -257,32 +257,23 @@ int FrameBuffer::copyFrom(const FrameBuffer *src) } } - for (unsigned int i = 0; i < planes_.size(); i++) { - void *dstmem = mmap(nullptr, planes_[i].length, PROT_WRITE, - MAP_SHARED, planes_[i].fd.fd(), 0); + MappedFrameBuffer source(src, PROT_READ); + MappedFrameBuffer destination(this, PROT_WRITE); - if (dstmem == MAP_FAILED) { - LOG(Buffer, Error) - << "Failed to map destination plane " << i; - metadata_.status = FrameMetadata::FrameError; - return -EINVAL; - } - - void *srcmem = mmap(nullptr, src->planes_[i].length, PROT_READ, - MAP_SHARED, src->planes_[i].fd.fd(), 0); - - if (srcmem == MAP_FAILED) { - munmap(dstmem, planes_[i].length); - LOG(Buffer, Error) - << "Failed to map source plane " << i; - metadata_.status = FrameMetadata::FrameError; - return -EINVAL; - } + if (!source.isValid()) { + LOG(Buffer, Error) << "Failed to map source planes"; + return -EINVAL; + } - memcpy(dstmem, srcmem, src->planes_[i].length); + if (!destination.isValid()) { + LOG(Buffer, Error) << "Failed to map destination planes"; + return -EINVAL; + } - munmap(srcmem, src->planes_[i].length); - munmap(dstmem, planes_[i].length); + for (unsigned int i = 0; i < planes_.size(); i++) { + memcpy(destination.maps()[i].address, + source.maps()[i].address, + source.maps()[i].length); } metadata_ = src->metadata_; From patchwork Mon Jul 20 22:42:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8895 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 F3369C2E67 for ; Mon, 20 Jul 2020 22:42:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 13CD86087E; Tue, 21 Jul 2020 00:42:40 +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="eWz/qbnu"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EDEEF605BB for ; Tue, 21 Jul 2020 00:42:37 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C9BDA49; Tue, 21 Jul 2020 00:42:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284957; bh=0/d+NRPlOjBZEzfEZjvq9MzBQ4q/8ZbSbxzpg7wdSTc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eWz/qbnu7/rgGjVIxadBd1eKMvQoUrRguPPnVmgY9sf9zO1+nu346mCo46Hsh7is3 Bg0OmrOMY5/dBPMcLLQ6ye/8sFroJ5TIb+4t/k/BXztbJn4WiC+r3zB0hVsL56JMxC 52DnCqjz98I9QL9epUU1W+vtD7mJ2rXK4ijWT0zQ= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:27 +0100 Message-Id: <20200720224232.153717-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 3/8] qcam: Convert to use MappedFrameBuffer 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" Remove the local mapping code, and utilise the libcamera buffer map helper class. Signed-off-by: Kieran Bingham --- Working towards a more generic MappedBuffer base interface of the newly introduced MappedFrameBuffer hits a snag that the viewfinder in qcam already defines a type which conflicts. Remove it by converting qcam to use the new MappedFrameBuffer types. src/qcam/main_window.cpp | 27 +++++++++++---------------- src/qcam/main_window.h | 2 +- src/qcam/viewfinder.cpp | 4 ++-- src/qcam/viewfinder.h | 7 +------ 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 7bc13603774e..b25260ba7b28 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -446,10 +446,14 @@ int MainWindow::startCapture() for (const std::unique_ptr &buffer : allocator_->buffers(stream)) { /* Map memory buffers and cache the mappings. */ - const FrameBuffer::Plane &plane = buffer->planes().front(); - void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED, - plane.fd.fd(), 0); - mappedBuffers_[buffer.get()] = { memory, plane.length }; + MappedFrameBuffer mapped(buffer.get(), PROT_READ); + if (!mapped.isValid()) { + qWarning() << "Failed to map buffer"; + ret = mapped.error(); + goto error; + } + + mappedBuffers_.insert({buffer.get(), std::move(mapped)}); /* Store buffers on the free list. */ freeBuffers_[stream].enqueue(buffer.get()); @@ -512,12 +516,7 @@ error: for (Request *request : requests) delete request; - for (auto &iter : mappedBuffers_) { - const MappedBuffer &buffer = iter.second; - munmap(buffer.memory, buffer.size); - } mappedBuffers_.clear(); - freeBuffers_.clear(); delete allocator_; @@ -548,10 +547,6 @@ void MainWindow::stopCapture() camera_->requestCompleted.disconnect(this, &MainWindow::requestComplete); - for (auto &iter : mappedBuffers_) { - const MappedBuffer &buffer = iter.second; - munmap(buffer.memory, buffer.size); - } mappedBuffers_.clear(); delete allocator_; @@ -643,10 +638,10 @@ void MainWindow::processRaw(FrameBuffer *buffer, const ControlList &metadata) "DNG Files (*.dng)"); if (!filename.isEmpty()) { - const MappedBuffer &mapped = mappedBuffers_[buffer]; + const MappedFrameBuffer &mapped = mappedBuffers_.at(buffer); DNGWriter::write(filename.toStdString().c_str(), camera_.get(), rawStream_->configuration(), metadata, buffer, - mapped.memory); + mapped.maps()[0].address); } #endif @@ -720,7 +715,7 @@ void MainWindow::processViewfinder(FrameBuffer *buffer) << "fps:" << Qt::fixed << qSetRealNumberPrecision(2) << fps; /* Render the frame on the viewfinder. */ - viewfinder_->render(buffer, &mappedBuffers_[buffer]); + viewfinder_->render(buffer, &mappedBuffers_.at(buffer)); } void MainWindow::queueRequest(FrameBuffer *buffer) diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 4606fe487ad4..ddf51ca01111 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -119,7 +119,7 @@ private: FrameBufferAllocator *allocator_; std::unique_ptr config_; - std::map mappedBuffers_; + std::map mappedBuffers_; /* Capture state, buffers queue and statistics */ bool isCapturing_; diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp index dcf8a15d2df6..591d26eae87c 100644 --- a/src/qcam/viewfinder.cpp +++ b/src/qcam/viewfinder.cpp @@ -78,14 +78,14 @@ int ViewFinder::setFormat(const libcamera::PixelFormat &format, return 0; } -void ViewFinder::render(libcamera::FrameBuffer *buffer, MappedBuffer *map) +void ViewFinder::render(libcamera::FrameBuffer *buffer, libcamera::MappedFrameBuffer *map) { if (buffer->planes().size() != 1) { qWarning() << "Multi-planar buffers are not supported"; return; } - unsigned char *memory = static_cast(map->memory); + unsigned char *memory = static_cast(map->maps()[0].address); size_t size = buffer->metadata().planes[0].bytesused; { diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h index 26a1320537d2..c4cc51f14dda 100644 --- a/src/qcam/viewfinder.h +++ b/src/qcam/viewfinder.h @@ -23,11 +23,6 @@ class QImage; -struct MappedBuffer { - void *memory; - size_t size; -}; - class ViewFinder : public QWidget { Q_OBJECT @@ -39,7 +34,7 @@ public: const QList &nativeFormats() const; int setFormat(const libcamera::PixelFormat &format, const QSize &size); - void render(libcamera::FrameBuffer *buffer, MappedBuffer *map); + void render(libcamera::FrameBuffer *buffer, libcamera::MappedFrameBuffer *map); void stop(); QImage getCurrentImage(); From patchwork Mon Jul 20 22:42:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8896 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 3D11AC0109 for ; Mon, 20 Jul 2020 22:42:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5695760890; Tue, 21 Jul 2020 00:42:40 +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="SPkAmrb5"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 60DBC605BB for ; Tue, 21 Jul 2020 00:42:38 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E29122A4; Tue, 21 Jul 2020 00:42:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284958; bh=Ao/ddpZ6hPuJ7yXhHH3kjZ7OtE5OS8ZtmY1Lkks+YPM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SPkAmrb5AlGw3nalq1T0WNOtyaWGpFTF+2g8+SiPBRfrC6/gXwo8PZE8ZZugJzGQ2 6XJh8zrrkf4UtUlJTJ+5A1T5sieaxZ+CnbWG2zl2+MJfRPDDoG/csPNo9mXKdT9ELp 6bfqsTPcDRlvdBi1SR80UHvybH+s9jx8WkBAvpEw= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:28 +0100 Message-Id: <20200720224232.153717-5-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 4/8] buffer: Provide a base MappedBuffer class 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" Move the interface of the MappedFrameBuffer to a MappedBuffer class to provide a common interface of mapped buffers from different sources. This allows MappedBuffer instances to be created from Camera3Buffer types. Signed-off-by: Kieran Bingham --- Now we can create our new base class, the MappedBuffer. I can see this going further to also push the mmap down to a MappedDmaBuf, but that can be on top/later or if this general automatic mapping approach is desired at all.... include/libcamera/buffer.h | 16 +++++--- src/libcamera/buffer.cpp | 80 +++++++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 20 deletions(-) diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 881d736da2db..558204e5a09b 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -71,13 +71,12 @@ private: unsigned int cookie_; }; -class MappedFrameBuffer { +class MappedBuffer { public: - MappedFrameBuffer(const FrameBuffer *buffer, int flags); - ~MappedFrameBuffer(); - + MappedBuffer(); /* Move constructor only, copying is not permitted. */ - MappedFrameBuffer(MappedFrameBuffer &&rhs); + MappedBuffer(MappedBuffer &&rhs); + ~MappedBuffer(); struct MappedPlane { void *address; @@ -88,12 +87,17 @@ public: int error() const { return error_; } const std::vector &maps() const { return maps_; } -private: +protected: int error_; bool valid_; std::vector maps_; }; +class MappedFrameBuffer : public MappedBuffer { +public: + MappedFrameBuffer(const FrameBuffer *buffer, int flags); +}; + } /* namespace libcamera */ #endif /* __LIBCAMERA_BUFFER_H__ */ diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index af5345b91195..0fe12ab93b58 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -281,6 +281,72 @@ int FrameBuffer::copyFrom(const FrameBuffer *src) return 0; } +/** + * \brief Construct an empty MappedBuffer + * + * A default constructor is required to allow subclassing the MappedBuffer + * class. Construct an initialised, but invalid MappedBuffer. + */ +MappedBuffer::MappedBuffer() + : error_(0), valid_(false) +{ +} + +/** + * \brief Move constructor, create a MappedBuffer by taking the \a rhs mappings + * \param[in] rhs The other MappedBuffer + * + * Moving a MappedBuffer moves the mappings contained in the \a rhs to the new + * MappedBuffer and invalidates the \a rhs. No mappings are unmapped or + * destroyed in this process. + */ +MappedBuffer::MappedBuffer(MappedBuffer &&rhs) +{ + error_ = rhs.error_; + valid_ = rhs.valid_; + maps_ = std::move(rhs.maps_); + rhs.valid_ = false; + rhs.error_ = 0; +} + +MappedBuffer::~MappedBuffer() +{ + for (MappedPlane map : maps_) + munmap(map.address, map.length); +} + +/** + * \fn MappedBuffer::isValid() + * \brief Check if the MappedBuffer instance is valid + * \return True if the MappedBuffer has valid mappings, false otherwise + */ + +/** + * \fn MappedBuffer::error() + * \brief Retrieve the map error status + * + * This function retrieves the error status from the MappedBuffer. + * The error status is a negative number as defined by errno.h. If + * no error occurred, this function returns 0. + */ + +/** + * \var MappedBuffer::valid_ + * \brief Stores the status of the mapping + * + * MappedBuffer implementations shall set this to represent if the mapping + * was successfully completed without errors. + */ + + +/** + * \var MappedBuffer::error_ + * \brief Stores the error value if present + * + * MappedBuffer implementations shall set this to a negative value as defined + * by errno.h if an error occured during the mapping process + */ + /** * \brief Map all planes of a FrameBuffer * \param[in] src Buffer to be mapped @@ -291,7 +357,6 @@ int FrameBuffer::copyFrom(const FrameBuffer *src) * PROT_WRITE, or a bitwise-or combination of both. */ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags) - : error_(0) { maps_.reserve(buffer->planes().size()); @@ -311,17 +376,4 @@ MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags) valid_ = buffer->planes().size() == maps_.size(); } -MappedFrameBuffer::~MappedFrameBuffer() -{ - for (MappedPlane map : maps_) - munmap(map.address, map.length); -} - -MappedFrameBuffer::MappedFrameBuffer(MappedFrameBuffer &&rhs) -{ - error_ = rhs.error_; - valid_ = rhs.valid_; - maps_ = std::move(rhs.maps_); -} - } /* namespace libcamera */ From patchwork Mon Jul 20 22:42:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8897 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 72A07C2E68 for ; Mon, 20 Jul 2020 22:42:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BAA49608A0; Tue, 21 Jul 2020 00:42:40 +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="Qk7ClZGp"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C274E605BB for ; Tue, 21 Jul 2020 00:42:38 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4B001563; Tue, 21 Jul 2020 00:42:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284958; bh=CIJiScVilazsTkJLAVPYGXBBRQhLfiiZd8rAJSud8r4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qk7ClZGpn8Xs6sHDlskWmdyknwNOcFElFvRsYDjjUqsPLtrB4pdPKl+4P8fXCn6OE Ueb4DrK9yBFaz24J2wHyU47wPYoF4HorLEB9KPHs6K3AFs4ZmIOCh1CtU3H/cqXFPH cHNs2z3R+AiWvFhqM+7zK7ErTmizeZgHKhr8NXwk= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:29 +0100 Message-Id: <20200720224232.153717-6-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 5/8] android: camera_device: Report an error in notifyError() 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" If an error is generated, try to be verbose about it in the libcamera logs. Signed-off-by: Kieran Bingham Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- A little unrelated from the RFC series, but in the tree and at v2, so posted anyway.... This helps ;-) v2: - Add todo to note possible debug info expansion - Fix typo - Print .toString() formatted pixel format src/android/camera_device.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 48f8090a93db..e5c50084e590 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1209,6 +1209,13 @@ void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream) { camera3_notify_msg_t notify = {}; + /* + * \todo: Report and identify the stream number or configuration to + * clarify the stream that failed. + */ + LOG(HAL, Error) << "Error occurred on frame " << frameNumber << " (" + << toPixelFormat(stream->format).toString() << ")"; + notify.type = CAMERA3_MSG_ERROR; notify.message.error.error_stream = stream; notify.message.error.frame_number = frameNumber; From patchwork Mon Jul 20 22:42:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8898 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 AF0DCC0109 for ; Mon, 20 Jul 2020 22:42:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7C3CF6073C; Tue, 21 Jul 2020 00:42:45 +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="DNA/6x/m"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2FBDA607CB for ; Tue, 21 Jul 2020 00:42:39 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AE2C09E7; Tue, 21 Jul 2020 00:42:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284958; bh=A9/O4GRyE6wLJVHxigPTzDQbLMi/FtROcKcri04dwk4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DNA/6x/mAiqmqozP5YYAI9+DfeMZywiWx4zsIyMxtNqD3lpe/07JZcG1kD6IGkOgG 0Lzg7JkZxRqOZP4G/peo6UepXEvSWrLURJtGxDchbItmZBHRBV8G9QjE5WbmmYq/Qb fQCP981v+jOB558F+JkDSSFs3cuQskVt+0eEGFBk= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:30 +0100 Message-Id: <20200720224232.153717-7-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 6/8] android: camera_device: Only construct required planes 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 camera3buffer describes the number of filedescriptors given. Don't try to construct more planes than that. Signed-off-by: Kieran Bingham --- We always try to create 3 planes, and we never check if the FileDescriptor is valid. Instead, use the numFds provided by the camera3buffer, but check to see if the FileDescriptor was valid before adding the plane to the FrameBuffer. I have a further check in a later patch which skips planes where the camera3buffer->data[i] is already set to -1, so we know it's invalid, and this removes the warning below, leaving us with two planes created for all buffers tested using the Camera app. src/android/camera_device.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index e5c50084e590..538b8ab5da03 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1033,9 +1033,18 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list) FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer) { std::vector planes; - for (unsigned int i = 0; i < 3; i++) { + for (int i = 0; i < camera3buffer->numFds; i++) { FrameBuffer::Plane plane; plane.fd = FileDescriptor(camera3buffer->data[i]); + + /* numFds is seemingly always 4... */ + if (!plane.fd.isValid()) { + LOG(HAL, Debug) << "Created an invalid plane... (" + << camera3buffer->data[i] << ") " + << i << "/" << camera3buffer->numFds; + continue; + } + /* * Setting length to zero here is OK as the length is only used * to map the memory of the plane. Libcamera do not need to poke From patchwork Mon Jul 20 22:42:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8899 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 1CB24C2E67 for ; Mon, 20 Jul 2020 22:42:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DC799607CB; Tue, 21 Jul 2020 00:42:45 +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="qqekhroF"; 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 7CF6B6081E for ; Tue, 21 Jul 2020 00:42:39 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 10C8EA49; Tue, 21 Jul 2020 00:42:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284959; bh=R+cpnFHtqQo7aKOYXlpN0kq0AcvZ7mdtSsLO3YpKlpE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qqekhroFRxLkckpLWE31ZppSeCaFApZTFq9FGxPfICjR013mgLJ8NXhBmSXAezV1q x973iSP1Ji3jP4NMhgg+lIPlzrglMsPyJU+jh1bdeWQv6dQC03jUzPm5SuPT5hL3qH /O6xI9NVwhITFX1KKy38ooBiJXD+7781NTHsLldg= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:31 +0100 Message-Id: <20200720224232.153717-8-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 7/8] android: camera_device: Query plane length 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 lseek to query the length of planes where possible rather than leaving the plane.length as zero, which prevents mapping buffers for software processing. Signed-off-by: Kieran Bingham --- I like this one ;-) We need to know the plane lengths for software streams now, but the correct way to get this would be to talk to the gralloc allocator. This would mean pulling in various extra cros-specific libraries, where instead we can query the size of the dmabuf by getting the offset when we SEEK_END. src/android/camera_device.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 538b8ab5da03..6212ccdd61ec 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1045,12 +1045,18 @@ FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer continue; } - /* - * Setting length to zero here is OK as the length is only used - * to map the memory of the plane. Libcamera do not need to poke - * at the memory content queued by the HAL. - */ - plane.length = 0; + off_t length = lseek(plane.fd.fd(), 0, SEEK_END); + if (length == -1) { + /* + * A zero length plane is not fatal unless the + * FrameBuffer is used for a software stream, libcamera + * itself will not access the internal frame content. + */ + LOG(HAL, Error) << "Failed to query plane length"; + length = 0; + } + + plane.length = length; planes.push_back(std::move(plane)); } From patchwork Mon Jul 20 22:42:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 8900 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 816D4C0109 for ; Mon, 20 Jul 2020 22:42:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4A1BD605C6; Tue, 21 Jul 2020 00:42:46 +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="RlrB1Mpp"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C9F7460868 for ; Tue, 21 Jul 2020 00:42:39 +0200 (CEST) Received: from localhost.localdomain (cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 66A8F2A4; Tue, 21 Jul 2020 00:42:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1595284959; bh=b+RJdw7AB5+v7lD8xvW9oNeJ88FYZV30jIahUr+L2/s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RlrB1MppXjoINy8Oic1BAU82SCRU3ZjsmLoYksFyTO02cIRtbmsHbi0EC7YP/iYzh 4P+ea9Ot5OeyAtSMdaQqC1cvcgXwehZJdHOl1Temq9XgXhyjCJMEDtU0UhGuzXEMkJ 9fSB2EXD2gGuvkAfEzY/kwMe4HPRGg9QuFZ8qpfU= From: Kieran Bingham To: libcamera devel Date: Mon, 20 Jul 2020 23:42:32 +0100 Message-Id: <20200720224232.153717-9-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> References: <20200720224232.153717-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH 8/8] RFC-Only: android: camera_device: Provide a MappedCamera3Buffer 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" Utilise the MappedBuffer interface to map each of the planes provided in the Camera3 buffer to facilitate use in software streams. The buffers will be automatically unmapped when the object goes out of scope or is deleted. Signed-off-by: Kieran Bingham --- This patch shows an addition of a new MappedBuffer type constructed from a camera3buffer. The base class deals with the move-constructors and destructor, and gives us a common interface to pass a set of mapped dmabufs around. I had hoped to use this to pass in the camera3buffer for writing jpeg buffers to, giving the same interface for both the source and destination buffer - but for JPEG, I do also need to return the number of bytes actually consumed, so this ended up potentially not adding the benefits I hoped for. Still, it might still provide some benefits, so I've included it here as something to talk about. -- Kieran src/android/camera_device.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 6212ccdd61ec..f78486117e9f 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -86,6 +86,39 @@ const std::map camera3FormatsMap = { LOG_DECLARE_CATEGORY(HAL); +class MappedCamera3Buffer : public MappedBuffer { +public: + MappedCamera3Buffer(const buffer_handle_t camera3buffer, int flags) + { + maps_.reserve(camera3buffer->numFds); + error_ = 0; + + for (int i = 0; i < camera3buffer->numFds; i++) { + if (camera3buffer->data[i] == -1) + continue; + + off_t length = lseek(camera3buffer->data[i], 0, SEEK_END); + if (length < 0) { + error_ = errno; + LOG(HAL, Error) << "Failed to query plane length"; + break; + } + + void *address = mmap(nullptr, length, flags, MAP_SHARED, + camera3buffer->data[i], 0); + if (address == MAP_FAILED) { + error_ = errno; + LOG(HAL, Error) << "Failed to mmap plane"; + break; + } + + maps_.push_back({address, static_cast(length)}); + } + + valid_ = error_ == 0; + } +}; + /* * \struct Camera3RequestDescriptor *