Show a patch.

GET /api/1.1/patches/4006/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 4006,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/4006/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/4006/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/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": "<20200609232323.29628-2-laurent.pinchart@ideasonboard.com>",
    "date": "2020-06-09T23:23:17",
    "name": "[libcamera-devel,v2,1/7] libcamera: Define constants for pixel formats in the public API",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "720bc146bd01c12a9291e2f745db8975795db239",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/4006/mbox/",
    "series": [
        {
            "id": 982,
            "url": "https://patchwork.libcamera.org/api/1.1/series/982/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=982",
            "date": "2020-06-09T23:23:16",
            "name": "Introduce formats:: namespace for libcamera pixel formats",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/982/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/4006/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/4006/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<laurent.pinchart@ideasonboard.com>",
        "Received": [
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C2F306002B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Jun 2020 01:23:48 +0200 (CEST)",
            "from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id EF1E631F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Jun 2020 01:23:47 +0200 (CEST)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"uNTZSXeB\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1591745028;\n\tbh=UiiWkBBwjYXyJm+N89kN6zugSathEb9SPzJyKR/iipM=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=uNTZSXeBJejEGeUSb6/F2yf8CDRmd9feVY+IJo5zvrBJwH8nX+/ErIk5YYarzDW4o\n\tM1ePEB+fuufJ+FVf99yprLS0Y2MT0Ko0ce0D4EA+O6D7vdsa/faZl92EJVeToWmbeL\n\tsO166pYYEoqGSIaYrdvoHy8R4pFNFxlni0bpL/0E=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Wed, 10 Jun 2020 02:23:17 +0300",
        "Message-Id": "<20200609232323.29628-2-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.27.0",
        "In-Reply-To": "<20200609232323.29628-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20200609232323.29628-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 1/7] libcamera: Define constants for\n\tpixel formats in the public API",
        "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>",
        "X-List-Received-Date": "Tue, 09 Jun 2020 23:23:49 -0000"
    },
    "content": "libcamera uses pixel format FourCC and modifier values from DRM. This\nrequires inclusion of drm_fourcc.h, creating a dependency on a header\nthat is packaged differently between distributions, and causing possible\nissues with third-party applications.\n\nDefine constants for the supported pixel formats in the new formats.h\npublic API header, in order to remove the dependency on drm_fourcc.h.\nThe header is generated by a Python script from a list of supported\nformats. The numerical values for the FourCC and modifier are extracted\nfrom drm_fourcc.h by the script, ensuring that numerical values are not\ninadvertently modified and preserving the direct interoperability.\n\nThe pixel formats constants can't be generated solely from drm_fourcc.h,\nas that header defines FourCC values and modifier values, but doesn't\nlist the valid combinations. The supported formats are thus stored in a\nYAML file, which contains the FourCC and optional modifier for each\nsupported format. We may later extend the YAML file to include formats\ndocumentation, and possibly formats metadata to populate the\npixelFormatInfo map (in formats.cpp) automatically.\n\nNow that two formats.h header are present (one in include/libcamera/ and\none in include/libcamera/internal/), we need to explicitly qualify the\nDoxygen \\file directive with a path.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\nChanges since v1:\n\n- Add a note about the Doxygen \\file change to the commit message\n- Generate formats.h from formats.yaml\n- Dropped Kieran's R-b tag due to the switch to auto-generation\n- Mention libcamera/formats.h in the PixelFormat class documentation\n- Add IPU3-packed Bayer formats\n---\n include/libcamera/formats.h.in   |  44 +++++++++++\n include/libcamera/gen-formats.py | 118 +++++++++++++++++++++++++++++\n include/libcamera/meson.build    |  22 ++++++\n src/libcamera/formats.cpp        |   2 +-\n src/libcamera/formats.yaml       | 124 +++++++++++++++++++++++++++++++\n src/libcamera/pixel_format.cpp   |   4 +-\n 6 files changed, 312 insertions(+), 2 deletions(-)\n create mode 100644 include/libcamera/formats.h.in\n create mode 100755 include/libcamera/gen-formats.py\n create mode 100644 src/libcamera/formats.yaml",
    "diff": "diff --git a/include/libcamera/formats.h.in b/include/libcamera/formats.h.in\nnew file mode 100644\nindex 000000000000..8e7b95812afa\n--- /dev/null\n+++ b/include/libcamera/formats.h.in\n@@ -0,0 +1,44 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2020, Google Inc.\n+ *\n+ * formats.h - Formats\n+ *\n+ * This file is auto-generated. Do not edit.\n+ */\n+#ifndef __LIBCAMERA_FORMATS_H__\n+#define __LIBCAMERA_FORMATS_H__\n+\n+#include <stdint.h>\n+\n+#include <libcamera/pixel_format.h>\n+\n+namespace libcamera {\n+\n+namespace formats {\n+\n+namespace {\n+\n+constexpr uint32_t __fourcc(char a, char b, char c, char d)\n+{\n+\treturn (static_cast<uint32_t>(a) <<  0) |\n+\t       (static_cast<uint32_t>(b) <<  8) |\n+\t       (static_cast<uint32_t>(c) << 16) |\n+\t       (static_cast<uint32_t>(d) << 24);\n+}\n+\n+constexpr uint64_t __mod(unsigned int vendor, unsigned int mod)\n+{\n+\treturn (static_cast<uint64_t>(vendor) << 56) |\n+\t       (static_cast<uint64_t>(mod) << 0);\n+}\n+\n+} /* namespace */\n+\n+${formats}\n+\n+} /* namespace formats */\n+\n+} /* namespace libcamera */\n+\n+#endif /* __LIBCAMERA_FORMATS_H__ */\ndiff --git a/include/libcamera/gen-formats.py b/include/libcamera/gen-formats.py\nnew file mode 100755\nindex 000000000000..9bbff5f1cf6f\n--- /dev/null\n+++ b/include/libcamera/gen-formats.py\n@@ -0,0 +1,118 @@\n+#!/usr/bin/env python3\n+# SPDX-License-Identifier: GPL-2.0-or-later\n+# Copyright (C) 2020, Google Inc.\n+#\n+# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n+#\n+# gen-formatss.py - Generate formats definitions from YAML\n+\n+import argparse\n+import re\n+import string\n+import sys\n+import yaml\n+\n+\n+class DRMFourCC(object):\n+    format_regex = re.compile(r\"#define (DRM_FORMAT_[A-Z0-9_]+)[ \\t]+fourcc_code\\(('.', '.', '.', '.')\\)\")\n+    mod_vendor_regex = re.compile(r\"#define DRM_FORMAT_MOD_VENDOR_([A-Z0-9_]+)[ \\t]+([0-9a-fA-Fx]+)\")\n+    mod_regex = re.compile(r\"#define ([A-Za-z0-9_]+)[ \\t]+fourcc_mod_code\\(([A-Z0-9_]+), ([0-9a-fA-Fx]+)\\)\")\n+\n+    def __init__(self, filename):\n+        self.formats = {}\n+        self.vendors = {}\n+        self.mods = {}\n+\n+        for line in open(filename, 'rb').readlines():\n+            line = line.decode('utf-8')\n+\n+            match = DRMFourCC.format_regex.match(line)\n+            if match:\n+                format, fourcc = match.groups()\n+                self.formats[format] = fourcc\n+                continue\n+\n+            match = DRMFourCC.mod_vendor_regex.match(line)\n+            if match:\n+                vendor, value = match.groups()\n+                self.vendors[vendor] = int(value, 0)\n+                continue\n+\n+            match = DRMFourCC.mod_regex.match(line)\n+            if match:\n+                mod, vendor, value = match.groups()\n+                self.mods[mod] = (vendor, int(value, 0))\n+                continue\n+\n+    def fourcc(self, name):\n+        return self.formats[name]\n+\n+    def mod(self, name):\n+        vendor, value = self.mods[name]\n+        return self.vendors[vendor], value\n+\n+\n+def generate_h(formats, drm_fourcc):\n+    template = string.Template('constexpr PixelFormat ${name}{ __fourcc(${fourcc}), __mod(${mod}) };')\n+\n+    fmts = []\n+\n+    for format in formats:\n+        name, format = format.popitem()\n+\n+        data = {\n+            'name': name,\n+            'fourcc': drm_fourcc.fourcc(format['fourcc']),\n+            'mod': '0, 0',\n+        }\n+\n+        mod = format.get('mod')\n+        if mod:\n+            data['mod'] = '%u, %u' % drm_fourcc.mod(mod)\n+\n+        fmts.append(template.substitute(data))\n+\n+    return {'formats': '\\n'.join(fmts)}\n+\n+\n+def fill_template(template, data):\n+\n+    template = open(template, 'rb').read()\n+    template = template.decode('utf-8')\n+    template = string.Template(template)\n+    return template.substitute(data)\n+\n+\n+def main(argv):\n+\n+    # Parse command line arguments\n+    parser = argparse.ArgumentParser()\n+    parser.add_argument('-o', dest='output', metavar='file', type=str,\n+                        help='Output file name. Defaults to standard output if not specified.')\n+    parser.add_argument('input', type=str,\n+                        help='Input file name.')\n+    parser.add_argument('template', type=str,\n+                        help='Template file name.')\n+    parser.add_argument('drm_fourcc', type=str,\n+                        help='Path to drm_fourcc.h.')\n+    args = parser.parse_args(argv[1:])\n+\n+    data = open(args.input, 'rb').read()\n+    formats = yaml.safe_load(data)['formats']\n+    drm_fourcc = DRMFourCC(args.drm_fourcc)\n+\n+    data = generate_h(formats, drm_fourcc)\n+    data = fill_template(args.template, data)\n+\n+    if args.output:\n+        output = open(args.output, 'wb')\n+        output.write(data.encode('utf-8'))\n+        output.close()\n+    else:\n+        sys.stdout.write(data)\n+\n+    return 0\n+\n+\n+if __name__ == '__main__':\n+    sys.exit(main(sys.argv))\ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 73c5b999acf4..cdb8e0372e77 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -29,6 +29,11 @@ subdir('ipa')\n install_headers(libcamera_public_headers,\n                 subdir : include_dir)\n \n+#\n+# Generate headers from templates.\n+#\n+\n+# control_ids.h and property_ids.h\n gen_controls = files('../../src/libcamera/gen-controls.py')\n \n control_source_files = [\n@@ -51,6 +56,22 @@ endforeach\n \n libcamera_public_headers += control_headers\n \n+# formats.h\n+gen_formats = files('gen-formats.py')\n+\n+formats_h = custom_target('formats_h',\n+                          input : files(\n+                              '../../src/libcamera/formats.yaml',\n+                              'formats.h.in',\n+                              '../linux/drm_fourcc.h'\n+                          ),\n+                          output : 'formats.h',\n+                          command : [gen_formats, '-o', '@OUTPUT@', '@INPUT@'],\n+                          install : true,\n+                          install_dir : join_paths('include', include_dir))\n+libcamera_public_headers += formats_h\n+\n+# libcamera.h\n gen_header = files('gen-header.sh')\n \n libcamera_h = custom_target('gen-header',\n@@ -62,6 +83,7 @@ libcamera_h = custom_target('gen-header',\n \n libcamera_public_headers += libcamera_h\n \n+# version.h\n version = libcamera_version.split('.')\n libcamera_version_config = configuration_data()\n libcamera_version_config.set('LIBCAMERA_VERSION_MAJOR', version[0])\ndiff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp\nindex 2ac3b412ecdb..74c239a5e710 100644\n--- a/src/libcamera/formats.cpp\n+++ b/src/libcamera/formats.cpp\n@@ -12,7 +12,7 @@\n #include \"libcamera/internal/log.h\"\n \n /**\n- * \\file formats.h\n+ * \\file internal/formats.h\n  * \\brief Types and helper methods to handle libcamera image formats\n  */\n \ndiff --git a/src/libcamera/formats.yaml b/src/libcamera/formats.yaml\nnew file mode 100644\nindex 000000000000..a6841c618f93\n--- /dev/null\n+++ b/src/libcamera/formats.yaml\n@@ -0,0 +1,124 @@\n+# SPDX-License-Identifier: LGPL-2.1-or-later\n+#\n+# Copyright (C) 2020, Google Inc.\n+#\n+%YAML 1.2\n+---\n+formats:\n+  - R8:\n+      fourcc: DRM_FORMAT_R8\n+\n+  - RGB888:\n+      fourcc: DRM_FORMAT_RGB888\n+  - BGR888:\n+      fourcc: DRM_FORMAT_BGR888\n+\n+  - XRGB8888:\n+      fourcc: DRM_FORMAT_XRGB8888\n+  - XBGR8888:\n+      fourcc: DRM_FORMAT_XBGR8888\n+  - RGBX8888:\n+      fourcc: DRM_FORMAT_RGBX8888\n+  - BGRX8888:\n+      fourcc: DRM_FORMAT_BGRX8888\n+\n+  - ARGB8888:\n+      fourcc: DRM_FORMAT_ARGB8888\n+  - ABGR8888:\n+      fourcc: DRM_FORMAT_ABGR8888\n+  - RGBA8888:\n+      fourcc: DRM_FORMAT_RGBA8888\n+  - BGRA8888:\n+      fourcc: DRM_FORMAT_BGRA8888\n+\n+  - YUYV:\n+      fourcc: DRM_FORMAT_YUYV\n+  - YVYU:\n+      fourcc: DRM_FORMAT_YVYU\n+  - UYVY:\n+      fourcc: DRM_FORMAT_UYVY\n+  - VYUY:\n+      fourcc: DRM_FORMAT_VYUY\n+\n+  - NV12:\n+      fourcc: DRM_FORMAT_NV12\n+  - NV21:\n+      fourcc: DRM_FORMAT_NV21\n+  - NV16:\n+      fourcc: DRM_FORMAT_NV16\n+  - NV61:\n+      fourcc: DRM_FORMAT_NV61\n+  - NV24:\n+      fourcc: DRM_FORMAT_NV24\n+  - NV42:\n+      fourcc: DRM_FORMAT_NV42\n+\n+  - MJPEG:\n+      fourcc: DRM_FORMAT_MJPEG\n+\n+  - SRGGB8:\n+      fourcc: DRM_FORMAT_SRGGB8\n+  - SGRBG8:\n+      fourcc: DRM_FORMAT_SGRBG8\n+  - SGBRG8:\n+      fourcc: DRM_FORMAT_SGBRG8\n+  - SBGGR8:\n+      fourcc: DRM_FORMAT_SBGGR8\n+\n+  - SRGGB10:\n+      fourcc: DRM_FORMAT_SRGGB10\n+  - SGRBG10:\n+      fourcc: DRM_FORMAT_SGRBG10\n+  - SGBRG10:\n+      fourcc: DRM_FORMAT_SGBRG10\n+  - SBGGR10:\n+      fourcc: DRM_FORMAT_SBGGR10\n+\n+  - SRGGB12:\n+      fourcc: DRM_FORMAT_SRGGB12\n+  - SGRBG12:\n+      fourcc: DRM_FORMAT_SGRBG12\n+  - SGBRG12:\n+      fourcc: DRM_FORMAT_SGBRG12\n+  - SBGGR12:\n+      fourcc: DRM_FORMAT_SBGGR12\n+\n+  - SRGGB10_CSI2P:\n+      fourcc: DRM_FORMAT_SRGGB10\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+  - SGRBG10_CSI2P:\n+      fourcc: DRM_FORMAT_SGRBG10\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+  - SGBRG10_CSI2P:\n+      fourcc: DRM_FORMAT_SGBRG10\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+  - SBGGR10_CSI2P:\n+      fourcc: DRM_FORMAT_SBGGR10\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+\n+  - SRGGB12_CSI2P:\n+      fourcc: DRM_FORMAT_SRGGB12\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+  - SGRBG12_CSI2P:\n+      fourcc: DRM_FORMAT_SGRBG12\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+  - SGBRG12_CSI2P:\n+      fourcc: DRM_FORMAT_SGBRG12\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+  - SBGGR12_CSI2P:\n+      fourcc: DRM_FORMAT_SBGGR12\n+      mod: MIPI_FORMAT_MOD_CSI2_PACKED\n+\n+  - SRGGB10_IPU3:\n+      fourcc: DRM_FORMAT_SRGGB10\n+      mod: IPU3_FORMAT_MOD_PACKED\n+  - SGRBG10_IPU3:\n+      fourcc: DRM_FORMAT_SGRBG10\n+      mod: IPU3_FORMAT_MOD_PACKED\n+  - SGBRG10_IPU3:\n+      fourcc: DRM_FORMAT_SGBRG10\n+      mod: IPU3_FORMAT_MOD_PACKED\n+  - SBGGR10_IPU3:\n+      fourcc: DRM_FORMAT_SBGGR10\n+      mod: IPU3_FORMAT_MOD_PACKED\n+...\ndiff --git a/src/libcamera/pixel_format.cpp b/src/libcamera/pixel_format.cpp\nindex d501c5f09c6b..f191851ae22c 100644\n--- a/src/libcamera/pixel_format.cpp\n+++ b/src/libcamera/pixel_format.cpp\n@@ -5,6 +5,7 @@\n  * pixel_format.cpp - libcamera Pixel Format\n  */\n \n+#include <libcamera/formats.h>\n #include <libcamera/pixel_format.h>\n \n /**\n@@ -21,7 +22,8 @@ namespace libcamera {\n  * The PixelFormat type describes the format of images in the public libcamera\n  * API. It stores a FourCC value as a 32-bit unsigned integer and a modifier.\n  * The FourCC and modifier values are defined in the Linux kernel DRM/KMS API\n- * (see linux/drm_fourcc.h).\n+ * (see linux/drm_fourcc.h). Constant expressions for all pixel formats\n+ * supported by libcamera are available in libcamera/formats.h.\n  */\n \n /**\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "1/7"
    ]
}