Patch Detail
Show a patch.
GET /api/patches/13230/?format=api
{ "id": 13230, "url": "https://patchwork.libcamera.org/api/patches/13230/?format=api", "web_url": "https://patchwork.libcamera.org/patch/13230/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210805182203.1297-1-laurent.pinchart@ideasonboard.com>", "date": "2021-08-05T18:22:03", "name": "[libcamera-devel,RFC] libcamera: Add FrameFormat class", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "eac8b1377215e131644a6d94785bdbb57ac078be", "submitter": { "id": 2, "url": "https://patchwork.libcamera.org/api/people/2/?format=api", "name": "Laurent Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "delegate": { "id": 14, "url": "https://patchwork.libcamera.org/api/users/14/?format=api", "username": "pinchartl", "first_name": "Laurent", "last_name": "Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "mbox": "https://patchwork.libcamera.org/patch/13230/mbox/", "series": [ { "id": 2313, "url": "https://patchwork.libcamera.org/api/series/2313/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2313", "date": "2021-08-05T18:22:03", "name": "[libcamera-devel,RFC] libcamera: Add FrameFormat class", "version": 1, "mbox": "https://patchwork.libcamera.org/series/2313/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/13230/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/13230/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C070BC3235\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 5 Aug 2021 18:22:25 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 34DD36881B;\n\tThu, 5 Aug 2021 20:22:25 +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 12F046026D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 5 Aug 2021 20:22:24 +0200 (CEST)", "from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D5B3E04;\n\tThu, 5 Aug 2021 20:22:23 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"srUHfKlr\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628187743;\n\tbh=koRM3ZbradqDe8I9xvxRR8oGC/sSx6Dpf/r1e0jAu3c=;\n\th=From:To:Cc:Subject:Date:From;\n\tb=srUHfKlrVJ+pOdVzIDTKP0Ykp5v1VZNYpHBgV0JoIfxYb3xhID7rpEfFcWRNHJ8wS\n\t3mIrLgIqBAkIFzkl/VCy4gZmp4jJzyxgPJrG73/SIWOJ/qFOSazSLhs7lA2dMFlCDZ\n\tv7YsFjMRg8I/lBGKvZiAR1HxlaejUFiBuG/tpXdM=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Thu, 5 Aug 2021 21:22:03 +0300", "Message-Id": "<20210805182203.1297-1-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.31.1", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[libcamera-devel] [RFC PATCH] libcamera: Add FrameFormat class", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "The FrameFormat class describes how a frame is stored in memory. It\ngroups a pixel format, size in pixels, and per-plane stride and size.\n\nThis new class will be used in the configuration API rework, but could\nalready be put in use if desired to replace the various data structures\nused to carry the same information.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n\nI've developed this as part of the configuration API rework, and\nrealized it could already be useful, in particular if we want to start\ncleaning up support for multi-planar formats. I'm thus sending it as an\nRFC.\n\n---\n include/libcamera/format.h | 43 ++++++++++\n include/libcamera/meson.build | 1 +\n src/libcamera/format.cpp | 142 ++++++++++++++++++++++++++++++++++\n src/libcamera/meson.build | 1 +\n 4 files changed, 187 insertions(+)\n create mode 100644 include/libcamera/format.h\n create mode 100644 src/libcamera/format.cpp", "diff": "diff --git a/include/libcamera/format.h b/include/libcamera/format.h\nnew file mode 100644\nindex 000000000000..4982ab8230dc\n--- /dev/null\n+++ b/include/libcamera/format.h\n@@ -0,0 +1,43 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Google Inc.\n+ *\n+ * format.h - Frame Format\n+ */\n+#ifndef __LIBCAMERA_FORMAT_H__\n+#define __LIBCAMERA_FORMAT_H__\n+\n+#include <array>\n+#include <cstddef>\n+#include <string>\n+\n+#include <libcamera/geometry.h>\n+#include <libcamera/pixel_format.h>\n+\n+namespace libcamera {\n+\n+class FrameFormat\n+{\n+public:\n+\tstatic constexpr unsigned int kMaxPlanes = 4;\n+\n+\tstruct Plane {\n+\t\tstd::size_t stride;\n+\t\tstd::size_t size;\n+\t};\n+\n+\tFrameFormat();\n+\tFrameFormat(PixelFormat format, const Size &size);\n+\n+\tstd::size_t stride() const;\n+\tstd::size_t frameSize() const;\n+\tstd::string toString() const;\n+\n+\tPixelFormat format_;\n+\tSize size_;\n+\tstd::array<Plane, kMaxPlanes> planes_;\n+};\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_FORMAT_H__ */\ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 5b25ef847ed4..dcfadb381874 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -6,6 +6,7 @@ libcamera_public_headers = files([\n 'compiler.h',\n 'controls.h',\n 'file_descriptor.h',\n+ 'format.h',\n 'framebuffer.h',\n 'framebuffer_allocator.h',\n 'geometry.h',\ndiff --git a/src/libcamera/format.cpp b/src/libcamera/format.cpp\nnew file mode 100644\nindex 000000000000..f77413781de1\n--- /dev/null\n+++ b/src/libcamera/format.cpp\n@@ -0,0 +1,142 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2021, Google Inc.\n+ *\n+ * format.cpp - Frame Format\n+ */\n+\n+#include <libcamera/format.h>\n+\n+#include <numeric>\n+\n+/**\n+ * \\file libcamera/format.h\n+ * \\brief Frame Format\n+ */\n+\n+namespace libcamera {\n+\n+/**\n+ * \\class FrameFormat\n+ * \\brief Format of a frame as stored in memory\n+ *\n+ * The FrameFormat class fully describes how a frame is stored in memory. It\n+ * combines a pixel format, a size in pixels, and memory layout information for\n+ * planes.\n+ *\n+ * Frames are stored in memory in one or multiple planes, as specified by the\n+ * pixel format. A plane is a two-dimensional memory area organized as lines of\n+ * samples. A sample typically stores one or multiple components of a pixel (for\n+ * instance, the NV12 format uses two planes, with the first plane storing only\n+ * the luminance Y component of the pixels, and the second plane storing both\n+ * the chroma Cb and Cr components).\n+ *\n+ * Planes cover the whole frame. Their number of lines and sample per lines\n+ * correspond to the frame width and height in pixels, possibly divided by\n+ * horizontal and vertical subsampling factors as specified by the pixel\n+ * format.\n+ *\n+ * A plane may contain padding at the end of line, to support requirements of\n+ * applications and cameras, such as alignment constraints. This is specified\n+ * as a line stride value, equal to the distance in bytes between the first\n+ * sample of successive lines in memory, including pixel data and padding. All\n+ * lines in a plane have the same stride value, including the last line.\n+ * Additionally, padding may also occur at the end of the plane, specified as\n+ * the total plane size in bytes.\n+ *\n+ * \\var FrameFormat::kMaxPlanes\n+ * \\brief Maximum number of data planes for a frame\n+ *\n+ * \\var FrameFormat::format_\n+ * \\brief Frame pixel format, defines how pixel data is packed and stored in\n+ * memory\n+ *\n+ * \\var FrameFormat::size_\n+ * \\brief Frame size, defines the horizontal and vertical dimensions of the\n+ * frame in pixels (excluding any padding)\n+ *\n+ * \\var FrameFormat::planes_\n+ * \\brief Frame data planes, defines the memory layout for each data plane of\n+ * the frame\n+ *\n+ * Unused entries in the planes array shall be zero-initialized.\n+ */\n+\n+/**\n+ * \\class FrameFormat::Plane\n+ * \\brief Memory layout configuration for one data plane of a frame\n+ *\n+ * \\var FrameFormat::Plane::stride\n+ * \\brief Distance in bytes between the beginning of two successive lines\n+ *\n+ * If the strides of different planes can't be set separately, the stride of the\n+ * first plane takes precedence and is used by the camera.\n+ *\n+ * \\var FrameFormat::Plane::size\n+ * \\brief Maximum number of bytes required to store the plane\n+ *\n+ * The \\a size reports the number of bytes required to store data for plane.\n+ * For uncompressed formats, it takes into account the plane's stride, the\n+ * frame height, the plane's vertical subsampling and the overall alignment\n+ * constraints of the camera (for instance many cameras require buffer sizes\n+ * to be a multiple of the page size). For compressed formats, it indicates the\n+ * maximum size of the compressed data.\n+ */\n+\n+/**\n+ * \\brief Construct a zero-initialized FrameFormat\n+ */\n+FrameFormat::FrameFormat() = default;\n+\n+/**\n+ * \\brief Construct a FrameFormat\n+ * \\param[in] format The pixel format\n+ * \\param[in] size The frame size in pixels\n+ */\n+FrameFormat::FrameFormat(PixelFormat format, const Size &size)\n+\t: format_(format), size_(size)\n+{\n+}\n+\n+/**\n+ * \\brief Retrieve the frame stride in bytes\n+ *\n+ * The stride() function is a convenience helper to retrieve the stride of the\n+ * first plane. For multi-planar formats that have different stride values for\n+ * each plane, applications shall access the stride from the \\ref planes_\n+ * instead.\n+ *\n+ * \\return The frame stride in bytes\n+ */\n+std::size_t FrameFormat::stride() const\n+{\n+\treturn planes_[0].stride;\n+}\n+\n+/**\n+ * \\brief Retrieve the full frame size\n+ *\n+ * The frameSize() function is a convenience helper to retrieve the full frame\n+ * size, defined as the sum of the sizes of all planes.\n+ *\n+ * \\return The full frame size, in bytes\n+ */\n+std::size_t FrameFormat::frameSize() const\n+{\n+\treturn std::accumulate(planes_.begin(), planes_.end(), 0,\n+\t\t\t [](std::size_t a, const Plane &b) {\n+\t\t\t\t return a + b.size;\n+\t\t\t });\n+}\n+\n+/**\n+ * \\brief Assemble and return a string describing the frame format\n+ *\n+ * \\return A string describing the FrameFormat\n+ */\n+std::string FrameFormat::toString() const\n+{\n+\treturn size_.toString() + \"-\" + format_.toString();\n+}\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 4f08580157f9..7cf17ec2c628 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -15,6 +15,7 @@ libcamera_sources = files([\n 'device_enumerator.cpp',\n 'device_enumerator_sysfs.cpp',\n 'file_descriptor.cpp',\n+ 'format.cpp',\n 'formats.cpp',\n 'framebuffer.cpp',\n 'framebuffer_allocator.cpp',\n", "prefixes": [ "libcamera-devel", "RFC" ] }