[{"id":17604,"web_url":"https://patchwork.libcamera.org/comment/17604/","msgid":"<505e63c2-ab4f-e828-9291-7d8a36887a77@ideasonboard.com>","date":"2021-06-17T07:24:25","subject":"Re: [libcamera-devel] [PATCH 6/6] libcamera-helpers: Provide helper\n\tlibrary","submitter":{"id":86,"url":"https://patchwork.libcamera.org/api/people/86/","name":"Umang Jain","email":"umang.jain@ideasonboard.com"},"content":"Hi Kieran,\n\nI cannot compile this series with this patch, due to missing \nsrc/libcamera-helpers/meson.build\n\nsrc/meson.build:34:0: ERROR: Non-existent build file \n'src/libcamera-helpers/meson.build'\n\nOn 6/16/21 8:41 PM, Kieran Bingham wrote:\n> Provide a library which build support on top of the libcamera API.\n>\n> This currently implements the MappedBuffer and MappedFrameBuffer classes\n> which help with lifetime management of mmapping libcamera buffers.\n>\n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>   Documentation/Doxyfile.in                     |   2 +\n>   .../buffer.h => helpers/mapped_buffer.h}      |  10 +-\n>   include/libcamera/helpers/meson.build         |  10 +\n>   include/libcamera/internal/meson.build        |   1 -\n>   include/libcamera/meson.build                 |   1 +\n>   src/android/camera_device.h                   |   2 +-\n>   src/android/camera_stream.h                   |   2 +-\n>   src/android/jpeg/encoder_libjpeg.h            |   3 +-\n>   src/android/jpeg/post_processor_jpeg.h        |   2 +-\n>   src/android/jpeg/thumbnailer.h                |   3 +-\n>   src/android/meson.build                       |   1 +\n>   src/android/mm/generic_camera_buffer.cpp      |   2 +-\n>   src/android/post_processor.h                  |   2 +-\n>   src/ipa/ipu3/ipu3.cpp                         |   2 +-\n>   src/ipa/ipu3/meson.build                      |   2 +-\n>   src/ipa/raspberrypi/meson.build               |   1 +\n>   src/ipa/raspberrypi/raspberrypi.cpp           |   2 +-\n>   src/libcamera-helpers/mapped_buffer.cpp       | 171 ++++++++++++++++++\n>   src/libcamera/buffer.cpp                      | 149 ---------------\n>   .../pipeline/raspberrypi/raspberrypi.cpp      |   3 +-\n>   src/meson.build                               |   1 +\n>   test/mapped-buffer.cpp                        |   3 +-\n>   test/meson.build                              |  14 +-\n>   23 files changed, 220 insertions(+), 169 deletions(-)\n>   rename include/libcamera/{internal/buffer.h => helpers/mapped_buffer.h} (81%)\n>   create mode 100644 include/libcamera/helpers/meson.build\n>   create mode 100644 src/libcamera-helpers/mapped_buffer.cpp\n> diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in\n> index c1b395bf0b83..e67775b99d26 100644\n> --- a/Documentation/Doxyfile.in\n> +++ b/Documentation/Doxyfile.in\n> @@ -791,9 +791,11 @@ WARN_LOGFILE           =\n>   INPUT                  = \"@TOP_SRCDIR@/include/libcamera\" \\\n>   \t\t\t \"@TOP_SRCDIR@/src/ipa/libipa\" \\\n>   \t\t\t \"@TOP_SRCDIR@/src/libcamera\" \\\n> +\t\t\t \"@TOP_SRCDIR@/src/libcamera-helpers\" \\\n>   \t\t\t \"@TOP_SRCDIR@/src/libcamera-platform\" \\\n>   \t\t\t \"@TOP_BUILDDIR@/include/libcamera\" \\\n>   \t\t\t \"@TOP_BUILDDIR@/src/libcamera\" \\\n> +\t\t\t \"@TOP_BUILDDIR@/src/libcamera-helpers\" \\\n>   \t\t\t \"@TOP_BUILDDIR@/src/libcamera-platform\"\n>   \n>   # This tag can be used to specify the character encoding of the source files\n> diff --git a/include/libcamera/internal/buffer.h b/include/libcamera/helpers/mapped_buffer.h\n> similarity index 81%\n> rename from include/libcamera/internal/buffer.h\n> rename to include/libcamera/helpers/mapped_buffer.h\n> index 9da1fbd12c27..ece24f2ddd2c 100644\n> --- a/include/libcamera/internal/buffer.h\n> +++ b/include/libcamera/helpers/mapped_buffer.h\n> @@ -2,16 +2,16 @@\n>   /*\n>    * Copyright (C) 2020, Google Inc.\n>    *\n> - * buffer.h - Internal buffer handling\n> + * mapped_buffer.h - Mapped Buffer handling\n>    */\n> -#ifndef __LIBCAMERA_INTERNAL_BUFFER_H__\n> -#define __LIBCAMERA_INTERNAL_BUFFER_H__\n> +#ifndef __LIBCAMERA_HELPERS_MAPPED_BUFFER_H__\n> +#define __LIBCAMERA_HELPERS_MAPPED_BUFFER_H__\n>   \n>   #include <sys/mman.h>\n>   #include <vector>\n>   \n> -#include <libcamera/class.h>\n>   #include <libcamera/buffer.h>\n> +#include <libcamera/class.h>\n>   #include <libcamera/span.h>\n>   \n>   namespace libcamera {\n> @@ -48,4 +48,4 @@ public:\n>   \n>   } /* namespace libcamera */\n>   \n> -#endif /* __LIBCAMERA_INTERNAL_BUFFER_H__ */\n> +#endif /* __LIBCAMERA_HELPERS_MAPPED_BUFFER_H__ */\n> diff --git a/include/libcamera/helpers/meson.build b/include/libcamera/helpers/meson.build\n> new file mode 100644\n> index 000000000000..c025eb930600\n> --- /dev/null\n> +++ b/include/libcamera/helpers/meson.build\n> @@ -0,0 +1,10 @@\n> +# SPDX-License-Identifier: CC0-1.0\n> +\n> +libcamera_helpers_include_dir = libcamera_include_dir / 'helpers'\n> +\n> +libcamera_helpers_headers = files([\n> +    'mapped_buffer.h',\n> +])\n> +\n> +install_headers(libcamera_helpers_headers,\n> +                subdir: libcamera_helpers_include_dir)\n> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build\n> index 1187cc1f63e4..ecd0c8ba183e 100644\n> --- a/include/libcamera/internal/meson.build\n> +++ b/include/libcamera/internal/meson.build\n> @@ -11,7 +11,6 @@ libcamera_tracepoint_header = custom_target(\n>   \n>   libcamera_internal_headers = files([\n>       'bayer_format.h',\n> -    'buffer.h',\n>       'byte_stream_buffer.h',\n>       'camera_controls.h',\n>       'camera_sensor.h',\n> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> index 7bfcebc79c86..7c98d8744ec2 100644\n> --- a/include/libcamera/meson.build\n> +++ b/include/libcamera/meson.build\n> @@ -20,6 +20,7 @@ libcamera_public_headers = files([\n>   \n>   include_dir = libcamera_include_dir / 'libcamera'\n>   \n> +subdir('helpers')\n>   subdir('internal')\n>   subdir('ipa')\n>   subdir('platform')\n> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> index b9be3df58084..26e5bbc0c26c 100644\n> --- a/src/android/camera_device.h\n> +++ b/src/android/camera_device.h\n> @@ -25,7 +25,7 @@\n>   #include <libcamera/platform/message.h>\n>   #include <libcamera/platform/thread.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   #include \"camera_metadata.h\"\n>   #include \"camera_stream.h\"\n> diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h\n> index 3401672233ca..12484cb607ed 100644\n> --- a/src/android/camera_stream.h\n> +++ b/src/android/camera_stream.h\n> @@ -19,7 +19,7 @@\n>   #include <libcamera/geometry.h>\n>   #include <libcamera/pixel_format.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   class CameraDevice;\n>   class CameraMetadata;\n> diff --git a/src/android/jpeg/encoder_libjpeg.h b/src/android/jpeg/encoder_libjpeg.h\n> index 838da7728382..ca7c1958e20e 100644\n> --- a/src/android/jpeg/encoder_libjpeg.h\n> +++ b/src/android/jpeg/encoder_libjpeg.h\n> @@ -9,7 +9,8 @@\n>   \n>   #include \"encoder.h\"\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n> +\n>   #include \"libcamera/internal/formats.h\"\n>   \n>   #include <jpeglib.h>\n> diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h\n> index 5d2d4ab224b1..4700a7f562a2 100644\n> --- a/src/android/jpeg/post_processor_jpeg.h\n> +++ b/src/android/jpeg/post_processor_jpeg.h\n> @@ -13,7 +13,7 @@\n>   \n>   #include <libcamera/geometry.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   class CameraDevice;\n>   \n> diff --git a/src/android/jpeg/thumbnailer.h b/src/android/jpeg/thumbnailer.h\n> index 4e9226c34104..483b41dfe47d 100644\n> --- a/src/android/jpeg/thumbnailer.h\n> +++ b/src/android/jpeg/thumbnailer.h\n> @@ -9,7 +9,8 @@\n>   \n>   #include <libcamera/geometry.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n> +\n>   #include \"libcamera/internal/formats.h\"\n>   \n>   class Thumbnailer\n> diff --git a/src/android/meson.build b/src/android/meson.build\n> index 6edaa1185905..abde9fd2def0 100644\n> --- a/src/android/meson.build\n> +++ b/src/android/meson.build\n> @@ -5,6 +5,7 @@ android_deps = [\n>       dependency('libjpeg', required : get_option('android')),\n>       dependency('yaml-0.1', required : get_option('android')),\n>       libcamera_dep,\n> +    libcamera_helpers,\n>   ]\n>   \n>   android_enabled = true\n> diff --git a/src/android/mm/generic_camera_buffer.cpp b/src/android/mm/generic_camera_buffer.cpp\n> index f138ada14964..64c73c5716ad 100644\n> --- a/src/android/mm/generic_camera_buffer.cpp\n> +++ b/src/android/mm/generic_camera_buffer.cpp\n> @@ -11,7 +11,7 @@\n>   \n>   #include <libcamera/platform/log.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   using namespace libcamera;\n>   \n> diff --git a/src/android/post_processor.h b/src/android/post_processor.h\n> index 547fda379ed8..53220edaf24d 100644\n> --- a/src/android/post_processor.h\n> +++ b/src/android/post_processor.h\n> @@ -10,7 +10,7 @@\n>   #include <libcamera/buffer.h>\n>   #include <libcamera/stream.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   #include \"camera_buffer.h\"\n>   \n> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n> index ca1ce4dc96d0..158eb3bc49e5 100644\n> --- a/src/ipa/ipu3/ipu3.cpp\n> +++ b/src/ipa/ipu3/ipu3.cpp\n> @@ -20,7 +20,7 @@\n>   \n>   #include <libcamera/platform/log.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   #include \"ipu3_agc.h\"\n>   #include \"ipu3_awb.h\"\n> diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build\n> index 0d843846acde..34620024def7 100644\n> --- a/src/ipa/ipu3/meson.build\n> +++ b/src/ipa/ipu3/meson.build\n> @@ -12,7 +12,7 @@ mod = shared_module(ipa_name,\n>                       [ipu3_ipa_sources, libcamera_generated_ipa_headers],\n>                       name_prefix : '',\n>                       include_directories : [ipa_includes, libipa_includes],\n> -                    dependencies : libcamera_dep,\n> +                    dependencies : [libcamera_dep, libcamera_helpers],\n>                       link_with : libipa,\n>                       install : true,\n>                       install_dir : ipa_install_dir)\n> diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build\n> index 230356d3ce3a..b2ce6f3e8618 100644\n> --- a/src/ipa/raspberrypi/meson.build\n> +++ b/src/ipa/raspberrypi/meson.build\n> @@ -4,6 +4,7 @@ ipa_name = 'ipa_rpi'\n>   \n>   rpi_ipa_deps = [\n>       libcamera_dep,\n> +    libcamera_helpers,\n>       dependency('boost'),\n>       libatomic,\n>   ]\n> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\n> index 90f35d970fd0..b85a1e51d757 100644\n> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n> @@ -26,7 +26,7 @@\n>   \n>   #include <libcamera/platform/log.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   #include <linux/bcm2835-isp.h>\n>   \n> diff --git a/src/libcamera-helpers/mapped_buffer.cpp b/src/libcamera-helpers/mapped_buffer.cpp\n> new file mode 100644\n> index 000000000000..0d4517b62f65\n> --- /dev/null\n> +++ b/src/libcamera-helpers/mapped_buffer.cpp\n> @@ -0,0 +1,171 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Google Inc.\n> + *\n> + * mapped_buffer.cpp - Mapped Buffer handling\n> + */\n> +\n> +#include <libcamera/helpers/mapped_buffer.h>\n> +\n> +#include <errno.h>\n> +#include <string.h>\n> +#include <sys/mman.h>\n> +#include <unistd.h>\n> +\n> +#include <libcamera/platform/log.h>\n> +\n> +/**\n> + * \\file libcamera/helpers/mapped_buffer.h\n> + * \\brief Mapped Buffer handling\n> + */\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(MappedBuffer)\n> +\n> +/**\n> + * \\class MappedBuffer\n> + * \\brief Provide an interface to support managing memory mapped buffers\n> + *\n> + * The MappedBuffer interface provides access to a set of MappedPlanes which\n> + * are available for access by the CPU.\n> + *\n> + * This class is not meant to be constructed directly, but instead derived\n> + * classes should be used to implement the correct mapping of a source buffer.\n> + *\n> + * This allows treating CPU accessible memory through a generic interface\n> + * regardless of whether it originates from a libcamera FrameBuffer or other\n> + * source.\n> + */\n> +\n> +/**\n> + * \\typedef MappedBuffer::Plane\n> + * \\brief A mapped region of memory accessible to the CPU\n> + *\n> + * The MappedBuffer::Plane uses the Span interface to describe the mapped memory\n> + * region.\n> + */\n> +\n> +/**\n> + * \\brief Construct an empty MappedBuffer\n> + */\n> +MappedBuffer::MappedBuffer()\n> +\t: error_(0)\n> +{\n> +}\n> +\n> +/**\n> + * \\brief Move constructor, construct the MappedBuffer with the contents of \\a\n> + * other using move semantics\n> + * \\param[in] other The other MappedBuffer\n> + *\n> + * Moving a MappedBuffer moves the mappings contained in the \\a other to the new\n> + * MappedBuffer and invalidates the \\a other.\n> + *\n> + * No mappings are unmapped or destroyed in this process.\n> + */\n> +MappedBuffer::MappedBuffer(MappedBuffer &&other)\n> +{\n> +\t*this = std::move(other);\n> +}\n> +\n> +/**\n> + * \\brief Move assignment operator, replace the mappings with those of \\a other\n> +* \\param[in] other The other MappedBuffer\n> + *\n> + * Moving a MappedBuffer moves the mappings contained in the \\a other to the new\n> + * MappedBuffer and invalidates the \\a other.\n> + *\n> + * No mappings are unmapped or destroyed in this process.\n> + */\n> +MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other)\n> +{\n> +\terror_ = other.error_;\n> +\tmaps_ = std::move(other.maps_);\n> +\tother.error_ = -ENOENT;\n> +\n> +\treturn *this;\n> +}\n> +\n> +MappedBuffer::~MappedBuffer()\n> +{\n> +\tfor (Plane &map : maps_)\n> +\t\tmunmap(map.data(), map.size());\n> +}\n> +\n> +/**\n> + * \\fn MappedBuffer::isValid()\n> + * \\brief Check if the MappedBuffer instance is valid\n> + * \\return True if the MappedBuffer has valid mappings, false otherwise\n> + */\n> +\n> +/**\n> + * \\fn MappedBuffer::error()\n> + * \\brief Retrieve the map error status\n> + *\n> + * This function retrieves the error status from the MappedBuffer.\n> + * The error status is a negative number as defined by errno.h. If\n> + * no error occurred, this function returns 0.\n> + *\n> + * \\return The map error code\n> + */\n> +\n> +/**\n> + * \\fn MappedBuffer::maps()\n> + * \\brief Retrieve the mapped planes\n> + *\n> + * This function retrieves the successfully mapped planes stored as a vector\n> + * of Span<uint8_t> to provide access to the mapped memory.\n> + *\n> + * \\return A vector of the mapped planes\n> + */\n> +\n> +/**\n> + * \\var MappedBuffer::error_\n> + * \\brief Stores the error value if present\n> + *\n> + * MappedBuffer derived classes shall set this to a negative value as defined\n> + * by errno.h if an error occured during the mapping process.\n> + */\n> +\n> +/**\n> + * \\var MappedBuffer::maps_\n> + * \\brief Stores the internal mapped planes\n> + *\n> + * MappedBuffer derived classes shall store the mappings they create in this\n> + * vector which is parsed during destruct to unmap any memory mappings which\n> + * completed successfully.\n> + */\n> +\n> +/**\n> + * \\class MappedFrameBuffer\n> + * \\brief Map a FrameBuffer using the MappedBuffer interface\n> + */\n> +\n> +/**\n> + * \\brief Map all planes of a FrameBuffer\n> + * \\param[in] buffer FrameBuffer to be mapped\n> + * \\param[in] flags Protection flags to apply to map\n> + *\n> + * Construct an object to map a frame buffer for CPU access.\n> + * The flags are passed directly to mmap and should be either PROT_READ,\n> + * PROT_WRITE, or a bitwise-or combination of both.\n> + */\n> +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)\n> +{\n> +\tmaps_.reserve(buffer->planes().size());\n> +\n> +\tfor (const FrameBuffer::Plane &plane : buffer->planes()) {\n> +\t\tvoid *address = mmap(nullptr, plane.length, flags,\n> +\t\t\t\t     MAP_SHARED, plane.fd.fd(), 0);\n> +\t\tif (address == MAP_FAILED) {\n> +\t\t\terror_ = -errno;\n> +\t\t\tLOG(MappedBuffer, Error) << \"Failed to mmap plane\";\n> +\t\t\tbreak;\n> +\t\t}\n> +\n> +\t\tmaps_.emplace_back(static_cast<uint8_t *>(address), plane.length);\n> +\t}\n> +}\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp\n> index 3c862820e6e1..0a232d791fcd 100644\n> --- a/src/libcamera/buffer.cpp\n> +++ b/src/libcamera/buffer.cpp\n> @@ -6,7 +6,6 @@\n>    */\n>   \n>   #include <libcamera/buffer.h>\n> -#include \"libcamera/internal/buffer.h\"\n>   \n>   #include <errno.h>\n>   #include <string.h>\n> @@ -18,9 +17,6 @@\n>   /**\n>    * \\file libcamera/buffer.h\n>    * \\brief Buffer handling\n> - *\n> - * \\file libcamera/internal/buffer.h\n> - * \\brief Internal buffer handling support\n>    */\n>   \n>   namespace libcamera {\n> @@ -235,149 +231,4 @@ FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie)\n>    * indicate that the metadata is invalid.\n>    */\n>   \n> -/**\n> - * \\class MappedBuffer\n> - * \\brief Provide an interface to support managing memory mapped buffers\n> - *\n> - * The MappedBuffer interface provides access to a set of MappedPlanes which\n> - * are available for access by the CPU.\n> - *\n> - * This class is not meant to be constructed directly, but instead derived\n> - * classes should be used to implement the correct mapping of a source buffer.\n> - *\n> - * This allows treating CPU accessible memory through a generic interface\n> - * regardless of whether it originates from a libcamera FrameBuffer or other\n> - * source.\n> - */\n> -\n> -/**\n> - * \\typedef MappedBuffer::Plane\n> - * \\brief A mapped region of memory accessible to the CPU\n> - *\n> - * The MappedBuffer::Plane uses the Span interface to describe the mapped memory\n> - * region.\n> - */\n> -\n> -/**\n> - * \\brief Construct an empty MappedBuffer\n> - */\n> -MappedBuffer::MappedBuffer()\n> -\t: error_(0)\n> -{\n> -}\n> -\n> -/**\n> - * \\brief Move constructor, construct the MappedBuffer with the contents of \\a\n> - * other using move semantics\n> - * \\param[in] other The other MappedBuffer\n> - *\n> - * Moving a MappedBuffer moves the mappings contained in the \\a other to the new\n> - * MappedBuffer and invalidates the \\a other.\n> - *\n> - * No mappings are unmapped or destroyed in this process.\n> - */\n> -MappedBuffer::MappedBuffer(MappedBuffer &&other)\n> -{\n> -\t*this = std::move(other);\n> -}\n> -\n> -/**\n> - * \\brief Move assignment operator, replace the mappings with those of \\a other\n> -* \\param[in] other The other MappedBuffer\n> - *\n> - * Moving a MappedBuffer moves the mappings contained in the \\a other to the new\n> - * MappedBuffer and invalidates the \\a other.\n> - *\n> - * No mappings are unmapped or destroyed in this process.\n> - */\n> -MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other)\n> -{\n> -\terror_ = other.error_;\n> -\tmaps_ = std::move(other.maps_);\n> -\tother.error_ = -ENOENT;\n> -\n> -\treturn *this;\n> -}\n> -\n> -MappedBuffer::~MappedBuffer()\n> -{\n> -\tfor (Plane &map : maps_)\n> -\t\tmunmap(map.data(), map.size());\n> -}\n> -\n> -/**\n> - * \\fn MappedBuffer::isValid()\n> - * \\brief Check if the MappedBuffer instance is valid\n> - * \\return True if the MappedBuffer has valid mappings, false otherwise\n> - */\n> -\n> -/**\n> - * \\fn MappedBuffer::error()\n> - * \\brief Retrieve the map error status\n> - *\n> - * This function retrieves the error status from the MappedBuffer.\n> - * The error status is a negative number as defined by errno.h. If\n> - * no error occurred, this function returns 0.\n> - *\n> - * \\return The map error code\n> - */\n> -\n> -/**\n> - * \\fn MappedBuffer::maps()\n> - * \\brief Retrieve the mapped planes\n> - *\n> - * This function retrieves the successfully mapped planes stored as a vector\n> - * of Span<uint8_t> to provide access to the mapped memory.\n> - *\n> - * \\return A vector of the mapped planes\n> - */\n> -\n> -/**\n> - * \\var MappedBuffer::error_\n> - * \\brief Stores the error value if present\n> - *\n> - * MappedBuffer derived classes shall set this to a negative value as defined\n> - * by errno.h if an error occured during the mapping process.\n> - */\n> -\n> -/**\n> - * \\var MappedBuffer::maps_\n> - * \\brief Stores the internal mapped planes\n> - *\n> - * MappedBuffer derived classes shall store the mappings they create in this\n> - * vector which is parsed during destruct to unmap any memory mappings which\n> - * completed successfully.\n> - */\n> -\n> -/**\n> - * \\class MappedFrameBuffer\n> - * \\brief Map a FrameBuffer using the MappedBuffer interface\n> - */\n> -\n> -/**\n> - * \\brief Map all planes of a FrameBuffer\n> - * \\param[in] buffer FrameBuffer to be mapped\n> - * \\param[in] flags Protection flags to apply to map\n> - *\n> - * Construct an object to map a frame buffer for CPU access.\n> - * The flags are passed directly to mmap and should be either PROT_READ,\n> - * PROT_WRITE, or a bitwise-or combination of both.\n> - */\n> -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)\n> -{\n> -\tmaps_.reserve(buffer->planes().size());\n> -\n> -\tfor (const FrameBuffer::Plane &plane : buffer->planes()) {\n> -\t\tvoid *address = mmap(nullptr, plane.length, flags,\n> -\t\t\t\t     MAP_SHARED, plane.fd.fd(), 0);\n> -\t\tif (address == MAP_FAILED) {\n> -\t\t\terror_ = -errno;\n> -\t\t\tLOG(Buffer, Error) << \"Failed to mmap plane\";\n> -\t\t\tbreak;\n> -\t\t}\n> -\n> -\t\tmaps_.emplace_back(static_cast<uint8_t *>(address), plane.length);\n> -\t}\n> -}\n> -\n>   } /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> index dc3fe63112d4..e6849733f979 100644\n> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> @@ -29,8 +29,9 @@\n>   #include <linux/bcm2835-isp.h>\n>   #include <linux/videodev2.h>\n>   \n> +#include <libcamera/helpers/mapped_buffer.h>\n> +\n>   #include \"libcamera/internal/bayer_format.h\"\n> -#include \"libcamera/internal/buffer.h\"\n>   #include \"libcamera/internal/camera_sensor.h\"\n>   #include \"libcamera/internal/delayed_controls.h\"\n>   #include \"libcamera/internal/device_enumerator.h\"\n> diff --git a/src/meson.build b/src/meson.build\n> index 70e1a4618a0f..380de28d0f7a 100644\n> --- a/src/meson.build\n> +++ b/src/meson.build\n> @@ -31,6 +31,7 @@ libcamera_objects = []\n>   # libcamera must be built first as a dependency to the other components.\n>   subdir('libcamera-platform')\n>   subdir('libcamera')\n> +subdir('libcamera-helpers')\n>   \n>   subdir('android')\n>   subdir('ipa')\n> diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp\n> index 5de8201e45f6..218d700f40da 100644\n> --- a/test/mapped-buffer.cpp\n> +++ b/test/mapped-buffer.cpp\n> @@ -4,12 +4,11 @@\n>    *\n>    * libcamera internal MappedBuffer tests\n>    */\n> -\n>   #include <iostream>\n>   \n>   #include <libcamera/framebuffer_allocator.h>\n>   \n> -#include \"libcamera/internal/buffer.h\"\n> +#include <libcamera/helpers/mapped_buffer.h>\n>   \n>   #include \"camera_test.h\"\n>   #include \"test.h\"\n> diff --git a/test/meson.build b/test/meson.build\n> index 045ad2a2d7c9..ee0d127cf1ec 100644\n> --- a/test/meson.build\n> +++ b/test/meson.build\n> @@ -40,7 +40,6 @@ internal_tests = [\n>       ['file',                            'file.cpp'],\n>       ['file-descriptor',                 'file-descriptor.cpp'],\n>       ['hotplug-cameras',                 'hotplug-cameras.cpp'],\n> -    ['mapped-buffer',                   'mapped-buffer.cpp'],\n>       ['message',                         'message.cpp'],\n>       ['object',                          'object.cpp'],\n>       ['object-delete',                   'object-delete.cpp'],\n> @@ -53,6 +52,10 @@ internal_tests = [\n>       ['utils',                           'utils.cpp'],\n>   ]\n>   \n> +helpers_tests = [\n> +    ['mapped-buffer',                   'mapped-buffer.cpp'],\n> +]\n> +\n>   foreach t : public_tests\n>       exe = executable(t[0], t[1],\n>                        dependencies : libcamera_dep,\n> @@ -70,3 +73,12 @@ foreach t : internal_tests\n>   \n>       test(t[0], exe)\n>   endforeach\n> +\n> +foreach t : helpers_tests\n> +    exe = executable(t[0], t[1],\n> +                     dependencies : [libcamera_dep, libcamera_helpers],\n> +                     link_with : test_libraries,\n> +                     include_directories : test_includes_internal)\n> +\n> +    test(t[0], exe)\n> +endforeach","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id F3C03C3218\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 17 Jun 2021 07:24:31 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B173C68946;\n\tThu, 17 Jun 2021 09:24:31 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8A14A60298\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 17 Jun 2021 09:24:30 +0200 (CEST)","from [192.168.0.107] (unknown [103.238.109.26])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D8E8E53;\n\tThu, 17 Jun 2021 09:24:29 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"QCiYrpXp\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1623914670;\n\tbh=R7tpBXWKSLOpZavvCv8UMz8/1CN/9v+zrAptnThtH6k=;\n\th=Subject:To:References:From:Date:In-Reply-To:From;\n\tb=QCiYrpXpaotkk1wee1Rz6UttR5Ryj45/glvfk8zrogPITSpTnVgUVeZonMpX5ejFC\n\ttcyAGoTbXCgAxfzDmp9jdrou0+/p1ni+qPMQND89qulu+s7RZ6Rzfjpm4xmMakorsI\n\tTfHvh40vBYgPQZqFs9ULUjdm2QirGDRhRbeOHmOw=","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","References":"<20210616151152.3856595-1-kieran.bingham@ideasonboard.com>\n\t<20210616151152.3856595-7-kieran.bingham@ideasonboard.com>","From":"Umang Jain <umang.jain@ideasonboard.com>","Message-ID":"<505e63c2-ab4f-e828-9291-7d8a36887a77@ideasonboard.com>","Date":"Thu, 17 Jun 2021 12:54:25 +0530","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.10.2","MIME-Version":"1.0","In-Reply-To":"<20210616151152.3856595-7-kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8; format=flowed","Content-Transfer-Encoding":"7bit","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH 6/6] libcamera-helpers: Provide helper\n\tlibrary","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":17605,"web_url":"https://patchwork.libcamera.org/comment/17605/","msgid":"<ca869c15-d289-abaf-ff83-1b06b02c9601@ideasonboard.com>","date":"2021-06-17T07:30:40","subject":"Re: [libcamera-devel] [PATCH 6/6] libcamera-helpers: Provide helper\n\tlibrary","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Umang,\n\nOh dear - I'm sorry I slipped on this.\n\nHere is the diff which introduces the meson.build\n\n\ndiff --git a/src/libcamera-helpers/meson.build\nb/src/libcamera-helpers/meson.build\nnew file mode 100644\nindex 000000000000..53e6d91554f7\n--- /dev/null\n+++ b/src/libcamera-helpers/meson.build\n@@ -0,0 +1,29 @@\n+# SPDX-License-Identifier: CC0-1.0\n+\n+libcamera_helpers_sources = files([\n+    'mapped_buffer.cpp',\n+])\n+\n+libcamera_helpers_deps = [\n+    libcamera_dep,\n+]\n+\n+libcamera_helpers_lib = shared_library('libcamera-helpers',\n+                                       [libcamera_helpers_sources,\nlibcamera_helpers_headers],\n+                                       name_prefix : '',\n+                                       install : true,\n+                                       cpp_args : libcamera_cpp_args,\n+                                       include_directories :\nlibcamera_includes,\n+                                       dependencies :\nlibcamera_helpers_deps)\n+\n+libcamera_helpers = declare_dependency(sources: libcamera_helpers_headers,\n+                                       include_directories :\nlibcamera_includes,\n+                                       link_with : libcamera_helpers_lib)\n+\n+pkg_mod = import('pkgconfig')\n+pkg_mod.generate(libraries : libcamera_helpers_lib,\n+                 version : '1.0',\n+                 name : 'libcamera-helpers',\n+                 filebase : 'camera-helpers',\n+                 description : 'Complex Camera Support Library helpers',\n+                 subdirs : 'libcamera')\n\n\nwhich will of course be in any v2 ;-)\n\n--\nKieran\n\n\n\nOn 17/06/2021 08:24, Umang Jain wrote:\n> Hi Kieran,\n> \n> I cannot compile this series with this patch, due to missing\n> src/libcamera-helpers/meson.build\n> \n> src/meson.build:34:0: ERROR: Non-existent build file\n> 'src/libcamera-helpers/meson.build'\n> \n> On 6/16/21 8:41 PM, Kieran Bingham wrote:\n>> Provide a library which build support on top of the libcamera API.\n>>\n>> This currently implements the MappedBuffer and MappedFrameBuffer classes\n>> which help with lifetime management of mmapping libcamera buffers.\n>>\n>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>> ---\n>>   Documentation/Doxyfile.in                     |   2 +\n>>   .../buffer.h => helpers/mapped_buffer.h}      |  10 +-\n>>   include/libcamera/helpers/meson.build         |  10 +\n>>   include/libcamera/internal/meson.build        |   1 -\n>>   include/libcamera/meson.build                 |   1 +\n>>   src/android/camera_device.h                   |   2 +-\n>>   src/android/camera_stream.h                   |   2 +-\n>>   src/android/jpeg/encoder_libjpeg.h            |   3 +-\n>>   src/android/jpeg/post_processor_jpeg.h        |   2 +-\n>>   src/android/jpeg/thumbnailer.h                |   3 +-\n>>   src/android/meson.build                       |   1 +\n>>   src/android/mm/generic_camera_buffer.cpp      |   2 +-\n>>   src/android/post_processor.h                  |   2 +-\n>>   src/ipa/ipu3/ipu3.cpp                         |   2 +-\n>>   src/ipa/ipu3/meson.build                      |   2 +-\n>>   src/ipa/raspberrypi/meson.build               |   1 +\n>>   src/ipa/raspberrypi/raspberrypi.cpp           |   2 +-\n>>   src/libcamera-helpers/mapped_buffer.cpp       | 171 ++++++++++++++++++\n>>   src/libcamera/buffer.cpp                      | 149 ---------------\n>>   .../pipeline/raspberrypi/raspberrypi.cpp      |   3 +-\n>>   src/meson.build                               |   1 +\n>>   test/mapped-buffer.cpp                        |   3 +-\n>>   test/meson.build                              |  14 +-\n>>   23 files changed, 220 insertions(+), 169 deletions(-)\n>>   rename include/libcamera/{internal/buffer.h =>\n>> helpers/mapped_buffer.h} (81%)\n>>   create mode 100644 include/libcamera/helpers/meson.build\n>>   create mode 100644 src/libcamera-helpers/mapped_buffer.cpp\n>> diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in\n>> index c1b395bf0b83..e67775b99d26 100644\n>> --- a/Documentation/Doxyfile.in\n>> +++ b/Documentation/Doxyfile.in\n>> @@ -791,9 +791,11 @@ WARN_LOGFILE           =\n>>   INPUT                  = \"@TOP_SRCDIR@/include/libcamera\" \\\n>>                \"@TOP_SRCDIR@/src/ipa/libipa\" \\\n>>                \"@TOP_SRCDIR@/src/libcamera\" \\\n>> +             \"@TOP_SRCDIR@/src/libcamera-helpers\" \\\n>>                \"@TOP_SRCDIR@/src/libcamera-platform\" \\\n>>                \"@TOP_BUILDDIR@/include/libcamera\" \\\n>>                \"@TOP_BUILDDIR@/src/libcamera\" \\\n>> +             \"@TOP_BUILDDIR@/src/libcamera-helpers\" \\\n>>                \"@TOP_BUILDDIR@/src/libcamera-platform\"\n>>     # This tag can be used to specify the character encoding of the\n>> source files\n>> diff --git a/include/libcamera/internal/buffer.h\n>> b/include/libcamera/helpers/mapped_buffer.h\n>> similarity index 81%\n>> rename from include/libcamera/internal/buffer.h\n>> rename to include/libcamera/helpers/mapped_buffer.h\n>> index 9da1fbd12c27..ece24f2ddd2c 100644\n>> --- a/include/libcamera/internal/buffer.h\n>> +++ b/include/libcamera/helpers/mapped_buffer.h\n>> @@ -2,16 +2,16 @@\n>>   /*\n>>    * Copyright (C) 2020, Google Inc.\n>>    *\n>> - * buffer.h - Internal buffer handling\n>> + * mapped_buffer.h - Mapped Buffer handling\n>>    */\n>> -#ifndef __LIBCAMERA_INTERNAL_BUFFER_H__\n>> -#define __LIBCAMERA_INTERNAL_BUFFER_H__\n>> +#ifndef __LIBCAMERA_HELPERS_MAPPED_BUFFER_H__\n>> +#define __LIBCAMERA_HELPERS_MAPPED_BUFFER_H__\n>>     #include <sys/mman.h>\n>>   #include <vector>\n>>   -#include <libcamera/class.h>\n>>   #include <libcamera/buffer.h>\n>> +#include <libcamera/class.h>\n>>   #include <libcamera/span.h>\n>>     namespace libcamera {\n>> @@ -48,4 +48,4 @@ public:\n>>     } /* namespace libcamera */\n>>   -#endif /* __LIBCAMERA_INTERNAL_BUFFER_H__ */\n>> +#endif /* __LIBCAMERA_HELPERS_MAPPED_BUFFER_H__ */\n>> diff --git a/include/libcamera/helpers/meson.build\n>> b/include/libcamera/helpers/meson.build\n>> new file mode 100644\n>> index 000000000000..c025eb930600\n>> --- /dev/null\n>> +++ b/include/libcamera/helpers/meson.build\n>> @@ -0,0 +1,10 @@\n>> +# SPDX-License-Identifier: CC0-1.0\n>> +\n>> +libcamera_helpers_include_dir = libcamera_include_dir / 'helpers'\n>> +\n>> +libcamera_helpers_headers = files([\n>> +    'mapped_buffer.h',\n>> +])\n>> +\n>> +install_headers(libcamera_helpers_headers,\n>> +                subdir: libcamera_helpers_include_dir)\n>> diff --git a/include/libcamera/internal/meson.build\n>> b/include/libcamera/internal/meson.build\n>> index 1187cc1f63e4..ecd0c8ba183e 100644\n>> --- a/include/libcamera/internal/meson.build\n>> +++ b/include/libcamera/internal/meson.build\n>> @@ -11,7 +11,6 @@ libcamera_tracepoint_header = custom_target(\n>>     libcamera_internal_headers = files([\n>>       'bayer_format.h',\n>> -    'buffer.h',\n>>       'byte_stream_buffer.h',\n>>       'camera_controls.h',\n>>       'camera_sensor.h',\n>> diff --git a/include/libcamera/meson.build\n>> b/include/libcamera/meson.build\n>> index 7bfcebc79c86..7c98d8744ec2 100644\n>> --- a/include/libcamera/meson.build\n>> +++ b/include/libcamera/meson.build\n>> @@ -20,6 +20,7 @@ libcamera_public_headers = files([\n>>     include_dir = libcamera_include_dir / 'libcamera'\n>>   +subdir('helpers')\n>>   subdir('internal')\n>>   subdir('ipa')\n>>   subdir('platform')\n>> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n>> index b9be3df58084..26e5bbc0c26c 100644\n>> --- a/src/android/camera_device.h\n>> +++ b/src/android/camera_device.h\n>> @@ -25,7 +25,7 @@\n>>   #include <libcamera/platform/message.h>\n>>   #include <libcamera/platform/thread.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     #include \"camera_metadata.h\"\n>>   #include \"camera_stream.h\"\n>> diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h\n>> index 3401672233ca..12484cb607ed 100644\n>> --- a/src/android/camera_stream.h\n>> +++ b/src/android/camera_stream.h\n>> @@ -19,7 +19,7 @@\n>>   #include <libcamera/geometry.h>\n>>   #include <libcamera/pixel_format.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     class CameraDevice;\n>>   class CameraMetadata;\n>> diff --git a/src/android/jpeg/encoder_libjpeg.h\n>> b/src/android/jpeg/encoder_libjpeg.h\n>> index 838da7728382..ca7c1958e20e 100644\n>> --- a/src/android/jpeg/encoder_libjpeg.h\n>> +++ b/src/android/jpeg/encoder_libjpeg.h\n>> @@ -9,7 +9,8 @@\n>>     #include \"encoder.h\"\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>> +\n>>   #include \"libcamera/internal/formats.h\"\n>>     #include <jpeglib.h>\n>> diff --git a/src/android/jpeg/post_processor_jpeg.h\n>> b/src/android/jpeg/post_processor_jpeg.h\n>> index 5d2d4ab224b1..4700a7f562a2 100644\n>> --- a/src/android/jpeg/post_processor_jpeg.h\n>> +++ b/src/android/jpeg/post_processor_jpeg.h\n>> @@ -13,7 +13,7 @@\n>>     #include <libcamera/geometry.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     class CameraDevice;\n>>   diff --git a/src/android/jpeg/thumbnailer.h\n>> b/src/android/jpeg/thumbnailer.h\n>> index 4e9226c34104..483b41dfe47d 100644\n>> --- a/src/android/jpeg/thumbnailer.h\n>> +++ b/src/android/jpeg/thumbnailer.h\n>> @@ -9,7 +9,8 @@\n>>     #include <libcamera/geometry.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>> +\n>>   #include \"libcamera/internal/formats.h\"\n>>     class Thumbnailer\n>> diff --git a/src/android/meson.build b/src/android/meson.build\n>> index 6edaa1185905..abde9fd2def0 100644\n>> --- a/src/android/meson.build\n>> +++ b/src/android/meson.build\n>> @@ -5,6 +5,7 @@ android_deps = [\n>>       dependency('libjpeg', required : get_option('android')),\n>>       dependency('yaml-0.1', required : get_option('android')),\n>>       libcamera_dep,\n>> +    libcamera_helpers,\n>>   ]\n>>     android_enabled = true\n>> diff --git a/src/android/mm/generic_camera_buffer.cpp\n>> b/src/android/mm/generic_camera_buffer.cpp\n>> index f138ada14964..64c73c5716ad 100644\n>> --- a/src/android/mm/generic_camera_buffer.cpp\n>> +++ b/src/android/mm/generic_camera_buffer.cpp\n>> @@ -11,7 +11,7 @@\n>>     #include <libcamera/platform/log.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     using namespace libcamera;\n>>   diff --git a/src/android/post_processor.h\n>> b/src/android/post_processor.h\n>> index 547fda379ed8..53220edaf24d 100644\n>> --- a/src/android/post_processor.h\n>> +++ b/src/android/post_processor.h\n>> @@ -10,7 +10,7 @@\n>>   #include <libcamera/buffer.h>\n>>   #include <libcamera/stream.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     #include \"camera_buffer.h\"\n>>   diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n>> index ca1ce4dc96d0..158eb3bc49e5 100644\n>> --- a/src/ipa/ipu3/ipu3.cpp\n>> +++ b/src/ipa/ipu3/ipu3.cpp\n>> @@ -20,7 +20,7 @@\n>>     #include <libcamera/platform/log.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     #include \"ipu3_agc.h\"\n>>   #include \"ipu3_awb.h\"\n>> diff --git a/src/ipa/ipu3/meson.build b/src/ipa/ipu3/meson.build\n>> index 0d843846acde..34620024def7 100644\n>> --- a/src/ipa/ipu3/meson.build\n>> +++ b/src/ipa/ipu3/meson.build\n>> @@ -12,7 +12,7 @@ mod = shared_module(ipa_name,\n>>                       [ipu3_ipa_sources,\n>> libcamera_generated_ipa_headers],\n>>                       name_prefix : '',\n>>                       include_directories : [ipa_includes,\n>> libipa_includes],\n>> -                    dependencies : libcamera_dep,\n>> +                    dependencies : [libcamera_dep, libcamera_helpers],\n>>                       link_with : libipa,\n>>                       install : true,\n>>                       install_dir : ipa_install_dir)\n>> diff --git a/src/ipa/raspberrypi/meson.build\n>> b/src/ipa/raspberrypi/meson.build\n>> index 230356d3ce3a..b2ce6f3e8618 100644\n>> --- a/src/ipa/raspberrypi/meson.build\n>> +++ b/src/ipa/raspberrypi/meson.build\n>> @@ -4,6 +4,7 @@ ipa_name = 'ipa_rpi'\n>>     rpi_ipa_deps = [\n>>       libcamera_dep,\n>> +    libcamera_helpers,\n>>       dependency('boost'),\n>>       libatomic,\n>>   ]\n>> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp\n>> b/src/ipa/raspberrypi/raspberrypi.cpp\n>> index 90f35d970fd0..b85a1e51d757 100644\n>> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n>> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n>> @@ -26,7 +26,7 @@\n>>     #include <libcamera/platform/log.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     #include <linux/bcm2835-isp.h>\n>>   diff --git a/src/libcamera-helpers/mapped_buffer.cpp\n>> b/src/libcamera-helpers/mapped_buffer.cpp\n>> new file mode 100644\n>> index 000000000000..0d4517b62f65\n>> --- /dev/null\n>> +++ b/src/libcamera-helpers/mapped_buffer.cpp\n>> @@ -0,0 +1,171 @@\n>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> +/*\n>> + * Copyright (C) 2021, Google Inc.\n>> + *\n>> + * mapped_buffer.cpp - Mapped Buffer handling\n>> + */\n>> +\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>> +\n>> +#include <errno.h>\n>> +#include <string.h>\n>> +#include <sys/mman.h>\n>> +#include <unistd.h>\n>> +\n>> +#include <libcamera/platform/log.h>\n>> +\n>> +/**\n>> + * \\file libcamera/helpers/mapped_buffer.h\n>> + * \\brief Mapped Buffer handling\n>> + */\n>> +\n>> +namespace libcamera {\n>> +\n>> +LOG_DEFINE_CATEGORY(MappedBuffer)\n>> +\n>> +/**\n>> + * \\class MappedBuffer\n>> + * \\brief Provide an interface to support managing memory mapped buffers\n>> + *\n>> + * The MappedBuffer interface provides access to a set of\n>> MappedPlanes which\n>> + * are available for access by the CPU.\n>> + *\n>> + * This class is not meant to be constructed directly, but instead\n>> derived\n>> + * classes should be used to implement the correct mapping of a\n>> source buffer.\n>> + *\n>> + * This allows treating CPU accessible memory through a generic\n>> interface\n>> + * regardless of whether it originates from a libcamera FrameBuffer\n>> or other\n>> + * source.\n>> + */\n>> +\n>> +/**\n>> + * \\typedef MappedBuffer::Plane\n>> + * \\brief A mapped region of memory accessible to the CPU\n>> + *\n>> + * The MappedBuffer::Plane uses the Span interface to describe the\n>> mapped memory\n>> + * region.\n>> + */\n>> +\n>> +/**\n>> + * \\brief Construct an empty MappedBuffer\n>> + */\n>> +MappedBuffer::MappedBuffer()\n>> +    : error_(0)\n>> +{\n>> +}\n>> +\n>> +/**\n>> + * \\brief Move constructor, construct the MappedBuffer with the\n>> contents of \\a\n>> + * other using move semantics\n>> + * \\param[in] other The other MappedBuffer\n>> + *\n>> + * Moving a MappedBuffer moves the mappings contained in the \\a other\n>> to the new\n>> + * MappedBuffer and invalidates the \\a other.\n>> + *\n>> + * No mappings are unmapped or destroyed in this process.\n>> + */\n>> +MappedBuffer::MappedBuffer(MappedBuffer &&other)\n>> +{\n>> +    *this = std::move(other);\n>> +}\n>> +\n>> +/**\n>> + * \\brief Move assignment operator, replace the mappings with those\n>> of \\a other\n>> +* \\param[in] other The other MappedBuffer\n>> + *\n>> + * Moving a MappedBuffer moves the mappings contained in the \\a other\n>> to the new\n>> + * MappedBuffer and invalidates the \\a other.\n>> + *\n>> + * No mappings are unmapped or destroyed in this process.\n>> + */\n>> +MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other)\n>> +{\n>> +    error_ = other.error_;\n>> +    maps_ = std::move(other.maps_);\n>> +    other.error_ = -ENOENT;\n>> +\n>> +    return *this;\n>> +}\n>> +\n>> +MappedBuffer::~MappedBuffer()\n>> +{\n>> +    for (Plane &map : maps_)\n>> +        munmap(map.data(), map.size());\n>> +}\n>> +\n>> +/**\n>> + * \\fn MappedBuffer::isValid()\n>> + * \\brief Check if the MappedBuffer instance is valid\n>> + * \\return True if the MappedBuffer has valid mappings, false otherwise\n>> + */\n>> +\n>> +/**\n>> + * \\fn MappedBuffer::error()\n>> + * \\brief Retrieve the map error status\n>> + *\n>> + * This function retrieves the error status from the MappedBuffer.\n>> + * The error status is a negative number as defined by errno.h. If\n>> + * no error occurred, this function returns 0.\n>> + *\n>> + * \\return The map error code\n>> + */\n>> +\n>> +/**\n>> + * \\fn MappedBuffer::maps()\n>> + * \\brief Retrieve the mapped planes\n>> + *\n>> + * This function retrieves the successfully mapped planes stored as a\n>> vector\n>> + * of Span<uint8_t> to provide access to the mapped memory.\n>> + *\n>> + * \\return A vector of the mapped planes\n>> + */\n>> +\n>> +/**\n>> + * \\var MappedBuffer::error_\n>> + * \\brief Stores the error value if present\n>> + *\n>> + * MappedBuffer derived classes shall set this to a negative value as\n>> defined\n>> + * by errno.h if an error occured during the mapping process.\n>> + */\n>> +\n>> +/**\n>> + * \\var MappedBuffer::maps_\n>> + * \\brief Stores the internal mapped planes\n>> + *\n>> + * MappedBuffer derived classes shall store the mappings they create\n>> in this\n>> + * vector which is parsed during destruct to unmap any memory\n>> mappings which\n>> + * completed successfully.\n>> + */\n>> +\n>> +/**\n>> + * \\class MappedFrameBuffer\n>> + * \\brief Map a FrameBuffer using the MappedBuffer interface\n>> + */\n>> +\n>> +/**\n>> + * \\brief Map all planes of a FrameBuffer\n>> + * \\param[in] buffer FrameBuffer to be mapped\n>> + * \\param[in] flags Protection flags to apply to map\n>> + *\n>> + * Construct an object to map a frame buffer for CPU access.\n>> + * The flags are passed directly to mmap and should be either PROT_READ,\n>> + * PROT_WRITE, or a bitwise-or combination of both.\n>> + */\n>> +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int\n>> flags)\n>> +{\n>> +    maps_.reserve(buffer->planes().size());\n>> +\n>> +    for (const FrameBuffer::Plane &plane : buffer->planes()) {\n>> +        void *address = mmap(nullptr, plane.length, flags,\n>> +                     MAP_SHARED, plane.fd.fd(), 0);\n>> +        if (address == MAP_FAILED) {\n>> +            error_ = -errno;\n>> +            LOG(MappedBuffer, Error) << \"Failed to mmap plane\";\n>> +            break;\n>> +        }\n>> +\n>> +        maps_.emplace_back(static_cast<uint8_t *>(address),\n>> plane.length);\n>> +    }\n>> +}\n>> +\n>> +} /* namespace libcamera */\n>> diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp\n>> index 3c862820e6e1..0a232d791fcd 100644\n>> --- a/src/libcamera/buffer.cpp\n>> +++ b/src/libcamera/buffer.cpp\n>> @@ -6,7 +6,6 @@\n>>    */\n>>     #include <libcamera/buffer.h>\n>> -#include \"libcamera/internal/buffer.h\"\n>>     #include <errno.h>\n>>   #include <string.h>\n>> @@ -18,9 +17,6 @@\n>>   /**\n>>    * \\file libcamera/buffer.h\n>>    * \\brief Buffer handling\n>> - *\n>> - * \\file libcamera/internal/buffer.h\n>> - * \\brief Internal buffer handling support\n>>    */\n>>     namespace libcamera {\n>> @@ -235,149 +231,4 @@ FrameBuffer::FrameBuffer(const\n>> std::vector<Plane> &planes, unsigned int cookie)\n>>    * indicate that the metadata is invalid.\n>>    */\n>>   -/**\n>> - * \\class MappedBuffer\n>> - * \\brief Provide an interface to support managing memory mapped buffers\n>> - *\n>> - * The MappedBuffer interface provides access to a set of\n>> MappedPlanes which\n>> - * are available for access by the CPU.\n>> - *\n>> - * This class is not meant to be constructed directly, but instead\n>> derived\n>> - * classes should be used to implement the correct mapping of a\n>> source buffer.\n>> - *\n>> - * This allows treating CPU accessible memory through a generic\n>> interface\n>> - * regardless of whether it originates from a libcamera FrameBuffer\n>> or other\n>> - * source.\n>> - */\n>> -\n>> -/**\n>> - * \\typedef MappedBuffer::Plane\n>> - * \\brief A mapped region of memory accessible to the CPU\n>> - *\n>> - * The MappedBuffer::Plane uses the Span interface to describe the\n>> mapped memory\n>> - * region.\n>> - */\n>> -\n>> -/**\n>> - * \\brief Construct an empty MappedBuffer\n>> - */\n>> -MappedBuffer::MappedBuffer()\n>> -    : error_(0)\n>> -{\n>> -}\n>> -\n>> -/**\n>> - * \\brief Move constructor, construct the MappedBuffer with the\n>> contents of \\a\n>> - * other using move semantics\n>> - * \\param[in] other The other MappedBuffer\n>> - *\n>> - * Moving a MappedBuffer moves the mappings contained in the \\a other\n>> to the new\n>> - * MappedBuffer and invalidates the \\a other.\n>> - *\n>> - * No mappings are unmapped or destroyed in this process.\n>> - */\n>> -MappedBuffer::MappedBuffer(MappedBuffer &&other)\n>> -{\n>> -    *this = std::move(other);\n>> -}\n>> -\n>> -/**\n>> - * \\brief Move assignment operator, replace the mappings with those\n>> of \\a other\n>> -* \\param[in] other The other MappedBuffer\n>> - *\n>> - * Moving a MappedBuffer moves the mappings contained in the \\a other\n>> to the new\n>> - * MappedBuffer and invalidates the \\a other.\n>> - *\n>> - * No mappings are unmapped or destroyed in this process.\n>> - */\n>> -MappedBuffer &MappedBuffer::operator=(MappedBuffer &&other)\n>> -{\n>> -    error_ = other.error_;\n>> -    maps_ = std::move(other.maps_);\n>> -    other.error_ = -ENOENT;\n>> -\n>> -    return *this;\n>> -}\n>> -\n>> -MappedBuffer::~MappedBuffer()\n>> -{\n>> -    for (Plane &map : maps_)\n>> -        munmap(map.data(), map.size());\n>> -}\n>> -\n>> -/**\n>> - * \\fn MappedBuffer::isValid()\n>> - * \\brief Check if the MappedBuffer instance is valid\n>> - * \\return True if the MappedBuffer has valid mappings, false otherwise\n>> - */\n>> -\n>> -/**\n>> - * \\fn MappedBuffer::error()\n>> - * \\brief Retrieve the map error status\n>> - *\n>> - * This function retrieves the error status from the MappedBuffer.\n>> - * The error status is a negative number as defined by errno.h. If\n>> - * no error occurred, this function returns 0.\n>> - *\n>> - * \\return The map error code\n>> - */\n>> -\n>> -/**\n>> - * \\fn MappedBuffer::maps()\n>> - * \\brief Retrieve the mapped planes\n>> - *\n>> - * This function retrieves the successfully mapped planes stored as a\n>> vector\n>> - * of Span<uint8_t> to provide access to the mapped memory.\n>> - *\n>> - * \\return A vector of the mapped planes\n>> - */\n>> -\n>> -/**\n>> - * \\var MappedBuffer::error_\n>> - * \\brief Stores the error value if present\n>> - *\n>> - * MappedBuffer derived classes shall set this to a negative value as\n>> defined\n>> - * by errno.h if an error occured during the mapping process.\n>> - */\n>> -\n>> -/**\n>> - * \\var MappedBuffer::maps_\n>> - * \\brief Stores the internal mapped planes\n>> - *\n>> - * MappedBuffer derived classes shall store the mappings they create\n>> in this\n>> - * vector which is parsed during destruct to unmap any memory\n>> mappings which\n>> - * completed successfully.\n>> - */\n>> -\n>> -/**\n>> - * \\class MappedFrameBuffer\n>> - * \\brief Map a FrameBuffer using the MappedBuffer interface\n>> - */\n>> -\n>> -/**\n>> - * \\brief Map all planes of a FrameBuffer\n>> - * \\param[in] buffer FrameBuffer to be mapped\n>> - * \\param[in] flags Protection flags to apply to map\n>> - *\n>> - * Construct an object to map a frame buffer for CPU access.\n>> - * The flags are passed directly to mmap and should be either PROT_READ,\n>> - * PROT_WRITE, or a bitwise-or combination of both.\n>> - */\n>> -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int\n>> flags)\n>> -{\n>> -    maps_.reserve(buffer->planes().size());\n>> -\n>> -    for (const FrameBuffer::Plane &plane : buffer->planes()) {\n>> -        void *address = mmap(nullptr, plane.length, flags,\n>> -                     MAP_SHARED, plane.fd.fd(), 0);\n>> -        if (address == MAP_FAILED) {\n>> -            error_ = -errno;\n>> -            LOG(Buffer, Error) << \"Failed to mmap plane\";\n>> -            break;\n>> -        }\n>> -\n>> -        maps_.emplace_back(static_cast<uint8_t *>(address),\n>> plane.length);\n>> -    }\n>> -}\n>> -\n>>   } /* namespace libcamera */\n>> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n>> b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n>> index dc3fe63112d4..e6849733f979 100644\n>> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n>> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n>> @@ -29,8 +29,9 @@\n>>   #include <linux/bcm2835-isp.h>\n>>   #include <linux/videodev2.h>\n>>   +#include <libcamera/helpers/mapped_buffer.h>\n>> +\n>>   #include \"libcamera/internal/bayer_format.h\"\n>> -#include \"libcamera/internal/buffer.h\"\n>>   #include \"libcamera/internal/camera_sensor.h\"\n>>   #include \"libcamera/internal/delayed_controls.h\"\n>>   #include \"libcamera/internal/device_enumerator.h\"\n>> diff --git a/src/meson.build b/src/meson.build\n>> index 70e1a4618a0f..380de28d0f7a 100644\n>> --- a/src/meson.build\n>> +++ b/src/meson.build\n>> @@ -31,6 +31,7 @@ libcamera_objects = []\n>>   # libcamera must be built first as a dependency to the other\n>> components.\n>>   subdir('libcamera-platform')\n>>   subdir('libcamera')\n>> +subdir('libcamera-helpers')\n>>     subdir('android')\n>>   subdir('ipa')\n>> diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp\n>> index 5de8201e45f6..218d700f40da 100644\n>> --- a/test/mapped-buffer.cpp\n>> +++ b/test/mapped-buffer.cpp\n>> @@ -4,12 +4,11 @@\n>>    *\n>>    * libcamera internal MappedBuffer tests\n>>    */\n>> -\n>>   #include <iostream>\n>>     #include <libcamera/framebuffer_allocator.h>\n>>   -#include \"libcamera/internal/buffer.h\"\n>> +#include <libcamera/helpers/mapped_buffer.h>\n>>     #include \"camera_test.h\"\n>>   #include \"test.h\"\n>> diff --git a/test/meson.build b/test/meson.build\n>> index 045ad2a2d7c9..ee0d127cf1ec 100644\n>> --- a/test/meson.build\n>> +++ b/test/meson.build\n>> @@ -40,7 +40,6 @@ internal_tests = [\n>>       ['file',                            'file.cpp'],\n>>       ['file-descriptor',                 'file-descriptor.cpp'],\n>>       ['hotplug-cameras',                 'hotplug-cameras.cpp'],\n>> -    ['mapped-buffer',                   'mapped-buffer.cpp'],\n>>       ['message',                         'message.cpp'],\n>>       ['object',                          'object.cpp'],\n>>       ['object-delete',                   'object-delete.cpp'],\n>> @@ -53,6 +52,10 @@ internal_tests = [\n>>       ['utils',                           'utils.cpp'],\n>>   ]\n>>   +helpers_tests = [\n>> +    ['mapped-buffer',                   'mapped-buffer.cpp'],\n>> +]\n>> +\n>>   foreach t : public_tests\n>>       exe = executable(t[0], t[1],\n>>                        dependencies : libcamera_dep,\n>> @@ -70,3 +73,12 @@ foreach t : internal_tests\n>>         test(t[0], exe)\n>>   endforeach\n>> +\n>> +foreach t : helpers_tests\n>> +    exe = executable(t[0], t[1],\n>> +                     dependencies : [libcamera_dep, libcamera_helpers],\n>> +                     link_with : test_libraries,\n>> +                     include_directories : test_includes_internal)\n>> +\n>> +    test(t[0], exe)\n>> +endforeach","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 9AABCBD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 17 Jun 2021 07:30:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CFC6768941;\n\tThu, 17 Jun 2021 09:30:45 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 915C960297\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 17 Jun 2021 09:30:44 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0B6B2E53;\n\tThu, 17 Jun 2021 09:30:44 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"XvDW/rYd\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1623915044;\n\tbh=EdPzTRhG4NxRJY8RvxD3L4Ns1udrXeFL5oaKAqvbWcE=;\n\th=Reply-To:Subject:To:References:From:Date:In-Reply-To:From;\n\tb=XvDW/rYdnI3LWLGiIeBHe1FjEokv31dUzFLHPi2NX4rLR1EnK47QpW77igjmBLykE\n\tgwaUBN/7dMv+lgk/Nf8++RRJijINo9OoMZ3TyYSPFA5LAPoIX8dndtJo9hSLpSeenH\n\tId9ciVnN+yru4RpNVIK6X3du4YLycuwOSTuvVC8Y=","To":"Umang Jain <umang.jain@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","References":"<20210616151152.3856595-1-kieran.bingham@ideasonboard.com>\n\t<20210616151152.3856595-7-kieran.bingham@ideasonboard.com>\n\t<505e63c2-ab4f-e828-9291-7d8a36887a77@ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Organization":"Ideas on Board","Message-ID":"<ca869c15-d289-abaf-ff83-1b06b02c9601@ideasonboard.com>","Date":"Thu, 17 Jun 2021 08:30:40 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.8.1","MIME-Version":"1.0","In-Reply-To":"<505e63c2-ab4f-e828-9291-7d8a36887a77@ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH 6/6] libcamera-helpers: Provide helper\n\tlibrary","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Reply-To":"kieran.bingham@ideasonboard.com","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]