[{"id":12801,"web_url":"https://patchwork.libcamera.org/comment/12801/","msgid":"<20200928105714.GB23539@pendragon.ideasonboard.com>","date":"2020-09-28T10:57:14","subject":"Re: [libcamera-devel] [PATCH v8 4/8] libcamera: Add BayerFormat type","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David,\n\nThank you for the patch.\n\nOn Mon, Sep 07, 2020 at 08:15:59AM +0100, David Plowman wrote:\n> This type encodes BayerFormats in an explicit way, that makes them\n> easier to use than some of the other more opaque type formats. This\n> makes the BayerFormat useful for editing or manipulating Bayer types\n> more easily.\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  include/libcamera/internal/bayer_format.h |  61 +++++\n>  src/libcamera/bayer_format.cpp            | 268 ++++++++++++++++++++++\n>  src/libcamera/meson.build                 |   1 +\n>  3 files changed, 330 insertions(+)\n>  create mode 100644 include/libcamera/internal/bayer_format.h\n>  create mode 100644 src/libcamera/bayer_format.cpp\n> \n> diff --git a/include/libcamera/internal/bayer_format.h b/include/libcamera/internal/bayer_format.h\n> new file mode 100644\n> index 0000000..4280b76\n> --- /dev/null\n> +++ b/include/libcamera/internal/bayer_format.h\n> @@ -0,0 +1,61 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2020, Raspberry Pi (Trading) Ltd.\n> + *\n> + * bayer_format.h - Bayer Pixel Format\n> + */\n> +#ifndef __LIBCAMERA_INTERNAL_BAYER_FORMAT_H__\n> +#define __LIBCAMERA_INTERNAL_BAYER_FORMAT_H__\n> +\n> +#include <stdint.h>\n> +#include <string>\n> +\n> +#include \"libcamera/internal/v4l2_pixelformat.h\"\n> +\n> +namespace libcamera {\n> +\n> +enum class Transform;\n> +\n> +class BayerFormat\n> +{\n> +public:\n> +\tenum Order : uint8_t {\n> +\t\tBGGR = 0,\n> +\t\tGBRG = 1,\n> +\t\tGRBG = 2,\n> +\t\tRGGB = 3\n> +\t};\n> +\n> +\tenum Packing : uint16_t {\n> +\t\tNone = 0,\n> +\t\tCSI2Packed = 1,\n> +\t\tIPU3Packed = 2,\n> +\t};\n> +\n> +\tconstexpr BayerFormat()\n> +\t\t: order(Order::BGGR), bitDepth(0), packing(Packing::None)\n> +\t{\n> +\t}\n> +\n> +\tconstexpr BayerFormat(Order o, uint8_t b, Packing p)\n> +\t\t: order(o), bitDepth(b), packing(p)\n> +\t{\n> +\t}\n> +\n> +\texplicit BayerFormat(V4L2PixelFormat v4l2Format);\n> +\tbool isValid() const { return bitDepth != 0; }\n> +\n> +\tstd::string toString() const;\n> +\n> +\tV4L2PixelFormat toV4L2PixelFormat() const;\n> +\tBayerFormat transform(Transform t) const;\n> +\n> +\tOrder order;\n> +\tuint8_t bitDepth;\n> +\n> +\tPacking packing;\n> +};\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_INTERNAL_BAYER_FORMAT_H__ */\n> diff --git a/src/libcamera/bayer_format.cpp b/src/libcamera/bayer_format.cpp\n> new file mode 100644\n> index 0000000..c7e4f22\n> --- /dev/null\n> +++ b/src/libcamera/bayer_format.cpp\n> @@ -0,0 +1,268 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2020, Raspberry Pi (Trading) Limited\n> + *\n> + * bayer_format.cpp - Class to represent Bayer formats\n> + */\n> +\n> +#include \"libcamera/internal/bayer_format.h\"\n> +\n> +#include <map>\n> +\n> +#include <libcamera/transform.h>\n> +\n> +/**\n> + * \\file bayer_format.h\n> + * \\brief Class to represent Bayer formats and manipulate them\n> + */\n> +\n> +namespace libcamera {\n> +\n> +/**\n> + * \\class BayerFormat\n> + * \\brief Class to represent a raw image Bayer format\n> + *\n> + * This class encodes the different Bayer formats in such a way that they can\n> + * be easily manipulated. For example, the bit depth or Bayer order can be\n> + * easily altered - the Bayer order can even be \"transformed\" in the same\n> + * manner as happens in many sensors when their horizontal or vertical \"flip\"\n> + * controls are set.\n> + */\n> +\n> +/**\n> + * \\enum BayerFormat::Order\n> + * \\brief The order of the colour channels in the Bayer pattern\n> + *\n> + * \\var BayerFormat::BGGR\n> + * \\brief B then G on the first row, G then R on the second row.\n> + * \\var BayerFormat::GBRG\n> + * \\brief G then B on the first row, R then G on the second row.\n> + * \\var BayerFormat::GRBG\n> + * \\brief G then R on the first row, B then G on the second row.\n> + * \\var BayerFormat::RGGB\n> + * \\brief R then G on the first row, G then B on the second row.\n> + */\n> +\n> +/**\n> + * \\enum BayerFormat::Packing\n> + * \\brief Different types of packing that can be applied to a BayerFormat\n> + *\n> + * \\var BayerFormat::None\n> + * \\brief No packing\n> + * \\var BayerFormat::CSI2Packed\n> + * \\brief Format uses MIPI CSI-2 style packing\n> + * \\var BayerFormat::IPU3Packed\n> + * \\brief Format uses IPU3 style packing\n> + */\n> +\n> +namespace {\n> +\n> +const std::map<V4L2PixelFormat, BayerFormat> v4l2ToBayer{\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8), { BayerFormat::BGGR, 8, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8), { BayerFormat::GBRG, 8, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8), { BayerFormat::GRBG, 8, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8), { BayerFormat::RGGB, 8, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10), { BayerFormat::BGGR, 10, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10), { BayerFormat::GBRG, 10, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10), { BayerFormat::GRBG, 10, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10), { BayerFormat::RGGB, 10, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P), { BayerFormat::BGGR, 10, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P), { BayerFormat::GBRG, 10, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P), { BayerFormat::GRBG, 10, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P), { BayerFormat::RGGB, 10, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10), { BayerFormat::BGGR, 10, BayerFormat::IPU3Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10), { BayerFormat::GBRG, 10, BayerFormat::IPU3Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10), { BayerFormat::GRBG, 10, BayerFormat::IPU3Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10), { BayerFormat::RGGB, 10, BayerFormat::IPU3Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12), { BayerFormat::BGGR, 12, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12), { BayerFormat::GBRG, 12, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12), { BayerFormat::GRBG, 12, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12), { BayerFormat::RGGB, 12, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P), { BayerFormat::BGGR, 12, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P), { BayerFormat::GBRG, 12, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P), { BayerFormat::GRBG, 12, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P), { BayerFormat::RGGB, 12, BayerFormat::CSI2Packed } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16), { BayerFormat::BGGR, 16, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16), { BayerFormat::GBRG, 16, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16), { BayerFormat::GRBG, 16, BayerFormat::None } },\n> +\t{ V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16), { BayerFormat::RGGB, 16, BayerFormat::None } },\n> +};\n> +\n> +/* Define a slightly arbitrary ordering so that we can use a std::map. */\n> +struct BayerFormatComparator {\n> +\tconstexpr bool operator()(const BayerFormat &lhs, const BayerFormat &rhs) const\n> +\t{\n> +\t\tif (lhs.bitDepth < rhs.bitDepth)\n> +\t\t\treturn true;\n> +\t\telse if (lhs.bitDepth > rhs.bitDepth)\n> +\t\t\treturn false;\n> +\n> +\t\tif (lhs.order < rhs.order)\n> +\t\t\treturn true;\n> +\t\telse if (lhs.order > rhs.order)\n> +\t\t\treturn false;\n> +\n> +\t\tif (lhs.packing < rhs.packing)\n> +\t\t\treturn true;\n> +\t\telse\n> +\t\t\treturn false;\n> +\t}\n> +};\n> +\n> +const std::map<BayerFormat, V4L2PixelFormat, BayerFormatComparator> bayerToV4l2{\n> +\t{ { BayerFormat::BGGR, 8, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SBGGR8) },\n> +\t{ { BayerFormat::GBRG, 8, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG8) },\n> +\t{ { BayerFormat::GRBG, 8, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG8) },\n> +\t{ { BayerFormat::RGGB, 8, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB8) },\n> +\t{ { BayerFormat::BGGR, 10, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10) },\n> +\t{ { BayerFormat::GBRG, 10, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10) },\n> +\t{ { BayerFormat::GRBG, 10, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10) },\n> +\t{ { BayerFormat::RGGB, 10, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10) },\n> +\t{ { BayerFormat::BGGR, 10, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SBGGR10P) },\n> +\t{ { BayerFormat::GBRG, 10, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG10P) },\n> +\t{ { BayerFormat::GRBG, 10, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG10P) },\n> +\t{ { BayerFormat::RGGB, 10, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB10P) },\n> +\t{ { BayerFormat::BGGR, 10, BayerFormat::IPU3Packed }, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SBGGR10) },\n> +\t{ { BayerFormat::GBRG, 10, BayerFormat::IPU3Packed }, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGBRG10) },\n> +\t{ { BayerFormat::GRBG, 10, BayerFormat::IPU3Packed }, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SGRBG10) },\n> +\t{ { BayerFormat::RGGB, 10, BayerFormat::IPU3Packed }, V4L2PixelFormat(V4L2_PIX_FMT_IPU3_SRGGB10) },\n> +\t{ { BayerFormat::BGGR, 12, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12) },\n> +\t{ { BayerFormat::GBRG, 12, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12) },\n> +\t{ { BayerFormat::GRBG, 12, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12) },\n> +\t{ { BayerFormat::RGGB, 12, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12) },\n> +\t{ { BayerFormat::BGGR, 12, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SBGGR12P) },\n> +\t{ { BayerFormat::GBRG, 12, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG12P) },\n> +\t{ { BayerFormat::GRBG, 12, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG12P) },\n> +\t{ { BayerFormat::RGGB, 12, BayerFormat::CSI2Packed }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB12P) },\n> +\t{ { BayerFormat::BGGR, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SBGGR16) },\n> +\t{ { BayerFormat::GBRG, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGBRG16) },\n> +\t{ { BayerFormat::GRBG, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SGRBG16) },\n> +\t{ { BayerFormat::RGGB, 16, BayerFormat::None }, V4L2PixelFormat(V4L2_PIX_FMT_SRGGB16) },\n> +};\n> +\n> +} // namespace\n\n} /* namespace */\n\nWith this small issue fixed,\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\n> +/**\n> + * \\fn BayerFormat::BayerFormat()\n> + * \\brief Construct an empty (and invalid) BayerFormat\n> + */\n> +\n> +/**\n> + * \\fn BayerFormat::BayerFormat(Order o, uint8_t b, Packing p)\n> + * \\brief Construct a BayerFormat from explicit values\n> + * \\param[in] o The order of the Bayer pattern\n> + * \\param[in] b The bit depth of the Bayer samples\n> + * \\param[in] p The type of packing applied to the pixel values\n> + */\n> +\n> +/**\n> + * \\brief Construct a BayerFormat from a V4L2PixelFormat\n> + * \\param[in] v4l2Format The raw format to convert into a BayerFormat\n> + */\n> +BayerFormat::BayerFormat(V4L2PixelFormat v4l2Format)\n> +\t: order(BGGR), packing(None)\n> +{\n> +\tconst auto it = v4l2ToBayer.find(v4l2Format);\n> +\tif (it == v4l2ToBayer.end())\n> +\t\tbitDepth = 0;\n> +\telse\n> +\t\t*this = it->second;\n> +}\n> +\n> +/**\n> + * \\fn BayerFormat::isValid()\n> + * \\brief Return whether a BayerFormat is valid\n> + */\n> +\n> +/**\n> + * \\brief Assemble and return a readable string representation of the\n> + * BayerFormat\n> + * \\return A string describing the BayerFormat\n> + */\n> +std::string BayerFormat::toString() const\n> +{\n> +\tstd::string result;\n> +\n> +\tstatic const char *orderStrings[] = {\n> +\t\t\"BGGR\",\n> +\t\t\"GBRG\",\n> +\t\t\"GRBG\",\n> +\t\t\"RGGB\"\n> +\t};\n> +\tif (isValid() && order <= RGGB)\n> +\t\tresult = orderStrings[order];\n> +\telse\n> +\t\treturn \"INVALID\";\n> +\n> +\tresult += \"-\" + std::to_string(bitDepth);\n> +\n> +\tif (packing == CSI2Packed)\n> +\t\tresult += \"-CSI2P\";\n> +\telse if (packing == IPU3Packed)\n> +\t\tresult += \"-IPU3P\";\n> +\n> +\treturn result;\n> +}\n> +\n> +/**\n> + * \\brief Convert a BayerFormat into the corresponding V4L2PixelFormat\n> + * \\return The V4L2PixelFormat corresponding to this BayerFormat\n> + */\n> +V4L2PixelFormat BayerFormat::toV4L2PixelFormat() const\n> +{\n> +\tconst auto it = bayerToV4l2.find(*this);\n> +\tif (it != bayerToV4l2.end())\n> +\t\treturn it->second;\n> +\n> +\treturn V4L2PixelFormat();\n> +}\n> +\n> +/**\n> + * \\brief Apply a transform to this BayerFormat\n> + * \\param[in] t The transform to apply\n> + *\n> + * Appplying a transform to an image stored in a Bayer format affects the Bayer\n> + * order. For example, performing a horizontal flip on the Bayer pattern\n> + * RGGB causes the RG rows of pixels to become GR, and the GB rows to become BG.\n> + * The transformed image would have a GRBG order. The bit depth and modifiers\n> + * are not affected.\n> + *\n> + * Note that transpositions are ignored as the order of a transpose with\n> + * respect to the flips would have to be defined, and sensors are not expected\n> + * to support transposition.\n> + *\n> + * \\return The transformed Bayer format\n> + */\n> +BayerFormat BayerFormat::transform(Transform t) const\n> +{\n> +\tBayerFormat result = *this;\n> +\n> +\t/*\n> +\t * Observe that flipping bit 0 of the Order enum performs a horizontal\n> +\t * mirror on the Bayer pattern (e.g. RGGB goes to GRBG). Similarly,\n> +\t * flipping bit 1 performs a vertical mirror operation on it. Hence:\n> +\t */\n> +\tif (!!(t & Transform::HFlip))\n> +\t\tresult.order = static_cast<Order>(result.order ^ 1);\n> +\tif (!!(t & Transform::VFlip))\n> +\t\tresult.order = static_cast<Order>(result.order ^ 2);\n> +\n> +\treturn result;\n> +}\n> +\n> +/**\n> + * \\var BayerFormat::order\n> + * \\brief The order of the colour channels in the Bayer pattern\n> + */\n> +\n> +/**\n> + * \\var BayerFormat::bitDepth\n> + * \\brief The bit depth of the samples in the Bayer pattern\n> + */\n> +\n> +/**\n> + * \\var BayerFormat::packing\n> + * \\brief Any packing scheme applied to this BayerFormat\n> + */\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index edec55e..86c225f 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -1,6 +1,7 @@\n>  # SPDX-License-Identifier: CC0-1.0\n>  \n>  libcamera_sources = files([\n> +    'bayer_format.cpp',\n>      'bound_method.cpp',\n>      'buffer.cpp',\n>      'byte_stream_buffer.cpp',","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 C0E24C3B5B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 28 Sep 2020 10:57:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 245A460CE7;\n\tMon, 28 Sep 2020 12:57:50 +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 3AC0960364\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 28 Sep 2020 12:57:49 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B09DA54E;\n\tMon, 28 Sep 2020 12:57:48 +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=\"gmzgr2od\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1601290668;\n\tbh=jKLm+UlyywsvHhmYY3NH7lb09LJlmkrrjYUn9T1XQk4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=gmzgr2odgs6cUbespmN6apvZKHWFu3RVXDzh+4jQAqUc7vtugapMFx2VJb0nLgNv4\n\tg3htIIYcdUldhKyyyqq00/3t1WORgMMhzW7ki/yhV4IABBSKNExYcrdGm7v3hntdBR\n\t7DpqLIxP7QRwJv7CPhhvkYrbR+lH3UlzHRbMuOZc=","Date":"Mon, 28 Sep 2020 13:57:14 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<20200928105714.GB23539@pendragon.ideasonboard.com>","References":"<20200907071604.8355-1-david.plowman@raspberrypi.com>\n\t<20200907071604.8355-5-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200907071604.8355-5-david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH v8 4/8] libcamera: Add BayerFormat type","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]