From patchwork Mon Aug 9 13:29:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 13258 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 42B90C3240 for ; Mon, 9 Aug 2021 13:29:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AB3796888C; Mon, 9 Aug 2021 15:29:35 +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="NhbcKpfI"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B63D7687EB for ; Mon, 9 Aug 2021 15:29:33 +0200 (CEST) Received: from Monstersaurus.local (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6309449A; Mon, 9 Aug 2021 15:29:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628515773; bh=nR0uUsHzn10IUFikqDTW8JzeDzUSgH6ImPRQyF+2zAk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NhbcKpfI/F9mvTI46ejmjZ45pFZIKFTlnhUBC05sjwVfrtpabGfgjjBvRtwZSPOwH pjaObMWnb9/Q+aRdVAWwaTYawE51WAXSlV+TqO8OIr03+lVU4hcbMjqodkbx8ETvNA M4uDBSq7RlgvMsYQH1pkkrPDgd6LKuUYrWtmPxW0= From: Kieran Bingham To: libcamera devel Date: Mon, 9 Aug 2021 14:29:27 +0100 Message-Id: <20210809132929.1824114-2-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210809132929.1824114-1-kieran.bingham@ideasonboard.com> References: <20210809132929.1824114-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/3] src: Remove all unused sys/mman.h inclusions 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 leftover inclusions of the sys/mman header file. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 1 - src/libcamera/ipa_module.cpp | 1 - src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 1 - src/libcamera/v4l2_videodevice.cpp | 1 - src/v4l2/v4l2_camera_proxy.h | 1 - src/v4l2/v4l2_compat_manager.h | 1 - 6 files changed, 6 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 3266c495d0ca..59b37bc864b5 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include diff --git a/src/libcamera/ipa_module.cpp b/src/libcamera/ipa_module.cpp index 7c52ad8d5796..908f2e07bd3f 100644 --- a/src/libcamera/ipa_module.cpp +++ b/src/libcamera/ipa_module.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 0bab3bedd402..2e8774ae360d 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index da2af6a13dfb..cddabad753e1 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index 92a79abb9e21..f1a8b61c5eac 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h index bc548ab2a8bd..1ec46162211d 100644 --- a/src/v4l2/v4l2_compat_manager.h +++ b/src/v4l2/v4l2_compat_manager.h @@ -11,7 +11,6 @@ #include #include #include -#include #include #include From patchwork Mon Aug 9 13:29:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 13259 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 EC3E6C3241 for ; Mon, 9 Aug 2021 13:29:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5C18368855; Mon, 9 Aug 2021 15:29:36 +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="rpGhScOT"; 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 04EA960269 for ; Mon, 9 Aug 2021 15:29:34 +0200 (CEST) Received: from Monstersaurus.local (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A0FA94A1; Mon, 9 Aug 2021 15:29:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628515773; bh=Fu0NlCAT9MHZKEb6kLV3KSvWeBaZ650is12SCtVSmUA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rpGhScOTJZbIMowIQcVaQDENBkGka0f8vhi//2M279C+REWMrwmTCLmTfUndcdl3S mMPX3PRMmPIxB3AtKiPnFz1gF1d+h/TZUAGHi6M+rocLN4x6Z3OooabdPZwk9qgRdL g2Tej4tTLglPyuVpA7RBkhJWeRiZ2mpDDcKz6ufY= From: Kieran Bingham To: libcamera devel Date: Mon, 9 Aug 2021 14:29:28 +0100 Message-Id: <20210809132929.1824114-3-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210809132929.1824114-1-kieran.bingham@ideasonboard.com> References: <20210809132929.1824114-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/3] libcamera: Give MappedFrameBuffer its own implementation 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 MappedFrameBuffer is a convenience feature which sits on top of the FrameBuffer and facilitates mapping it to CPU accessible memory with mmap. This implementation is internal and currently sits in the same internal files as the internal FrameBuffer, thus exposing those internals to users of the MappedFramebuffer implementation. Move the MappedFrameBuffer and MappedBuffer implementation to its own implementation files, and fix the sources throughout to use that accordingly. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- include/libcamera/internal/framebuffer.h | 36 ---- .../libcamera/internal/mapped_framebuffer.h | 52 ++++++ include/libcamera/internal/meson.build | 1 + src/android/camera_device.h | 2 - src/android/camera_stream.cpp | 2 + src/android/camera_stream.h | 2 - src/android/jpeg/encoder_libjpeg.cpp | 1 + src/android/jpeg/encoder_libjpeg.h | 1 - src/android/jpeg/post_processor_jpeg.h | 2 - src/android/jpeg/thumbnailer.cpp | 2 + src/android/jpeg/thumbnailer.h | 2 +- src/android/mm/generic_camera_buffer.cpp | 3 +- src/android/post_processor.h | 2 - src/android/yuv/post_processor_yuv.cpp | 1 + src/ipa/ipu3/ipu3.cpp | 2 +- src/ipa/raspberrypi/raspberrypi.cpp | 2 +- src/libcamera/framebuffer.cpp | 145 --------------- src/libcamera/mapped_framebuffer.cpp | 171 ++++++++++++++++++ src/libcamera/meson.build | 1 + test/mapped-buffer.cpp | 2 +- 20 files changed, 237 insertions(+), 195 deletions(-) create mode 100644 include/libcamera/internal/mapped_framebuffer.h create mode 100644 src/libcamera/mapped_framebuffer.cpp diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index 8c187adf70c7..1352578a6cfb 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -7,46 +7,10 @@ #ifndef __LIBCAMERA_INTERNAL_FRAMEBUFFER_H__ #define __LIBCAMERA_INTERNAL_FRAMEBUFFER_H__ -#include -#include - -#include -#include - #include namespace libcamera { -class MappedBuffer -{ -public: - using Plane = Span; - - ~MappedBuffer(); - - MappedBuffer(MappedBuffer &&other); - MappedBuffer &operator=(MappedBuffer &&other); - - bool isValid() const { return error_ == 0; } - int error() const { return error_; } - const std::vector &maps() const { return maps_; } - -protected: - MappedBuffer(); - - int error_; - std::vector maps_; - -private: - LIBCAMERA_DISABLE_COPY(MappedBuffer) -}; - -class MappedFrameBuffer : public MappedBuffer -{ -public: - MappedFrameBuffer(const FrameBuffer *buffer, int flags); -}; - class FrameBuffer::Private : public Extensible::Private { LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h new file mode 100644 index 000000000000..41e587364260 --- /dev/null +++ b/include/libcamera/internal/mapped_framebuffer.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * mapped_framebuffer.h - Frame buffer memory mapping support + */ +#ifndef __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ +#define __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ + +#include +#include + +#include +#include + +#include + +namespace libcamera { + +class MappedBuffer +{ +public: + using Plane = Span; + + ~MappedBuffer(); + + MappedBuffer(MappedBuffer &&other); + MappedBuffer &operator=(MappedBuffer &&other); + + bool isValid() const { return error_ == 0; } + int error() const { return error_; } + const std::vector &maps() const { return maps_; } + +protected: + MappedBuffer(); + + int error_; + std::vector maps_; + +private: + LIBCAMERA_DISABLE_COPY(MappedBuffer) +}; + +class MappedFrameBuffer : public MappedBuffer +{ +public: + MappedFrameBuffer(const FrameBuffer *buffer, int flags); +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ */ diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build index dac1a2d36fa8..665fd6de4ed3 100644 --- a/include/libcamera/internal/meson.build +++ b/include/libcamera/internal/meson.build @@ -28,6 +28,7 @@ libcamera_internal_headers = files([ 'ipa_module.h', 'ipa_proxy.h', 'ipc_unixsocket.h', + 'mapped_framebuffer.h', 'media_device.h', 'media_object.h', 'pipeline_handler.h', diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 089a6204605e..dd9aebba7553 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -24,8 +24,6 @@ #include #include -#include "libcamera/internal/framebuffer.h" - #include "camera_capabilities.h" #include "camera_metadata.h" #include "camera_stream.h" diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index bf4a7b41a70a..61b441830e18 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -7,6 +7,8 @@ #include "camera_stream.h" +#include + #include "camera_buffer.h" #include "camera_device.h" #include "camera_metadata.h" diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 629d9e00e08d..2dab6c3a37d1 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -19,8 +19,6 @@ #include #include -#include "libcamera/internal/framebuffer.h" - class CameraDevice; class CameraMetadata; class PostProcessor; diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index e6358ca9466f..372018d2207f 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -23,6 +23,7 @@ #include #include "libcamera/internal/formats.h" +#include "libcamera/internal/mapped_framebuffer.h" using namespace libcamera; diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h index 14bf89223982..61fbd1a69278 100644 --- a/src/android/jpeg/encoder_libjpeg.h +++ b/src/android/jpeg/encoder_libjpeg.h @@ -10,7 +10,6 @@ #include "encoder.h" #include "libcamera/internal/formats.h" -#include "libcamera/internal/framebuffer.h" #include diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h index 5c399be9eb6a..6fd3102229ab 100644 --- a/src/android/jpeg/post_processor_jpeg.h +++ b/src/android/jpeg/post_processor_jpeg.h @@ -13,8 +13,6 @@ #include -#include "libcamera/internal/framebuffer.h" - class CameraDevice; class PostProcessorJpeg : public PostProcessor diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp index 5cb00744a688..535e2cece914 100644 --- a/src/android/jpeg/thumbnailer.cpp +++ b/src/android/jpeg/thumbnailer.cpp @@ -11,6 +11,8 @@ #include +#include "libcamera/internal/mapped_framebuffer.h" + using namespace libcamera; LOG_DEFINE_CATEGORY(Thumbnailer) diff --git a/src/android/jpeg/thumbnailer.h b/src/android/jpeg/thumbnailer.h index 68cbf74329a9..4d086c4943b0 100644 --- a/src/android/jpeg/thumbnailer.h +++ b/src/android/jpeg/thumbnailer.h @@ -7,10 +7,10 @@ #ifndef __ANDROID_JPEG_THUMBNAILER_H__ #define __ANDROID_JPEG_THUMBNAILER_H__ +#include #include #include "libcamera/internal/formats.h" -#include "libcamera/internal/framebuffer.h" class Thumbnailer { diff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp index 2a4b77ea5236..b3af194c21dd 100644 --- a/src/android/mm/generic_camera_buffer.cpp +++ b/src/android/mm/generic_camera_buffer.cpp @@ -7,11 +7,12 @@ #include "../camera_buffer.h" +#include #include #include -#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" using namespace libcamera; diff --git a/src/android/post_processor.h b/src/android/post_processor.h index 689f85d9d3b8..ab2b2c606fd0 100644 --- a/src/android/post_processor.h +++ b/src/android/post_processor.h @@ -10,8 +10,6 @@ #include #include -#include "libcamera/internal/framebuffer.h" - #include "camera_buffer.h" class CameraMetadata; diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp index 772e805b32cc..509d4244d614 100644 --- a/src/android/yuv/post_processor_yuv.cpp +++ b/src/android/yuv/post_processor_yuv.cpp @@ -16,6 +16,7 @@ #include #include "libcamera/internal/formats.h" +#include "libcamera/internal/mapped_framebuffer.h" using namespace libcamera; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 71698d36e50f..2647bf2f3b96 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -20,7 +20,7 @@ #include #include -#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" #include "ipu3_agc.h" #include "ipu3_awb.h" diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 48e11c699f29..76f67dd4567a 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -28,7 +28,7 @@ #include #include -#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" #include "agc_algorithm.hpp" #include "agc_status.h" diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index a59e93fbdf91..3d98affb20f9 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -251,149 +251,4 @@ Request *FrameBuffer::request() const * indicate that the metadata is invalid. */ -/** - * \class MappedBuffer - * \brief Provide an interface to support managing memory mapped buffers - * - * The MappedBuffer interface provides access to a set of MappedPlanes which - * are available for access by the CPU. - * - * This class is not meant to be constructed directly, but instead derived - * classes should be used to implement the correct mapping of a source buffer. - * - * This allows treating CPU accessible memory through a generic interface - * regardless of whether it originates from a libcamera FrameBuffer or other - * source. - */ - -/** - * \typedef MappedBuffer::Plane - * \brief A mapped region of memory accessible to the CPU - * - * The MappedBuffer::Plane uses the Span interface to describe the mapped memory - * region. - */ - -/** - * \brief Construct an empty MappedBuffer - */ -MappedBuffer::MappedBuffer() - : error_(0) -{ -} - -/** - * \brief Move constructor, construct the MappedBuffer with the contents of \a - * other using move semantics - * \param[in] other The other MappedBuffer - * - * Moving a MappedBuffer moves the mappings contained in the \a other to the new - * MappedBuffer and invalidates the \a other. - * - * No mappings are unmapped or destroyed in this process. - */ -MappedBuffer::MappedBuffer(MappedBuffer &&other) -{ - *this = std::move(other); -} - -/** - * \brief Move assignment operator, replace the mappings with those of \a other -* \param[in] other The other MappedBuffer - * - * Moving a MappedBuffer moves the mappings contained in the \a other to the new - * MappedBuffer and invalidates the \a other. - * - * No mappings are unmapped or destroyed in this process. - */ -MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other) -{ - error_ = other.error_; - maps_ = std::move(other.maps_); - other.error_ = -ENOENT; - - return *this; -} - -MappedBuffer::~MappedBuffer() -{ - for (Plane &map : maps_) - munmap(map.data(), map.size()); -} - -/** - * \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. - * - * \return The map error code - */ - -/** - * \fn MappedBuffer::maps() - * \brief Retrieve the mapped planes - * - * This function retrieves the successfully mapped planes stored as a vector - * of Span to provide access to the mapped memory. - * - * \return A vector of the mapped planes - */ - -/** - * \var MappedBuffer::error_ - * \brief Stores the error value if present - * - * MappedBuffer derived classes shall set this to a negative value as defined - * by errno.h if an error occured during the mapping process. - */ - -/** - * \var MappedBuffer::maps_ - * \brief Stores the internal mapped planes - * - * MappedBuffer derived classes shall store the mappings they create in this - * vector which is parsed during destruct to unmap any memory mappings which - * completed successfully. - */ - -/** - * \class MappedFrameBuffer - * \brief Map a FrameBuffer using the MappedBuffer interface - */ - -/** - * \brief Map all planes of a FrameBuffer - * \param[in] buffer FrameBuffer 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) -{ - 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"; - break; - } - - maps_.emplace_back(static_cast(address), plane.length); - } -} - } /* namespace libcamera */ diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp new file mode 100644 index 000000000000..0e30fc542154 --- /dev/null +++ b/src/libcamera/mapped_framebuffer.cpp @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2021, Google Inc. + * + * mapped_framebuffer.cpp - Mapped Framebuffer support + */ + +#include "libcamera/internal/mapped_framebuffer.h" + +#include +#include +#include +#include + +#include + +/** + * \file libcamera/internal/mapped_framebuffer.h + * \brief Frame buffer memory mapping support + */ + +namespace libcamera { + +LOG_DECLARE_CATEGORY(Buffer) + +/** + * \class MappedBuffer + * \brief Provide an interface to support managing memory mapped buffers + * + * The MappedBuffer interface provides access to a set of MappedPlanes which + * are available for access by the CPU. + * + * This class is not meant to be constructed directly, but instead derived + * classes should be used to implement the correct mapping of a source buffer. + * + * This allows treating CPU accessible memory through a generic interface + * regardless of whether it originates from a libcamera FrameBuffer or other + * source. + */ + +/** + * \typedef MappedBuffer::Plane + * \brief A mapped region of memory accessible to the CPU + * + * The MappedBuffer::Plane uses the Span interface to describe the mapped memory + * region. + */ + +/** + * \brief Construct an empty MappedBuffer + */ +MappedBuffer::MappedBuffer() + : error_(0) +{ +} + +/** + * \brief Move constructor, construct the MappedBuffer with the contents of \a + * other using move semantics + * \param[in] other The other MappedBuffer + * + * Moving a MappedBuffer moves the mappings contained in the \a other to the new + * MappedBuffer and invalidates the \a other. + * + * No mappings are unmapped or destroyed in this process. + */ +MappedBuffer::MappedBuffer(MappedBuffer &&other) +{ + *this = std::move(other); +} + +/** + * \brief Move assignment operator, replace the mappings with those of \a other +* \param[in] other The other MappedBuffer + * + * Moving a MappedBuffer moves the mappings contained in the \a other to the new + * MappedBuffer and invalidates the \a other. + * + * No mappings are unmapped or destroyed in this process. + */ +MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other) +{ + error_ = other.error_; + maps_ = std::move(other.maps_); + other.error_ = -ENOENT; + + return *this; +} + +MappedBuffer::~MappedBuffer() +{ + for (Plane &map : maps_) + munmap(map.data(), map.size()); +} + +/** + * \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. + * + * \return The map error code + */ + +/** + * \fn MappedBuffer::maps() + * \brief Retrieve the mapped planes + * + * This function retrieves the successfully mapped planes stored as a vector + * of Span to provide access to the mapped memory. + * + * \return A vector of the mapped planes + */ + +/** + * \var MappedBuffer::error_ + * \brief Stores the error value if present + * + * MappedBuffer derived classes shall set this to a negative value as defined + * by errno.h if an error occured during the mapping process. + */ + +/** + * \var MappedBuffer::maps_ + * \brief Stores the internal mapped planes + * + * MappedBuffer derived classes shall store the mappings they create in this + * vector which is parsed during destruct to unmap any memory mappings which + * completed successfully. + */ + +/** + * \class MappedFrameBuffer + * \brief Map a FrameBuffer using the MappedBuffer interface + */ + +/** + * \brief Map all planes of a FrameBuffer + * \param[in] buffer FrameBuffer 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) +{ + 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"; + break; + } + + maps_.emplace_back(static_cast(address), plane.length); + } +} + +} /* namespace libcamera */ diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build index 4f08580157f9..e9230b983aeb 100644 --- a/src/libcamera/meson.build +++ b/src/libcamera/meson.build @@ -28,6 +28,7 @@ libcamera_sources = files([ 'ipc_pipe.cpp', 'ipc_pipe_unixsocket.cpp', 'ipc_unixsocket.cpp', + 'mapped_framebuffer.cpp', 'media_device.cpp', 'media_object.cpp', 'pipeline_handler.cpp', diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp index c9479194cb68..a3d1511b74ce 100644 --- a/test/mapped-buffer.cpp +++ b/test/mapped-buffer.cpp @@ -9,7 +9,7 @@ #include -#include "libcamera/internal/framebuffer.h" +#include "libcamera/internal/mapped_framebuffer.h" #include "camera_test.h" #include "test.h" From patchwork Mon Aug 9 13:29:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 13260 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 72BF5C3240 for ; Mon, 9 Aug 2021 13:29:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 10E2A6888F; Mon, 9 Aug 2021 15:29:37 +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="MyxhvDJl"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 364F6687EB for ; Mon, 9 Aug 2021 15:29:34 +0200 (CEST) Received: from Monstersaurus.local (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E4038466; Mon, 9 Aug 2021 15:29:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1628515774; bh=iUclvwjcSIfmMFqvje7WD4iCW7ht+/NxdX9uVklz3uA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MyxhvDJluQJpd7zIhuTEAxp62z7ouySlNu+2fug/ZhR/xLuf+Gj32ZXqyQQGgvtg0 N14hNdB5HNF6bh6L4KPvZF1NXcoVARN2SeDcvCqi4KLha19cU7p2to1QRG/AgnqckU tJfkBK5cslun6LFx5VRZOCXJWA3AlBye1qU9ACPQ= From: Kieran Bingham To: libcamera devel Date: Mon, 9 Aug 2021 14:29:29 +0100 Message-Id: <20210809132929.1824114-4-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210809132929.1824114-1-kieran.bingham@ideasonboard.com> References: <20210809132929.1824114-1-kieran.bingham@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer: Use typed Flags 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 need for callers to reference PROT_READ/PROT_WRITE directly from by instead exposing the Read/Write mapping options as flags from the MappedFrameBuffer class itself. While here, introduce the header which is required for the uint8_t as part of the Plane. Signed-off-by: Kieran Bingham Reviewed-by: Laurent Pinchart Reviewed-by: Hirokazu Honda --- v2 - Use fully scoped enum class - Swap MapMode and MapModes - s/mmap_flags/mmapFlags/ - Remove and fix documentation regarding the modes - add LIBCAMERA_FLAGS_ENABLE_OPERATORS() v3: - Remove no longer necessary sys/mman.h inclusions throughout - fix documentation - rename MapMode as MapFlag and MapModes as MapFlags --- .../libcamera/internal/mapped_framebuffer.h | 15 ++++++-- src/android/jpeg/encoder_libjpeg.cpp | 3 +- src/android/jpeg/thumbnailer.cpp | 2 +- src/android/yuv/post_processor_yuv.cpp | 2 +- src/ipa/ipu3/ipu3.cpp | 3 +- src/ipa/raspberrypi/raspberrypi.cpp | 3 +- src/libcamera/framebuffer.cpp | 1 - src/libcamera/mapped_framebuffer.cpp | 34 ++++++++++++++++--- test/mapped-buffer.cpp | 6 ++-- 9 files changed, 51 insertions(+), 18 deletions(-) diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h index 41e587364260..68c8a43c35dc 100644 --- a/include/libcamera/internal/mapped_framebuffer.h +++ b/include/libcamera/internal/mapped_framebuffer.h @@ -7,10 +7,11 @@ #ifndef __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ #define __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ -#include +#include #include #include +#include #include #include @@ -44,9 +45,19 @@ private: class MappedFrameBuffer : public MappedBuffer { public: - MappedFrameBuffer(const FrameBuffer *buffer, int flags); + enum class MapFlag { + Read = 0 << 1, + Write = 1 << 1, + ReadWrite = Read | Write, + }; + + using MapFlags = Flags; + + MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags); }; +LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag) + } /* namespace libcamera */ #endif /* __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ */ diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp index 372018d2207f..a7a636011045 100644 --- a/src/android/jpeg/encoder_libjpeg.cpp +++ b/src/android/jpeg/encoder_libjpeg.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -182,7 +181,7 @@ void EncoderLibJpeg::compressNV(Span frame) int EncoderLibJpeg::encode(const FrameBuffer &source, Span dest, Span exifData, unsigned int quality) { - MappedFrameBuffer frame(&source, PROT_READ); + MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { LOG(JPEG, Error) << "Failed to map FrameBuffer : " << strerror(frame.error()); diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp index 535e2cece914..79d83926af5c 100644 --- a/src/android/jpeg/thumbnailer.cpp +++ b/src/android/jpeg/thumbnailer.cpp @@ -41,7 +41,7 @@ void Thumbnailer::createThumbnail(const FrameBuffer &source, const Size &targetSize, std::vector *destination) { - MappedFrameBuffer frame(&source, PROT_READ); + MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read); if (!frame.isValid()) { LOG(Thumbnailer, Error) << "Failed to map FrameBuffer : " diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp index 509d4244d614..3e793a580377 100644 --- a/src/android/yuv/post_processor_yuv.cpp +++ b/src/android/yuv/post_processor_yuv.cpp @@ -57,7 +57,7 @@ int PostProcessorYuv::process(const FrameBuffer &source, if (!isValidBuffers(source, *destination)) return -EINVAL; - const MappedFrameBuffer sourceMapped(&source, PROT_READ); + const MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read); if (!sourceMapped.isValid()) { LOG(YUV, Error) << "Failed to mmap camera frame buffer"; return -EINVAL; diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp index 2647bf2f3b96..10093acdad30 100644 --- a/src/ipa/ipu3/ipu3.cpp +++ b/src/ipa/ipu3/ipu3.cpp @@ -6,7 +6,6 @@ */ #include -#include #include #include @@ -211,7 +210,7 @@ void IPAIPU3::mapBuffers(const std::vector &buffers) for (const IPABuffer &buffer : buffers) { const FrameBuffer fb(buffer.planes); buffers_.emplace(buffer.id, - MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE)); + MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite)); } } diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 76f67dd4567a..592e2fe41617 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -411,7 +411,8 @@ void IPARPi::mapBuffers(const std::vector &buffers) { for (const IPABuffer &buffer : buffers) { const FrameBuffer fb(buffer.planes); - buffers_.emplace(buffer.id, MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE)); + buffers_.emplace(buffer.id, + MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite)); } } diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index 3d98affb20f9..2223e24321ca 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp index 0e30fc542154..5a70c18147f2 100644 --- a/src/libcamera/mapped_framebuffer.cpp +++ b/src/libcamera/mapped_framebuffer.cpp @@ -142,21 +142,45 @@ MappedBuffer::~MappedBuffer() * \brief Map a FrameBuffer using the MappedBuffer interface */ +/** + * \enum MappedFrameBuffer::MapFlag + * \brief Specify the mapping mode for the FrameBuffer + * \var MappedFrameBuffer::Read + * \brief Create a read-only mapping + * \var MappedFrameBuffer::Write + * \brief Create a write-only mapping + * \var MappedFrameBuffer::ReadWrite + * \brief Create a mapping that can be both read and written + */ + +/** + * \typedef MappedFrameBuffer::MapFlags + * \brief A bitwise combination of MappedFrameBuffer::MapFlag values + */ + /** * \brief Map all planes of a FrameBuffer * \param[in] buffer FrameBuffer 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. + * Construct an object to map a frame buffer for CPU access. The mapping can be + * made as Read only, Write only or support Read and Write operations by setting + * the MapFlag flags accordingly. */ -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags) +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags) { maps_.reserve(buffer->planes().size()); + int mmapFlags = 0; + + if (flags & MapFlag::Read) + mmapFlags |= PROT_READ; + + if (flags & MapFlag::Write) + mmapFlags |= PROT_WRITE; + for (const FrameBuffer::Plane &plane : buffer->planes()) { - void *address = mmap(nullptr, plane.length, flags, + void *address = mmap(nullptr, plane.length, mmapFlags, MAP_SHARED, plane.fd.fd(), 0); if (address == MAP_FAILED) { error_ = -errno; diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp index a3d1511b74ce..97571945cbca 100644 --- a/test/mapped-buffer.cpp +++ b/test/mapped-buffer.cpp @@ -71,7 +71,7 @@ protected: const std::unique_ptr &buffer = allocator_->buffers(stream_).front(); std::vector maps; - MappedFrameBuffer map(buffer.get(), PROT_READ); + MappedFrameBuffer map(buffer.get(), MappedFrameBuffer::MapFlag::Read); if (!map.isValid()) { cout << "Failed to successfully map buffer" << endl; return TestFail; @@ -90,13 +90,13 @@ protected: } /* Test for multiple successful maps on the same buffer. */ - MappedFrameBuffer write_map(buffer.get(), PROT_WRITE); + MappedFrameBuffer write_map(buffer.get(), MappedFrameBuffer::MapFlag::Write); if (!write_map.isValid()) { cout << "Failed to map write buffer" << endl; return TestFail; } - MappedFrameBuffer rw_map(buffer.get(), PROT_READ | PROT_WRITE); + MappedFrameBuffer rw_map(buffer.get(), MappedFrameBuffer::MapFlag::ReadWrite); if (!rw_map.isValid()) { cout << "Failed to map RW buffer" << endl; return TestFail;