Show a patch.

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

{
    "id": 19220,
    "url": "https://patchwork.libcamera.org/api/patches/19220/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/19220/",
    "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": "<20231121145350.5956-6-naush@raspberrypi.com>",
    "date": "2023-11-21T14:53:49",
    "name": "[libcamera-devel,v2,5/6] libcamera: controls: Use vendor tags for draft controls and properties",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "9c11620f6f218fcf3eea193cac0fff323b48b986",
    "submitter": {
        "id": 34,
        "url": "https://patchwork.libcamera.org/api/people/34/?format=api",
        "name": "Naushir Patuck",
        "email": "naush@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/19220/mbox/",
    "series": [
        {
            "id": 4077,
            "url": "https://patchwork.libcamera.org/api/series/4077/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4077",
            "date": "2023-11-21T14:53:44",
            "name": "Vendor controls and properties",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/4077/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/19220/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/19220/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 F3980C32B7\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 21 Nov 2023 14:54:03 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9830C61DB0;\n\tTue, 21 Nov 2023 15:54:03 +0100 (CET)",
            "from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com\n\t[IPv6:2a00:1450:4864:20::32d])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A8D1161DAE\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 Nov 2023 15:54:02 +0100 (CET)",
            "by mail-wm1-x32d.google.com with SMTP id\n\t5b1f17b1804b1-40b27726369so7144415e9.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 Nov 2023 06:54:02 -0800 (PST)",
            "from localhost.localdomain ([93.93.133.154])\n\tby smtp.gmail.com with ESMTPSA id\n\th18-20020a05600c351200b004063ea92492sm17570968wmq.22.2023.11.21.06.53.59\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 21 Nov 2023 06:54:00 -0800 (PST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1700578443;\n\tbh=j7Cv97qADJJB3EJTwpMI0i8b1TyMV7fh3AVKNS0kEI8=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=vGZ7wym3yW+ifDLUkGEc24jImgduhMHnx/jYSQuVgTBFUKGpxfgQijPN4oN3JW3C8\n\tBjcT4lGpGSDCdiHh18dRYPKrgGlI/B2j1mNbHcw/+uxjguC+rVoWNoHqwPmY3Mv/BE\n\twR744cQ28L7qSrrnu2IATUSNoOCiDqJwdyhagYncB0xXf7ElwuGxZHh24JiRRtNcC6\n\tNkI8KQ+1Ou3NfOjAoEUSKldq7tl/BNnRUgtd07yHxgXmXx6Zoc9wrqWd4ELxoCAOhu\n\tkQdthRVVeJA/BLMzwLSl3Xcov/ohN33HnEFwOknfxW0dqDsYkWPri9AQ8/z7L24rbu\n\th4xBGxoo0k2Mw==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1700578442; x=1701183242;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=ILqoDJ1URg6D1YBNyr6VpNtywrCixGglK53hUQ+03/E=;\n\tb=XxLeSdBFtjS0IWYMqRh0KFuqFqtwPKVsvQXcobxuTm9ekFTjr134/3ez15rH4hNxFN\n\tdyST2HwdeEH37sjhjsEHmRMB/qYY0vCArxrCKU2JqxmoKXJx8epA0Q4pCPUfoRNTEWCv\n\ts8E1ku/WaXLmJ/V7dRrqON8NH5Aq3ZYtPoKL/QQi+JBridRaFQtHxDdfuzRdtzRZ/xiG\n\tH00GmZgUtCSaAn7IiZPPNMWJyLuOBdY1vZmEGbyuhANBBD4tY2kbZuGLfB3+wwrfvIcT\n\tkMeP/hU7LzMUZQtHuK7CjbKGBJZuQ1XZR9pOxSw2/SFpMFC2uQxPywIuXRNdgida780W\n\t7Vow=="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"XxLeSdBF\"; dkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1700578442; x=1701183242;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=ILqoDJ1URg6D1YBNyr6VpNtywrCixGglK53hUQ+03/E=;\n\tb=KNs7KV9bnYqAKYhrVlHYInidLf1t8BUUpdxf5+/6ZyjxibGz9J7/Zo2Qo3P3HgaOEN\n\tnm0PINE02HQK9XVHD8SmxDxN0ondcjfH49xWqPGSBRZUTwK93mG1OM++eAQVg52KNFqQ\n\th7iPcM9OYxyPp3pkovc3Ea3GanZ7Tj5oTiHhtuBUrGLU+Phd41ATcp1zpmWnxGDT0jan\n\texjR4bcHP2HHzbiLmBz5/5992VZsmSCkzuJmy1OywG2IPEbJp7mTNcqvYBMJl8+XFdPj\n\tnAdGeVb7EZ2YhMtQuajSmO4a4Z8lSPe72M5GvMgUFZM8w5/O9MjAN2HQL5SOxmP0oVX7\n\t6M7A==",
        "X-Gm-Message-State": "AOJu0YwL2Zz4s8zpAI/QL/Gycnv8fGr0sjrZg31IAbAsclJzYSCb2zyP\n\t7KQy4hBTTRlyXl3UtZ5dxHUGGDwXIKFKbeAPlbaauA==",
        "X-Google-Smtp-Source": "AGHT+IFLQyiFWZcJG8hYgX6c6cX8oKPrnDP5lbCKQLbaxQvaazs6T9w5s5vs7aJJrMFvxcpyjsF9ZQ==",
        "X-Received": "by 2002:a05:600c:468c:b0:405:49aa:d578 with SMTP id\n\tp12-20020a05600c468c00b0040549aad578mr8208450wmo.37.1700578441498; \n\tTue, 21 Nov 2023 06:54:01 -0800 (PST)",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Tue, 21 Nov 2023 14:53:49 +0000",
        "Message-Id": "<20231121145350.5956-6-naush@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20231121145350.5956-1-naush@raspberrypi.com>",
        "References": "<20231121145350.5956-1-naush@raspberrypi.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v2 5/6] libcamera: controls: Use vendor\n\ttags for draft controls and properties",
        "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>",
        "From": "Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Naushir Patuck <naush@raspberrypi.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Label draft controls and properties through the \"draft\" vendor tag\nand deprecate the existing \"draft: true\" mechanism. This uses the new\nvendor tags mechanism to place draft controls in the same\nlibcamera::controls::draft namespace and provide a defined control id\nrange for these controls. This requires moving all draft controls from\ncontrol_ids.yaml to control_ids_draft.yaml.\n\nOne breaking change in this commit is that draft control ids also move\nto the libcamera::controls::draft namespace from the existing\nlibcamera::controls namespace. This is desirable to avoid API breakages\nwhen adding new libcamera controls. So, for example, the use of\ncontrols::NOISE_REDUCTION_MODE will need to be replaced with\ncontrols::draft::NOISE_REDUCTION_MODE.\n\nSigned-off-by: Naushir Patuck <naush@raspberrypi.com>\n---\n include/libcamera/control_ids.h.in            |   6 -\n include/libcamera/meson.build                 |   3 +-\n include/libcamera/property_ids.h.in           |   6 -\n src/ipa/rpi/common/ipa_base.cpp               |   2 +-\n src/ipa/rpi/vc4/vc4.cpp                       |   2 +-\n src/libcamera/control_ids.cpp.in              |  16 +-\n src/libcamera/control_ids.yaml                | 232 -----------------\n src/libcamera/control_ids_draft.yaml          | 240 ++++++++++++++++++\n src/libcamera/meson.build                     |   2 +-\n src/libcamera/property_ids.cpp.in             |  16 +-\n src/libcamera/property_ids.yaml               |  33 ---\n src/libcamera/property_ids_draft.yaml         |  39 +++\n src/py/libcamera/gen-py-controls.py           |   5 +-\n src/py/libcamera/meson.build                  |   6 +-\n src/py/libcamera/py_controls_generated.cpp.in |   5 -\n .../libcamera/py_properties_generated.cpp.in  |   3 +-\n utils/gen-controls.py                         |  39 +--\n 17 files changed, 303 insertions(+), 352 deletions(-)\n create mode 100644 src/libcamera/control_ids_draft.yaml\n create mode 100644 src/libcamera/property_ids_draft.yaml",
    "diff": "diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\nindex c97b09a82450..d53b1cf7beb2 100644\n--- a/include/libcamera/control_ids.h.in\n+++ b/include/libcamera/control_ids.h.in\n@@ -26,12 +26,6 @@ ${controls}\n \n extern const ControlIdMap controls;\n \n-namespace draft {\n-\n-${draft_controls}\n-\n-} /* namespace draft */\n-\n ${vendor_controls}\n \n } /* namespace controls */\ndiff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\nindex 6cac385fdee4..63fc120a0818 100644\n--- a/include/libcamera/meson.build\n+++ b/include/libcamera/meson.build\n@@ -76,7 +76,8 @@ foreach header, mode : control_source_files\n         vendor_prop_files = vendor_files\n     endif\n \n-    input_files = files('../../src/libcamera/' + header + '.yaml')\n+    input_files = files(['../../src/libcamera/' + header +'.yaml',\n+                         '../../src/libcamera/' + header +'_draft.yaml'])\n \n     foreach file : vendor_files\n         input_files += files('../../src/libcamera/' + file)\ndiff --git a/include/libcamera/property_ids.h.in b/include/libcamera/property_ids.h.in\nindex 47c5d6bf2e28..43372c718fc9 100644\n--- a/include/libcamera/property_ids.h.in\n+++ b/include/libcamera/property_ids.h.in\n@@ -23,12 +23,6 @@ ${ids}\n \n ${controls}\n \n-namespace draft {\n-\n-${draft_controls}\n-\n-} /* namespace draft */\n-\n extern const ControlIdMap properties;\n \n ${vendor_controls}\ndiff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp\nindex a1fec3aa3dd1..6ac9d5de2f88 100644\n--- a/src/ipa/rpi/common/ipa_base.cpp\n+++ b/src/ipa/rpi/common/ipa_base.cpp\n@@ -1024,7 +1024,7 @@ void IpaBase::applyControls(const ControlList &controls)\n \t\t\tbreak;\n \t\t}\n \n-\t\tcase controls::NOISE_REDUCTION_MODE:\n+\t\tcase controls::draft::NOISE_REDUCTION_MODE:\n \t\t\t/* Handled below in handleControls() */\n \t\t\tlibcameraMetadata_.set(controls::draft::NoiseReductionMode,\n \t\t\t\t\t       ctrl.second.get<int32_t>());\ndiff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp\nindex c4baf04fb1e7..c165a5b8b0b6 100644\n--- a/src/ipa/rpi/vc4/vc4.cpp\n+++ b/src/ipa/rpi/vc4/vc4.cpp\n@@ -260,7 +260,7 @@ void IpaVc4::handleControls(const ControlList &controls)\n \n \tfor (auto const &ctrl : controls) {\n \t\tswitch (ctrl.first) {\n-\t\tcase controls::NOISE_REDUCTION_MODE: {\n+\t\tcase controls::draft::NOISE_REDUCTION_MODE: {\n \t\t\tRPiController::DenoiseAlgorithm *sdn = dynamic_cast<RPiController::DenoiseAlgorithm *>(\n \t\t\t\tcontroller_.getAlgorithm(\"SDN\"));\n \t\t\t/* Some platforms may have a combined \"denoise\" algorithm instead. */\ndiff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in\nindex d26eb930b30c..284589567cfb 100644\n--- a/src/libcamera/control_ids.cpp.in\n+++ b/src/libcamera/control_ids.cpp.in\n@@ -24,15 +24,6 @@ namespace controls {\n \n ${controls_doc}\n \n-/**\n- * \\brief Namespace for libcamera draft controls\n- */\n-namespace draft {\n-\n-${draft_controls_doc}\n-\n-} /* namespace draft */\n-\n ${vendor_controls_doc}\n \n #ifndef __DOXYGEN__\n@@ -42,13 +33,8 @@ ${vendor_controls_doc}\n  */\n ${controls_def}\n \n-namespace draft {\n-\n-${draft_controls_def}\n-\n-} /* namespace draft */\n-\n ${vendor_controls_def}\n+\n #endif\n \n /**\ndiff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml\nindex ff74ce1deedb..76fb9347d8e3 100644\n--- a/src/libcamera/control_ids.yaml\n+++ b/src/libcamera/control_ids.yaml\n@@ -865,236 +865,4 @@ controls:\n           description: |\n             This is a long exposure image.\n \n-  # ----------------------------------------------------------------------------\n-  # Draft controls section\n-\n-  - AePrecaptureTrigger:\n-      type: int32_t\n-      draft: true\n-      description: |\n-        Control for AE metering trigger. Currently identical to\n-        ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER.\n-\n-        Whether the camera device will trigger a precapture metering sequence\n-        when it processes this request.\n-      enum:\n-        - name: AePrecaptureTriggerIdle\n-          value: 0\n-          description: The trigger is idle.\n-        - name: AePrecaptureTriggerStart\n-          value: 1\n-          description: The pre-capture AE metering is started by the camera.\n-        - name: AePrecaptureTriggerCancel\n-          value: 2\n-          description: |\n-            The camera will cancel any active or completed metering sequence.\n-            The AE algorithm is reset to its initial state.\n-\n-  - NoiseReductionMode:\n-      type: int32_t\n-      draft: true\n-      description: |\n-       Control to select the noise reduction algorithm mode. Currently\n-       identical to ANDROID_NOISE_REDUCTION_MODE.\n-\n-        Mode of operation for the noise reduction algorithm.\n-      enum:\n-        - name: NoiseReductionModeOff\n-          value: 0\n-          description: No noise reduction is applied\n-        - name: NoiseReductionModeFast\n-          value: 1\n-          description: |\n-            Noise reduction is applied without reducing the frame rate.\n-        - name: NoiseReductionModeHighQuality\n-          value: 2\n-          description: |\n-            High quality noise reduction at the expense of frame rate.\n-        - name: NoiseReductionModeMinimal\n-          value: 3\n-          description: |\n-            Minimal noise reduction is applied without reducing the frame rate.\n-        - name: NoiseReductionModeZSL\n-          value: 4\n-          description: |\n-            Noise reduction is applied at different levels to different streams.\n-\n-  - ColorCorrectionAberrationMode:\n-      type: int32_t\n-      draft: true\n-      description: |\n-       Control to select the color correction aberration mode. Currently\n-       identical to ANDROID_COLOR_CORRECTION_ABERRATION_MODE.\n-\n-        Mode of operation for the chromatic aberration correction algorithm.\n-      enum:\n-        - name: ColorCorrectionAberrationOff\n-          value: 0\n-          description: No aberration correction is applied.\n-        - name: ColorCorrectionAberrationFast\n-          value: 1\n-          description: Aberration correction will not slow down the frame rate.\n-        - name: ColorCorrectionAberrationHighQuality\n-          value: 2\n-          description: |\n-            High quality aberration correction which might reduce the frame\n-            rate.\n-\n-  - AeState:\n-      type: int32_t\n-      draft: true\n-      description: |\n-       Control to report the current AE algorithm state. Currently identical to\n-       ANDROID_CONTROL_AE_STATE.\n-\n-        Current state of the AE algorithm.\n-      enum:\n-        - name: AeStateInactive\n-          value: 0\n-          description: The AE algorithm is inactive.\n-        - name: AeStateSearching\n-          value: 1\n-          description: The AE algorithm has not converged yet.\n-        - name: AeStateConverged\n-          value: 2\n-          description: The AE algorithm has converged.\n-        - name: AeStateLocked\n-          value: 3\n-          description: The AE algorithm is locked.\n-        - name: AeStateFlashRequired\n-          value: 4\n-          description: The AE algorithm would need a flash for good results\n-        - name: AeStatePrecapture\n-          value: 5\n-          description: |\n-            The AE algorithm has started a pre-capture metering session.\n-            \\sa AePrecaptureTrigger\n-\n-  - AwbState:\n-      type: int32_t\n-      draft: true\n-      description: |\n-       Control to report the current AWB algorithm state. Currently identical\n-       to ANDROID_CONTROL_AWB_STATE.\n-\n-        Current state of the AWB algorithm.\n-      enum:\n-        - name: AwbStateInactive\n-          value: 0\n-          description: The AWB algorithm is inactive.\n-        - name: AwbStateSearching\n-          value: 1\n-          description: The AWB algorithm has not converged yet.\n-        - name: AwbConverged\n-          value: 2\n-          description: The AWB algorithm has converged.\n-        - name: AwbLocked\n-          value: 3\n-          description: The AWB algorithm is locked.\n-\n-  - SensorRollingShutterSkew:\n-      type: int64_t\n-      draft: true\n-      description: |\n-       Control to report the time between the start of exposure of the first\n-       row and the start of exposure of the last row. Currently identical to\n-       ANDROID_SENSOR_ROLLING_SHUTTER_SKEW\n-\n-  - LensShadingMapMode:\n-      type: int32_t\n-      draft: true\n-      description: |\n-       Control to report if the lens shading map is available. Currently\n-       identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE.\n-      enum:\n-        - name: LensShadingMapModeOff\n-          value: 0\n-          description: No lens shading map mode is available.\n-        - name: LensShadingMapModeOn\n-          value: 1\n-          description: The lens shading map mode is available.\n-\n-  - PipelineDepth:\n-      type: int32_t\n-      draft: true\n-      description: |\n-        Specifies the number of pipeline stages the frame went through from when\n-        it was exposed to when the final completed result was available to the\n-        framework. Always less than or equal to PipelineMaxDepth. Currently\n-        identical to ANDROID_REQUEST_PIPELINE_DEPTH.\n-\n-        The typical value for this control is 3 as a frame is first exposed,\n-        captured and then processed in a single pass through the ISP. Any\n-        additional processing step performed after the ISP pass (in example face\n-        detection, additional format conversions etc) count as an additional\n-        pipeline stage.\n-\n-  - MaxLatency:\n-      type: int32_t\n-      draft: true\n-      description: |\n-        The maximum number of frames that can occur after a request (different\n-        than the previous) has been submitted, and before the result's state\n-        becomes synchronized. A value of -1 indicates unknown latency, and 0\n-        indicates per-frame control. Currently identical to\n-        ANDROID_SYNC_MAX_LATENCY.\n-\n-  - TestPatternMode:\n-      type: int32_t\n-      draft: true\n-      description: |\n-        Control to select the test pattern mode. Currently identical to\n-        ANDROID_SENSOR_TEST_PATTERN_MODE.\n-      enum:\n-        - name: TestPatternModeOff\n-          value: 0\n-          description: |\n-            No test pattern mode is used. The camera device returns frames from\n-            the image sensor.\n-        - name: TestPatternModeSolidColor\n-          value: 1\n-          description: |\n-            Each pixel in [R, G_even, G_odd, B] is replaced by its respective\n-            color channel provided in test pattern data.\n-            \\todo Add control for test pattern data.\n-        - name: TestPatternModeColorBars\n-          value: 2\n-          description: |\n-            All pixel data is replaced with an 8-bar color pattern. The vertical\n-            bars (left-to-right) are as follows; white, yellow, cyan, green,\n-            magenta, red, blue and black. Each bar should take up 1/8 of the\n-            sensor pixel array width. When this is not possible, the bar size\n-            should be rounded down to the nearest integer and the pattern can\n-            repeat on the right side. Each bar's height must always take up the\n-            full sensor pixel array height.\n-        - name: TestPatternModeColorBarsFadeToGray\n-          value: 3\n-          description: |\n-            The test pattern is similar to TestPatternModeColorBars,\n-            except that each bar should start at its specified color at the top\n-            and fade to gray at the bottom. Furthermore each bar is further\n-            subdevided into a left and right half. The left half should have a\n-            smooth gradient, and the right half should have a quantized\n-            gradient. In particular, the right half's should consist of blocks\n-            of the same color for 1/16th active sensor pixel array width. The\n-            least significant bits in the quantized gradient should be copied\n-            from the most significant bits of the smooth gradient. The height of\n-            each bar should always be a multiple of 128. When this is not the\n-            case, the pattern should repeat at the bottom of the image.\n-        - name: TestPatternModePn9\n-          value: 4\n-          description: |\n-            All pixel data is replaced by a pseudo-random sequence generated\n-            from a PN9 512-bit sequence (typically implemented in hardware with\n-            a linear feedback shift register). The generator should be reset at\n-            the beginning of each frame, and thus each subsequent raw frame with\n-            this test pattern should be exactly the same as the last.\n-        - name: TestPatternModeCustom1\n-          value: 256\n-          description: |\n-            The first custom test pattern. All custom patterns that are\n-            available only on this camera device are at least this numeric\n-            value. All of the custom test patterns will be static (that is the\n-            raw image must not vary from frame to frame).\n-\n ...\ndiff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml\nnew file mode 100644\nindex 000000000000..e4f53ea51d7a\n--- /dev/null\n+++ b/src/libcamera/control_ids_draft.yaml\n@@ -0,0 +1,240 @@\n+# SPDX-License-Identifier: LGPL-2.1-or-later\n+#\n+# Copyright (C) 2019, Google Inc.\n+#\n+%YAML 1.1\n+---\n+# Unless otherwise stated, all controls are bi-directional, i.e. they can be\n+# set through Request::controls() and returned out through Request::metadata().\n+vendor: draft\n+controls:\n+  - AePrecaptureTrigger:\n+      type: int32_t\n+      draft: true\n+      description: |\n+        Control for AE metering trigger. Currently identical to\n+        ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER.\n+\n+        Whether the camera device will trigger a precapture metering sequence\n+        when it processes this request.\n+      enum:\n+        - name: AePrecaptureTriggerIdle\n+          value: 0\n+          description: The trigger is idle.\n+        - name: AePrecaptureTriggerStart\n+          value: 1\n+          description: The pre-capture AE metering is started by the camera.\n+        - name: AePrecaptureTriggerCancel\n+          value: 2\n+          description: |\n+            The camera will cancel any active or completed metering sequence.\n+            The AE algorithm is reset to its initial state.\n+\n+  - NoiseReductionMode:\n+      type: int32_t\n+      draft: true\n+      description: |\n+       Control to select the noise reduction algorithm mode. Currently\n+       identical to ANDROID_NOISE_REDUCTION_MODE.\n+\n+        Mode of operation for the noise reduction algorithm.\n+      enum:\n+        - name: NoiseReductionModeOff\n+          value: 0\n+          description: No noise reduction is applied\n+        - name: NoiseReductionModeFast\n+          value: 1\n+          description: |\n+            Noise reduction is applied without reducing the frame rate.\n+        - name: NoiseReductionModeHighQuality\n+          value: 2\n+          description: |\n+            High quality noise reduction at the expense of frame rate.\n+        - name: NoiseReductionModeMinimal\n+          value: 3\n+          description: |\n+            Minimal noise reduction is applied without reducing the frame rate.\n+        - name: NoiseReductionModeZSL\n+          value: 4\n+          description: |\n+            Noise reduction is applied at different levels to different streams.\n+\n+  - ColorCorrectionAberrationMode:\n+      type: int32_t\n+      draft: true\n+      description: |\n+       Control to select the color correction aberration mode. Currently\n+       identical to ANDROID_COLOR_CORRECTION_ABERRATION_MODE.\n+\n+        Mode of operation for the chromatic aberration correction algorithm.\n+      enum:\n+        - name: ColorCorrectionAberrationOff\n+          value: 0\n+          description: No aberration correction is applied.\n+        - name: ColorCorrectionAberrationFast\n+          value: 1\n+          description: Aberration correction will not slow down the frame rate.\n+        - name: ColorCorrectionAberrationHighQuality\n+          value: 2\n+          description: |\n+            High quality aberration correction which might reduce the frame\n+            rate.\n+\n+  - AeState:\n+      type: int32_t\n+      draft: true\n+      description: |\n+       Control to report the current AE algorithm state. Currently identical to\n+       ANDROID_CONTROL_AE_STATE.\n+\n+        Current state of the AE algorithm.\n+      enum:\n+        - name: AeStateInactive\n+          value: 0\n+          description: The AE algorithm is inactive.\n+        - name: AeStateSearching\n+          value: 1\n+          description: The AE algorithm has not converged yet.\n+        - name: AeStateConverged\n+          value: 2\n+          description: The AE algorithm has converged.\n+        - name: AeStateLocked\n+          value: 3\n+          description: The AE algorithm is locked.\n+        - name: AeStateFlashRequired\n+          value: 4\n+          description: The AE algorithm would need a flash for good results\n+        - name: AeStatePrecapture\n+          value: 5\n+          description: |\n+            The AE algorithm has started a pre-capture metering session.\n+            \\sa AePrecaptureTrigger\n+\n+  - AwbState:\n+      type: int32_t\n+      draft: true\n+      description: |\n+       Control to report the current AWB algorithm state. Currently identical\n+       to ANDROID_CONTROL_AWB_STATE.\n+\n+        Current state of the AWB algorithm.\n+      enum:\n+        - name: AwbStateInactive\n+          value: 0\n+          description: The AWB algorithm is inactive.\n+        - name: AwbStateSearching\n+          value: 1\n+          description: The AWB algorithm has not converged yet.\n+        - name: AwbConverged\n+          value: 2\n+          description: The AWB algorithm has converged.\n+        - name: AwbLocked\n+          value: 3\n+          description: The AWB algorithm is locked.\n+\n+  - SensorRollingShutterSkew:\n+      type: int64_t\n+      draft: true\n+      description: |\n+       Control to report the time between the start of exposure of the first\n+       row and the start of exposure of the last row. Currently identical to\n+       ANDROID_SENSOR_ROLLING_SHUTTER_SKEW\n+\n+  - LensShadingMapMode:\n+      type: int32_t\n+      draft: true\n+      description: |\n+       Control to report if the lens shading map is available. Currently\n+       identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE.\n+      enum:\n+        - name: LensShadingMapModeOff\n+          value: 0\n+          description: No lens shading map mode is available.\n+        - name: LensShadingMapModeOn\n+          value: 1\n+          description: The lens shading map mode is available.\n+\n+  - PipelineDepth:\n+      type: int32_t\n+      draft: true\n+      description: |\n+        Specifies the number of pipeline stages the frame went through from when\n+        it was exposed to when the final completed result was available to the\n+        framework. Always less than or equal to PipelineMaxDepth. Currently\n+        identical to ANDROID_REQUEST_PIPELINE_DEPTH.\n+\n+        The typical value for this control is 3 as a frame is first exposed,\n+        captured and then processed in a single pass through the ISP. Any\n+        additional processing step performed after the ISP pass (in example face\n+        detection, additional format conversions etc) count as an additional\n+        pipeline stage.\n+\n+  - MaxLatency:\n+      type: int32_t\n+      draft: true\n+      description: |\n+        The maximum number of frames that can occur after a request (different\n+        than the previous) has been submitted, and before the result's state\n+        becomes synchronized. A value of -1 indicates unknown latency, and 0\n+        indicates per-frame control. Currently identical to\n+        ANDROID_SYNC_MAX_LATENCY.\n+\n+  - TestPatternMode:\n+      type: int32_t\n+      draft: true\n+      description: |\n+        Control to select the test pattern mode. Currently identical to\n+        ANDROID_SENSOR_TEST_PATTERN_MODE.\n+      enum:\n+        - name: TestPatternModeOff\n+          value: 0\n+          description: |\n+            No test pattern mode is used. The camera device returns frames from\n+            the image sensor.\n+        - name: TestPatternModeSolidColor\n+          value: 1\n+          description: |\n+            Each pixel in [R, G_even, G_odd, B] is replaced by its respective\n+            color channel provided in test pattern data.\n+            \\todo Add control for test pattern data.\n+        - name: TestPatternModeColorBars\n+          value: 2\n+          description: |\n+            All pixel data is replaced with an 8-bar color pattern. The vertical\n+            bars (left-to-right) are as follows; white, yellow, cyan, green,\n+            magenta, red, blue and black. Each bar should take up 1/8 of the\n+            sensor pixel array width. When this is not possible, the bar size\n+            should be rounded down to the nearest integer and the pattern can\n+            repeat on the right side. Each bar's height must always take up the\n+            full sensor pixel array height.\n+        - name: TestPatternModeColorBarsFadeToGray\n+          value: 3\n+          description: |\n+            The test pattern is similar to TestPatternModeColorBars,\n+            except that each bar should start at its specified color at the top\n+            and fade to gray at the bottom. Furthermore each bar is further\n+            subdevided into a left and right half. The left half should have a\n+            smooth gradient, and the right half should have a quantized\n+            gradient. In particular, the right half's should consist of blocks\n+            of the same color for 1/16th active sensor pixel array width. The\n+            least significant bits in the quantized gradient should be copied\n+            from the most significant bits of the smooth gradient. The height of\n+            each bar should always be a multiple of 128. When this is not the\n+            case, the pattern should repeat at the bottom of the image.\n+        - name: TestPatternModePn9\n+          value: 4\n+          description: |\n+            All pixel data is replaced by a pseudo-random sequence generated\n+            from a PN9 512-bit sequence (typically implemented in hardware with\n+            a linear feedback shift register). The generator should be reset at\n+            the beginning of each frame, and thus each subsequent raw frame with\n+            this test pattern should be exactly the same as the last.\n+        - name: TestPatternModeCustom1\n+          value: 256\n+          description: |\n+            The first custom test pattern. All custom patterns that are\n+            available only on this camera device are at least this numeric\n+            value. All of the custom test patterns will be static (that is the\n+            raw image must not vary from frame to frame).\n+\n+...\ndiff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\nindex 303eee84a77e..e965b72e015a 100644\n--- a/src/libcamera/meson.build\n+++ b/src/libcamera/meson.build\n@@ -128,7 +128,7 @@ endif\n control_sources = []\n \n foreach source, mode : control_source_files\n-    input_files = files(source +'.yaml')\n+    input_files = files([source +'.yaml', source + '_draft.yaml'])\n \n     # Add the vendor specific files to the input.\n     if mode == 'controls'\ndiff --git a/src/libcamera/property_ids.cpp.in b/src/libcamera/property_ids.cpp.in\nindex ddbe714c3f00..b72e12e4cc70 100644\n--- a/src/libcamera/property_ids.cpp.in\n+++ b/src/libcamera/property_ids.cpp.in\n@@ -23,14 +23,7 @@ namespace properties {\n \n ${controls_doc}\n \n-/**\n- * \\brief Namespace for libcamera draft properties\n- */\n-namespace draft {\n-\n-${draft_controls_doc}\n-\n-} /* namespace draft */\n+${vendor_controls_doc}\n \n ${vendor_controls_doc}\n \n@@ -41,13 +34,8 @@ ${vendor_controls_doc}\n  */\n ${controls_def}\n \n-namespace draft {\n-\n-${draft_controls_def}\n-\n-} /* namespace draft */\n-\n ${vendor_controls_def}\n+\n #endif\n \n /**\ndiff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml\nindex 45f3609b4236..834454a4e087 100644\n--- a/src/libcamera/property_ids.yaml\n+++ b/src/libcamera/property_ids.yaml\n@@ -701,37 +701,4 @@ controls:\n \n         Different cameras may report identical devices.\n \n-  # ----------------------------------------------------------------------------\n-  # Draft properties section\n-\n-  - ColorFilterArrangement:\n-      type: int32_t\n-      draft: true\n-      description: |\n-        The arrangement of color filters on sensor; represents the colors in the\n-        top-left 2x2 section of the sensor, in reading order. Currently\n-        identical to ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT.\n-      enum:\n-        - name: RGGB\n-          value: 0\n-          description: RGGB Bayer pattern\n-        - name: GRBG\n-          value: 1\n-          description: GRBG Bayer pattern\n-        - name: GBRG\n-          value: 2\n-          description: GBRG Bayer pattern\n-        - name: BGGR\n-          value: 3\n-          description: BGGR Bayer pattern\n-        - name: RGB\n-          value: 4\n-          description: |\n-            Sensor is not Bayer; output has 3 16-bit values for each pixel,\n-            instead of just 1 16-bit value per pixel.\n-        - name: MONO\n-          value: 5\n-          description: |\n-            Sensor is not Bayer; output consists of a single colour channel.\n-\n ...\ndiff --git a/src/libcamera/property_ids_draft.yaml b/src/libcamera/property_ids_draft.yaml\nnew file mode 100644\nindex 000000000000..62f0e242d0c6\n--- /dev/null\n+++ b/src/libcamera/property_ids_draft.yaml\n@@ -0,0 +1,39 @@\n+# SPDX-License-Identifier: LGPL-2.1-or-later\n+#\n+# Copyright (C) 2019, Google Inc.\n+#\n+%YAML 1.1\n+---\n+vendor: draft\n+controls:\n+  - ColorFilterArrangement:\n+      type: int32_t\n+      vendor: draft\n+      description: |\n+        The arrangement of color filters on sensor; represents the colors in the\n+        top-left 2x2 section of the sensor, in reading order. Currently\n+        identical to ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT.\n+      enum:\n+        - name: RGGB\n+          value: 0\n+          description: RGGB Bayer pattern\n+        - name: GRBG\n+          value: 1\n+          description: GRBG Bayer pattern\n+        - name: GBRG\n+          value: 2\n+          description: GBRG Bayer pattern\n+        - name: BGGR\n+          value: 3\n+          description: BGGR Bayer pattern\n+        - name: RGB\n+          value: 4\n+          description: |\n+            Sensor is not Bayer; output has 3 16-bit values for each pixel,\n+            instead of just 1 16-bit value per pixel.\n+        - name: MONO\n+          value: 5\n+          description: |\n+            Sensor is not Bayer; output consists of a single colour channel.\n+\n+...\ndiff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py\nindex e2ddad8581fd..e0695635dbcc 100755\n--- a/src/py/libcamera/gen-py-controls.py\n+++ b/src/py/libcamera/gen-py-controls.py\n@@ -36,10 +36,7 @@ def generate_py(controls, mode):\n                 vendor_defs.append('\\tauto {} = py::class_<Py{}Controls>(controls, \\\"{}\\\");'.format(vendor, vendor, vendor))\n                 vendors.append(vendor)\n \n-            if ctrl.get('draft'):\n-                ns = 'libcamera::{}::draft::'.format(mode)\n-                container = 'draft'\n-            elif vendor != 'libcamera':\n+            if vendor != 'libcamera':\n                 ns = 'libcamera::{}::{}::'.format(mode, vendor)\n                 container = vendor\n             else:\ndiff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build\nindex ea38ad6ca829..9641862a4e9b 100644\n--- a/src/py/libcamera/meson.build\n+++ b/src/py/libcamera/meson.build\n@@ -28,7 +28,8 @@ pycamera_sources = files([\n \n # Generate controls\n \n-gen_py_controls_input_files = files('../../libcamera/control_ids.yaml')\n+gen_py_controls_input_files = files(['../../libcamera/control_ids.yaml',\n+                                     '../../libcamera/control_ids_draft.yaml'])\n gen_py_controls_template = files('py_controls_generated.cpp.in')\n \n gen_py_controls = files('gen-py-controls.py')\n@@ -45,7 +46,8 @@ pycamera_sources += custom_target('py_gen_controls',\n \n # Generate properties\n \n-gen_py_property_enums_input_files = files('../../libcamera/property_ids.yaml')\n+gen_py_property_enums_input_files = files(['../../libcamera/property_ids.yaml',\n+                                           '../../libcamera/property_ids_draft.yaml'])\n gen_py_properties_template = files('py_properties_generated.cpp.in')\n \n foreach file : vendor_prop_files\ndiff --git a/src/py/libcamera/py_controls_generated.cpp.in b/src/py/libcamera/py_controls_generated.cpp.in\nindex ec4b55ef2011..8d282ce51856 100644\n--- a/src/py/libcamera/py_controls_generated.cpp.in\n+++ b/src/py/libcamera/py_controls_generated.cpp.in\n@@ -17,16 +17,11 @@ class PyControls\n {\n };\n \n-class PyDraftControls\n-{\n-};\n-\n ${vendors_class_def}\n \n void init_py_controls_generated(py::module& m)\n {\n \tauto controls = py::class_<PyControls>(m, \"controls\");\n-\tauto draft = py::class_<PyDraftControls>(controls, \"draft\");\n ${vendors_defs}\n \n ${controls}\ndiff --git a/src/py/libcamera/py_properties_generated.cpp.in b/src/py/libcamera/py_properties_generated.cpp.in\nindex f7b5ec8c635d..1fa1967a9672 100644\n--- a/src/py/libcamera/py_properties_generated.cpp.in\n+++ b/src/py/libcamera/py_properties_generated.cpp.in\n@@ -26,8 +26,7 @@ ${vendors_class_def}\n void init_py_properties_generated(py::module& m)\n {\n \tauto controls = py::class_<PyProperties>(m, \"properties\");\n-\tauto draft = py::class_<PyDraftProperties>(controls, \"draft\");\n-${vendors_defs}\n+${vendors_defs}\t\n \n ${controls}\n }\ndiff --git a/utils/gen-controls.py b/utils/gen-controls.py\nindex 9eede8940f24..f20e4eafcc2f 100755\n--- a/utils/gen-controls.py\n+++ b/utils/gen-controls.py\n@@ -85,11 +85,6 @@ class Control(object):\n         \"\"\"Is the control an enumeration\"\"\"\n         return self.__enum_values is not None\n \n-    @property\n-    def is_draft(self):\n-        \"\"\"Is the control a draft control\"\"\"\n-        return self.__data.get('draft') is not None\n-\n     @property\n     def vendor(self):\n         \"\"\"The vendor string, or None\"\"\"\n@@ -100,12 +95,6 @@ class Control(object):\n         \"\"\"The control name (CamelCase)\"\"\"\n         return self.__name\n \n-    @property\n-    def q_name(self):\n-        \"\"\"The control name, qualified with a namespace\"\"\"\n-        ns = 'draft::' if self.is_draft else ''\n-        return ns + self.__name\n-\n     @property\n     def type(self):\n         typ = self.__data.get('type')\n@@ -158,7 +147,7 @@ ${description}\n     for ctrl in controls:\n         id_name = snake_case(ctrl.name).upper()\n \n-        vendor = 'draft' if ctrl.is_draft else ctrl.vendor\n+        vendor = ctrl.vendor\n         if vendor not in ctrls_doc:\n             ctrls_doc[vendor] = []\n             ctrls_def[vendor] = []\n@@ -209,7 +198,7 @@ ${description}\n         target_doc.append(doc_template.substitute(info))\n         target_def.append(def_template.substitute(info))\n \n-        target_ctrls_map.append('\\t{ ' + id_name + ', &' + ctrl.q_name + ' },')\n+        target_ctrls_map.append('\\t{ ' + id_name + ', &' + ctrl.name + ' },')\n \n     vendor_ctrl_doc_sub = []\n     vendor_ctrl_template = string.Template('''\n@@ -219,11 +208,11 @@ ${vendor_controls_str}\n \n } /* namespace ${vendor} */''')\n \n-    for vendor in [v for v in ctrls_map.keys() if v not in ['libcamera', 'draft']]:\n+    for vendor in [v for v in ctrls_map.keys() if v != 'libcamera']:\n         vendor_ctrl_doc_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\\n\\n'.join(ctrls_doc[vendor])}))\n \n     vendor_ctrl_def_sub = []\n-    for vendor in [v for v in ctrls_map.keys() if v not in ['libcamera', 'draft']]:\n+    for vendor in [v for v in ctrls_map.keys() if v != 'libcamera']:\n         vendor_ctrl_def_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\\n'.join(ctrls_def[vendor])}))\n \n     vendor_ctrl_map_sub = []\n@@ -241,16 +230,14 @@ ${vendor_controls_map}\n } /* namespace ${vendor} */\n ''')\n \n-    for vendor in [v for v in ctrls_map.keys() if v not in ['libcamera', 'draft']]:\n+    for vendor in [v for v in ctrls_map.keys() if v != 'libcamera']:\n         vendor_ctrl_map_sub.append(vendor_ctrl_template.substitute({'vendor': vendor,\n                                                                     'vendor_controls_map': '\\n'.join(ctrls_map[vendor])}))\n \n     return {\n         'controls_doc': '\\n\\n'.join(ctrls_doc['libcamera']),\n         'controls_def': '\\n'.join(ctrls_def['libcamera']),\n-        'draft_controls_doc': '\\n\\n'.join(ctrls_doc['draft']),\n-        'draft_controls_def': '\\n\\n'.join(ctrls_def['draft']),\n-        'controls_map': '\\n'.join(ctrls_map['libcamera'] + ctrls_map['draft']),\n+        'controls_map': '\\n'.join(ctrls_map['libcamera']),\n         'vendor_controls_doc': '\\n'.join(vendor_ctrl_doc_sub),\n         'vendor_controls_def': '\\n'.join(vendor_ctrl_def_sub),\n         'vendor_controls_map': '\\n'.join(vendor_ctrl_map_sub),\n@@ -270,7 +257,7 @@ def generate_h(controls, mode, ranges):\n     for ctrl in controls:\n         id_name = snake_case(ctrl.name).upper()\n \n-        vendor = 'draft' if ctrl.is_draft else ctrl.vendor\n+        vendor = ctrl.vendor\n         if vendor not in ctrls:\n             if vendor not in ranges.keys():\n                 raise RuntimeError(f'Control id range is not defined for vendor {vendor}')\n@@ -278,8 +265,7 @@ def generate_h(controls, mode, ranges):\n             ids[vendor] = []\n             ctrls[vendor] = []\n \n-        # Core and draft controls use the same ID value\n-        target_ids = ids['libcamera'] if vendor in ['libcamera', 'draft'] else ids[vendor]\n+        target_ids = ids[vendor]\n         target_ids.append('\\t' + id_name + ' = ' + str(id_value[vendor]) + ',')\n \n         info = {\n@@ -287,11 +273,7 @@ def generate_h(controls, mode, ranges):\n             'type': ctrl.type,\n         }\n \n-        target_ctrls = ctrls['libcamera']\n-        if ctrl.is_draft:\n-            target_ctrls = ctrls['draft']\n-        elif vendor != 'libcamera':\n-            target_ctrls = ctrls[vendor]\n+        target_ctrls = ctrls[vendor]\n \n         if ctrl.is_enum:\n             target_ctrls.append(enum_template_start.substitute(info))\n@@ -332,7 +314,7 @@ ${vendor_controls}\n ''')\n \n     vendor_sub = []\n-    for vendor in [v for v in ctrls.keys() if v not in ['libcamera', 'draft']]:\n+    for vendor in [v for v in ctrls.keys() if v != 'libcamera']:\n         vendor_sub.append(vendor_template.substitute({'mode': mode.upper(),\n                                                       'vendor': vendor,\n                                                       'vendor_def': vendor.upper(),\n@@ -342,7 +324,6 @@ ${vendor_controls}\n     return {\n         'ids': '\\n'.join(ids['libcamera']),\n         'controls': '\\n'.join(ctrls['libcamera']),\n-        'draft_controls': '\\n'.join(ctrls['draft']),\n         'vendor_controls': '\\n'.join(vendor_sub)\n     }\n \n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "5/6"
    ]
}