From patchwork Thu Nov 30 14:25:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 19253 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7A02EC31E9 for ; Thu, 30 Nov 2023 14:25:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 268C9629CD; Thu, 30 Nov 2023 15:25:50 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1701354350; bh=OfkS80bDxpPLiQFo7/s2nNGfbJprdOgu2A0lUVDzufQ=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=reQ5cNj8yeOVHvtTqW2PFV+5/0udZ1RDyk8y34cRkji6XqFrZ34hiGjuQKgGGWKvF 6GdGGGrHG/fQ2ntRFa0qQmIrYQ/SMq49o53ISvw2tBZNwNU04NkDrvXOJhbPT5RtgK eGCT3ZiMnv2qO8u882jALHaxJ7Jlqgyt5UiODZuu8vT32Y35aqomFCuBDvXsd2cEOm C1KMO9mnLsyRUsq0Hvgz+tr/0N9NDXJdmXbBOYZ4b7fKZ7uDLOSXN/uZLnSS5PSlIn Gv29LTt+CRiGY0XRenf8R4oAVJHDTM5N/vtHpEqSpIzEWBpzPp5VUOWHBbGM7vQ5AA Rn4ZGfvRCNWTw== Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [IPv6:2a00:1450:4864:20::532]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 88CA6629CF for ; Thu, 30 Nov 2023 15:25:46 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="fpvJ+sxD"; dkim-atps=neutral Received: by mail-ed1-x532.google.com with SMTP id 4fb4d7f45d1cf-54b0073d50fso1045069a12.2 for ; Thu, 30 Nov 2023 06:25:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1701354346; x=1701959146; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JySX0keog5rCmfsQOpUf57BclqOiVUVVM1eEKysW46M=; b=fpvJ+sxDA/fu4exlnqcZZ9JBVzb6heK2YW8Y2saDFX1M1sxXVbS6x0tudpGEj+pz16 yRPNDYT7XQ/2wR19I6UIhCJQ7X/0LCSyDG5+axWH0manoP+dZITJhx+jte15jRWwZnpP /qrXwYOUGTJ/P/l49Fb+XtPSN73U0wvFTx5gY3QMTNJ5SgsG3rn2ruFylU8IJeND5/3r y+cmZFo4XGBgoQaekQXhqG86MaiqVhM30DzjOpSgrEM4oA50EyC0bUHrE8FG1FO0Si8z RNjEQkIwoUU3EOZBX3Ii8radgWAKxlctB+mfg11l2IaKxrjP1PFToK/v+PrlQ0QfCXkh vcIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701354346; x=1701959146; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JySX0keog5rCmfsQOpUf57BclqOiVUVVM1eEKysW46M=; b=asc5AzIf4JHWYzcmQfBQbAzGk+eoLsyAYR7GnoWzN4XY+LnWk7HNRkga8pH8Mo/xJO ZOARe9tuHZ9GLrzSpg0v2zGTindP6qHBsrFxihNotYqCmeK5X4K6549Wff65qcvwIOBz 1Rf5NfvSC27VHuh/UltvpCI08AT533QQspvp3gxeiqwcMNFHjyUOT4kO4nye/IX5Vm4t E4N1P2i1ZKHyQPgsKtJC8TlbjcduJ2U+VIJTkXNv8sNUBReUvXLPgKQzW4LVbRDmzC2r dG4+uWCAyGpS0j+/rlNw7qcUD/+Ped178lhyIlJB78C6l1Wlqvd9V90lIQxUM/8/RRYN SACw== X-Gm-Message-State: AOJu0Yw3QDOk2fiq5Kaq2n4DXYpETO8d8vh8uxvhYzPUG4ijq4TS/neH OXH5VutVKqNVYzNwb+VVOrJhbKNyW6lMo1t4R56FUQ== X-Google-Smtp-Source: AGHT+IFZm0wUJDWnwbBRHK1t/p/mVa36jSfhd7tFcpabr4s2HdspreqiXoyDg1rpe3dTTOkj8ChLzQ== X-Received: by 2002:a17:906:190:b0:a17:29b0:573e with SMTP id 16-20020a170906019000b00a1729b0573emr4555303ejb.37.1701354345410; Thu, 30 Nov 2023 06:25:45 -0800 (PST) Received: from localhost.localdomain ([88.97.53.79]) by smtp.gmail.com with ESMTPSA id a5-20020a17090640c500b009e50ea0a05asm725577ejk.99.2023.11.30.06.25.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Nov 2023 06:25:45 -0800 (PST) To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Nov 2023 14:25:33 +0000 Message-Id: <20231130142534.2075-6-naush@raspberrypi.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231130142534.2075-1-naush@raspberrypi.com> References: <20231130142534.2075-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 5/6] libcamera: controls: Use vendor tags for draft controls and properties X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Cc: Jacopo Mondi Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Label draft controls and properties through the "draft" vendor tag and deprecate the existing "draft: true" mechanism. This uses the new vendor tags mechanism to place draft controls in the same libcamera::controls::draft namespace and provide a defined control id range for these controls. This requires moving all draft controls from control_ids.yaml to control_ids_draft.yaml. One breaking change in this commit is that draft control ids also move to the libcamera::controls::draft namespace from the existing libcamera::controls namespace. This is desirable to avoid API breakages when adding new libcamera controls. So, for example, the use of controls::NOISE_REDUCTION_MODE will need to be replaced with controls::draft::NOISE_REDUCTION_MODE. Signed-off-by: Naushir Patuck Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- include/libcamera/control_ids.h.in | 6 - include/libcamera/meson.build | 2 + include/libcamera/property_ids.h.in | 6 - src/ipa/rpi/common/ipa_base.cpp | 2 +- src/ipa/rpi/vc4/vc4.cpp | 2 +- src/libcamera/control_ids.cpp.in | 15 -- src/libcamera/control_ids_core.yaml | 232 ------------------ src/libcamera/control_ids_draft.yaml | 230 +++++++++++++++++ src/libcamera/property_ids.cpp.in | 15 -- src/libcamera/property_ids_core.yaml | 33 --- src/libcamera/property_ids_draft.yaml | 39 +++ src/py/libcamera/gen-py-controls.py | 10 +- src/py/libcamera/py_controls_generated.cpp.in | 5 - .../libcamera/py_properties_generated.cpp.in | 5 - utils/gen-controls.py | 36 +-- 15 files changed, 286 insertions(+), 352 deletions(-) create mode 100644 src/libcamera/control_ids_draft.yaml create mode 100644 src/libcamera/property_ids_draft.yaml diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in index c97b09a82450..d53b1cf7beb2 100644 --- a/include/libcamera/control_ids.h.in +++ b/include/libcamera/control_ids.h.in @@ -26,12 +26,6 @@ ${controls} extern const ControlIdMap controls; -namespace draft { - -${draft_controls} - -} /* namespace draft */ - ${vendor_controls} } /* namespace controls */ diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build index a2bb5d163ece..bab858a3790f 100644 --- a/include/libcamera/meson.build +++ b/include/libcamera/meson.build @@ -34,10 +34,12 @@ libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir controls_map = { 'controls': { + 'draft': 'control_ids_draft.yaml', 'core': 'control_ids_core.yaml', }, 'properties': { + 'draft': 'property_ids_draft.yaml', 'core': 'property_ids_core.yaml', } } diff --git a/include/libcamera/property_ids.h.in b/include/libcamera/property_ids.h.in index 47c5d6bf2e28..43372c718fc9 100644 --- a/include/libcamera/property_ids.h.in +++ b/include/libcamera/property_ids.h.in @@ -23,12 +23,6 @@ ${ids} ${controls} -namespace draft { - -${draft_controls} - -} /* namespace draft */ - extern const ControlIdMap properties; ${vendor_controls} diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index a1fec3aa3dd1..6ac9d5de2f88 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -1024,7 +1024,7 @@ void IpaBase::applyControls(const ControlList &controls) break; } - case controls::NOISE_REDUCTION_MODE: + case controls::draft::NOISE_REDUCTION_MODE: /* Handled below in handleControls() */ libcameraMetadata_.set(controls::draft::NoiseReductionMode, ctrl.second.get()); diff --git a/src/ipa/rpi/vc4/vc4.cpp b/src/ipa/rpi/vc4/vc4.cpp index c4baf04fb1e7..c165a5b8b0b6 100644 --- a/src/ipa/rpi/vc4/vc4.cpp +++ b/src/ipa/rpi/vc4/vc4.cpp @@ -260,7 +260,7 @@ void IpaVc4::handleControls(const ControlList &controls) for (auto const &ctrl : controls) { switch (ctrl.first) { - case controls::NOISE_REDUCTION_MODE: { + case controls::draft::NOISE_REDUCTION_MODE: { RPiController::DenoiseAlgorithm *sdn = dynamic_cast( controller_.getAlgorithm("SDN")); /* Some platforms may have a combined "denoise" algorithm instead. */ diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in index bdb312759eb1..d283c1c1f401 100644 --- a/src/libcamera/control_ids.cpp.in +++ b/src/libcamera/control_ids.cpp.in @@ -24,15 +24,6 @@ namespace controls { ${controls_doc} -/** - * \brief Namespace for libcamera draft controls - */ -namespace draft { - -${draft_controls_doc} - -} /* namespace draft */ - ${vendor_controls_doc} #ifndef __DOXYGEN__ @@ -42,12 +33,6 @@ ${vendor_controls_doc} */ ${controls_def} -namespace draft { - -${draft_controls_def} - -} /* namespace draft */ - ${vendor_controls_def} #endif diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index ff74ce1deedb..76fb9347d8e3 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -865,236 +865,4 @@ controls: description: | This is a long exposure image. - # ---------------------------------------------------------------------------- - # Draft controls section - - - AePrecaptureTrigger: - type: int32_t - draft: true - description: | - Control for AE metering trigger. Currently identical to - ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER. - - Whether the camera device will trigger a precapture metering sequence - when it processes this request. - enum: - - name: AePrecaptureTriggerIdle - value: 0 - description: The trigger is idle. - - name: AePrecaptureTriggerStart - value: 1 - description: The pre-capture AE metering is started by the camera. - - name: AePrecaptureTriggerCancel - value: 2 - description: | - The camera will cancel any active or completed metering sequence. - The AE algorithm is reset to its initial state. - - - NoiseReductionMode: - type: int32_t - draft: true - description: | - Control to select the noise reduction algorithm mode. Currently - identical to ANDROID_NOISE_REDUCTION_MODE. - - Mode of operation for the noise reduction algorithm. - enum: - - name: NoiseReductionModeOff - value: 0 - description: No noise reduction is applied - - name: NoiseReductionModeFast - value: 1 - description: | - Noise reduction is applied without reducing the frame rate. - - name: NoiseReductionModeHighQuality - value: 2 - description: | - High quality noise reduction at the expense of frame rate. - - name: NoiseReductionModeMinimal - value: 3 - description: | - Minimal noise reduction is applied without reducing the frame rate. - - name: NoiseReductionModeZSL - value: 4 - description: | - Noise reduction is applied at different levels to different streams. - - - ColorCorrectionAberrationMode: - type: int32_t - draft: true - description: | - Control to select the color correction aberration mode. Currently - identical to ANDROID_COLOR_CORRECTION_ABERRATION_MODE. - - Mode of operation for the chromatic aberration correction algorithm. - enum: - - name: ColorCorrectionAberrationOff - value: 0 - description: No aberration correction is applied. - - name: ColorCorrectionAberrationFast - value: 1 - description: Aberration correction will not slow down the frame rate. - - name: ColorCorrectionAberrationHighQuality - value: 2 - description: | - High quality aberration correction which might reduce the frame - rate. - - - AeState: - type: int32_t - draft: true - description: | - Control to report the current AE algorithm state. Currently identical to - ANDROID_CONTROL_AE_STATE. - - Current state of the AE algorithm. - enum: - - name: AeStateInactive - value: 0 - description: The AE algorithm is inactive. - - name: AeStateSearching - value: 1 - description: The AE algorithm has not converged yet. - - name: AeStateConverged - value: 2 - description: The AE algorithm has converged. - - name: AeStateLocked - value: 3 - description: The AE algorithm is locked. - - name: AeStateFlashRequired - value: 4 - description: The AE algorithm would need a flash for good results - - name: AeStatePrecapture - value: 5 - description: | - The AE algorithm has started a pre-capture metering session. - \sa AePrecaptureTrigger - - - AwbState: - type: int32_t - draft: true - description: | - Control to report the current AWB algorithm state. Currently identical - to ANDROID_CONTROL_AWB_STATE. - - Current state of the AWB algorithm. - enum: - - name: AwbStateInactive - value: 0 - description: The AWB algorithm is inactive. - - name: AwbStateSearching - value: 1 - description: The AWB algorithm has not converged yet. - - name: AwbConverged - value: 2 - description: The AWB algorithm has converged. - - name: AwbLocked - value: 3 - description: The AWB algorithm is locked. - - - SensorRollingShutterSkew: - type: int64_t - draft: true - description: | - Control to report the time between the start of exposure of the first - row and the start of exposure of the last row. Currently identical to - ANDROID_SENSOR_ROLLING_SHUTTER_SKEW - - - LensShadingMapMode: - type: int32_t - draft: true - description: | - Control to report if the lens shading map is available. Currently - identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE. - enum: - - name: LensShadingMapModeOff - value: 0 - description: No lens shading map mode is available. - - name: LensShadingMapModeOn - value: 1 - description: The lens shading map mode is available. - - - PipelineDepth: - type: int32_t - draft: true - description: | - Specifies the number of pipeline stages the frame went through from when - it was exposed to when the final completed result was available to the - framework. Always less than or equal to PipelineMaxDepth. Currently - identical to ANDROID_REQUEST_PIPELINE_DEPTH. - - The typical value for this control is 3 as a frame is first exposed, - captured and then processed in a single pass through the ISP. Any - additional processing step performed after the ISP pass (in example face - detection, additional format conversions etc) count as an additional - pipeline stage. - - - MaxLatency: - type: int32_t - draft: true - description: | - The maximum number of frames that can occur after a request (different - than the previous) has been submitted, and before the result's state - becomes synchronized. A value of -1 indicates unknown latency, and 0 - indicates per-frame control. Currently identical to - ANDROID_SYNC_MAX_LATENCY. - - - TestPatternMode: - type: int32_t - draft: true - description: | - Control to select the test pattern mode. Currently identical to - ANDROID_SENSOR_TEST_PATTERN_MODE. - enum: - - name: TestPatternModeOff - value: 0 - description: | - No test pattern mode is used. The camera device returns frames from - the image sensor. - - name: TestPatternModeSolidColor - value: 1 - description: | - Each pixel in [R, G_even, G_odd, B] is replaced by its respective - color channel provided in test pattern data. - \todo Add control for test pattern data. - - name: TestPatternModeColorBars - value: 2 - description: | - All pixel data is replaced with an 8-bar color pattern. The vertical - bars (left-to-right) are as follows; white, yellow, cyan, green, - magenta, red, blue and black. Each bar should take up 1/8 of the - sensor pixel array width. When this is not possible, the bar size - should be rounded down to the nearest integer and the pattern can - repeat on the right side. Each bar's height must always take up the - full sensor pixel array height. - - name: TestPatternModeColorBarsFadeToGray - value: 3 - description: | - The test pattern is similar to TestPatternModeColorBars, - except that each bar should start at its specified color at the top - and fade to gray at the bottom. Furthermore each bar is further - subdevided into a left and right half. The left half should have a - smooth gradient, and the right half should have a quantized - gradient. In particular, the right half's should consist of blocks - of the same color for 1/16th active sensor pixel array width. The - least significant bits in the quantized gradient should be copied - from the most significant bits of the smooth gradient. The height of - each bar should always be a multiple of 128. When this is not the - case, the pattern should repeat at the bottom of the image. - - name: TestPatternModePn9 - value: 4 - description: | - All pixel data is replaced by a pseudo-random sequence generated - from a PN9 512-bit sequence (typically implemented in hardware with - a linear feedback shift register). The generator should be reset at - the beginning of each frame, and thus each subsequent raw frame with - this test pattern should be exactly the same as the last. - - name: TestPatternModeCustom1 - value: 256 - description: | - The first custom test pattern. All custom patterns that are - available only on this camera device are at least this numeric - value. All of the custom test patterns will be static (that is the - raw image must not vary from frame to frame). - ... diff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml new file mode 100644 index 000000000000..9bef5bf15238 --- /dev/null +++ b/src/libcamera/control_ids_draft.yaml @@ -0,0 +1,230 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2019, Google Inc. +# +%YAML 1.1 +--- +# Unless otherwise stated, all controls are bi-directional, i.e. they can be +# set through Request::controls() and returned out through Request::metadata(). +vendor: draft +controls: + - AePrecaptureTrigger: + type: int32_t + description: | + Control for AE metering trigger. Currently identical to + ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER. + + Whether the camera device will trigger a precapture metering sequence + when it processes this request. + enum: + - name: AePrecaptureTriggerIdle + value: 0 + description: The trigger is idle. + - name: AePrecaptureTriggerStart + value: 1 + description: The pre-capture AE metering is started by the camera. + - name: AePrecaptureTriggerCancel + value: 2 + description: | + The camera will cancel any active or completed metering sequence. + The AE algorithm is reset to its initial state. + + - NoiseReductionMode: + type: int32_t + description: | + Control to select the noise reduction algorithm mode. Currently + identical to ANDROID_NOISE_REDUCTION_MODE. + + Mode of operation for the noise reduction algorithm. + enum: + - name: NoiseReductionModeOff + value: 0 + description: No noise reduction is applied + - name: NoiseReductionModeFast + value: 1 + description: | + Noise reduction is applied without reducing the frame rate. + - name: NoiseReductionModeHighQuality + value: 2 + description: | + High quality noise reduction at the expense of frame rate. + - name: NoiseReductionModeMinimal + value: 3 + description: | + Minimal noise reduction is applied without reducing the frame rate. + - name: NoiseReductionModeZSL + value: 4 + description: | + Noise reduction is applied at different levels to different streams. + + - ColorCorrectionAberrationMode: + type: int32_t + description: | + Control to select the color correction aberration mode. Currently + identical to ANDROID_COLOR_CORRECTION_ABERRATION_MODE. + + Mode of operation for the chromatic aberration correction algorithm. + enum: + - name: ColorCorrectionAberrationOff + value: 0 + description: No aberration correction is applied. + - name: ColorCorrectionAberrationFast + value: 1 + description: Aberration correction will not slow down the frame rate. + - name: ColorCorrectionAberrationHighQuality + value: 2 + description: | + High quality aberration correction which might reduce the frame + rate. + + - AeState: + type: int32_t + description: | + Control to report the current AE algorithm state. Currently identical to + ANDROID_CONTROL_AE_STATE. + + Current state of the AE algorithm. + enum: + - name: AeStateInactive + value: 0 + description: The AE algorithm is inactive. + - name: AeStateSearching + value: 1 + description: The AE algorithm has not converged yet. + - name: AeStateConverged + value: 2 + description: The AE algorithm has converged. + - name: AeStateLocked + value: 3 + description: The AE algorithm is locked. + - name: AeStateFlashRequired + value: 4 + description: The AE algorithm would need a flash for good results + - name: AeStatePrecapture + value: 5 + description: | + The AE algorithm has started a pre-capture metering session. + \sa AePrecaptureTrigger + + - AwbState: + type: int32_t + description: | + Control to report the current AWB algorithm state. Currently identical + to ANDROID_CONTROL_AWB_STATE. + + Current state of the AWB algorithm. + enum: + - name: AwbStateInactive + value: 0 + description: The AWB algorithm is inactive. + - name: AwbStateSearching + value: 1 + description: The AWB algorithm has not converged yet. + - name: AwbConverged + value: 2 + description: The AWB algorithm has converged. + - name: AwbLocked + value: 3 + description: The AWB algorithm is locked. + + - SensorRollingShutterSkew: + type: int64_t + description: | + Control to report the time between the start of exposure of the first + row and the start of exposure of the last row. Currently identical to + ANDROID_SENSOR_ROLLING_SHUTTER_SKEW + + - LensShadingMapMode: + type: int32_t + description: | + Control to report if the lens shading map is available. Currently + identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE. + enum: + - name: LensShadingMapModeOff + value: 0 + description: No lens shading map mode is available. + - name: LensShadingMapModeOn + value: 1 + description: The lens shading map mode is available. + + - PipelineDepth: + type: int32_t + description: | + Specifies the number of pipeline stages the frame went through from when + it was exposed to when the final completed result was available to the + framework. Always less than or equal to PipelineMaxDepth. Currently + identical to ANDROID_REQUEST_PIPELINE_DEPTH. + + The typical value for this control is 3 as a frame is first exposed, + captured and then processed in a single pass through the ISP. Any + additional processing step performed after the ISP pass (in example face + detection, additional format conversions etc) count as an additional + pipeline stage. + + - MaxLatency: + type: int32_t + description: | + The maximum number of frames that can occur after a request (different + than the previous) has been submitted, and before the result's state + becomes synchronized. A value of -1 indicates unknown latency, and 0 + indicates per-frame control. Currently identical to + ANDROID_SYNC_MAX_LATENCY. + + - TestPatternMode: + type: int32_t + description: | + Control to select the test pattern mode. Currently identical to + ANDROID_SENSOR_TEST_PATTERN_MODE. + enum: + - name: TestPatternModeOff + value: 0 + description: | + No test pattern mode is used. The camera device returns frames from + the image sensor. + - name: TestPatternModeSolidColor + value: 1 + description: | + Each pixel in [R, G_even, G_odd, B] is replaced by its respective + color channel provided in test pattern data. + \todo Add control for test pattern data. + - name: TestPatternModeColorBars + value: 2 + description: | + All pixel data is replaced with an 8-bar color pattern. The vertical + bars (left-to-right) are as follows; white, yellow, cyan, green, + magenta, red, blue and black. Each bar should take up 1/8 of the + sensor pixel array width. When this is not possible, the bar size + should be rounded down to the nearest integer and the pattern can + repeat on the right side. Each bar's height must always take up the + full sensor pixel array height. + - name: TestPatternModeColorBarsFadeToGray + value: 3 + description: | + The test pattern is similar to TestPatternModeColorBars, + except that each bar should start at its specified color at the top + and fade to gray at the bottom. Furthermore each bar is further + subdevided into a left and right half. The left half should have a + smooth gradient, and the right half should have a quantized + gradient. In particular, the right half's should consist of blocks + of the same color for 1/16th active sensor pixel array width. The + least significant bits in the quantized gradient should be copied + from the most significant bits of the smooth gradient. The height of + each bar should always be a multiple of 128. When this is not the + case, the pattern should repeat at the bottom of the image. + - name: TestPatternModePn9 + value: 4 + description: | + All pixel data is replaced by a pseudo-random sequence generated + from a PN9 512-bit sequence (typically implemented in hardware with + a linear feedback shift register). The generator should be reset at + the beginning of each frame, and thus each subsequent raw frame with + this test pattern should be exactly the same as the last. + - name: TestPatternModeCustom1 + value: 256 + description: | + The first custom test pattern. All custom patterns that are + available only on this camera device are at least this numeric + value. All of the custom test patterns will be static (that is the + raw image must not vary from frame to frame). + +... diff --git a/src/libcamera/property_ids.cpp.in b/src/libcamera/property_ids.cpp.in index eed1124f3eb7..8b274c38c74b 100644 --- a/src/libcamera/property_ids.cpp.in +++ b/src/libcamera/property_ids.cpp.in @@ -23,15 +23,6 @@ namespace properties { ${controls_doc} -/** - * \brief Namespace for libcamera draft properties - */ -namespace draft { - -${draft_controls_doc} - -} /* namespace draft */ - ${vendor_controls_doc} #ifndef __DOXYGEN__ @@ -41,12 +32,6 @@ ${vendor_controls_doc} */ ${controls_def} -namespace draft { - -${draft_controls_def} - -} /* namespace draft */ - ${vendor_controls_def} #endif diff --git a/src/libcamera/property_ids_core.yaml b/src/libcamera/property_ids_core.yaml index 45f3609b4236..834454a4e087 100644 --- a/src/libcamera/property_ids_core.yaml +++ b/src/libcamera/property_ids_core.yaml @@ -701,37 +701,4 @@ controls: Different cameras may report identical devices. - # ---------------------------------------------------------------------------- - # Draft properties section - - - ColorFilterArrangement: - type: int32_t - draft: true - description: | - The arrangement of color filters on sensor; represents the colors in the - top-left 2x2 section of the sensor, in reading order. Currently - identical to ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT. - enum: - - name: RGGB - value: 0 - description: RGGB Bayer pattern - - name: GRBG - value: 1 - description: GRBG Bayer pattern - - name: GBRG - value: 2 - description: GBRG Bayer pattern - - name: BGGR - value: 3 - description: BGGR Bayer pattern - - name: RGB - value: 4 - description: | - Sensor is not Bayer; output has 3 16-bit values for each pixel, - instead of just 1 16-bit value per pixel. - - name: MONO - value: 5 - description: | - Sensor is not Bayer; output consists of a single colour channel. - ... diff --git a/src/libcamera/property_ids_draft.yaml b/src/libcamera/property_ids_draft.yaml new file mode 100644 index 000000000000..62f0e242d0c6 --- /dev/null +++ b/src/libcamera/property_ids_draft.yaml @@ -0,0 +1,39 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# Copyright (C) 2019, Google Inc. +# +%YAML 1.1 +--- +vendor: draft +controls: + - ColorFilterArrangement: + type: int32_t + vendor: draft + description: | + The arrangement of color filters on sensor; represents the colors in the + top-left 2x2 section of the sensor, in reading order. Currently + identical to ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT. + enum: + - name: RGGB + value: 0 + description: RGGB Bayer pattern + - name: GRBG + value: 1 + description: GRBG Bayer pattern + - name: GBRG + value: 2 + description: GBRG Bayer pattern + - name: BGGR + value: 3 + description: BGGR Bayer pattern + - name: RGB + value: 4 + description: | + Sensor is not Bayer; output has 3 16-bit values for each pixel, + instead of just 1 16-bit value per pixel. + - name: MONO + value: 5 + description: | + Sensor is not Bayer; output consists of a single colour channel. + +... diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py index 8ae8d5126e39..8efbf95b9433 100755 --- a/src/py/libcamera/gen-py-controls.py +++ b/src/py/libcamera/gen-py-controls.py @@ -32,14 +32,12 @@ def generate_py(controls, mode): name, ctrl = ctrls.popitem() if vendor not in vendors and vendor != 'libcamera': - vendors_class_def.append('class Py{}Controls\n{{\n}};\n'.format(vendor)) - vendor_defs.append('\tauto {} = py::class_(controls, \"{}\");'.format(vendor, vendor, vendor)) + vendor_mode_str = f'{vendor.capitalize()}{mode.capitalize()}' + vendors_class_def.append('class Py{}\n{{\n}};\n'.format(vendor_mode_str)) + vendor_defs.append('\tauto {} = py::class_(controls, \"{}\");'.format(vendor, vendor_mode_str, vendor)) vendors.append(vendor) - if ctrl.get('draft'): - ns = 'libcamera::{}::draft::'.format(mode) - container = 'draft' - elif vendor != 'libcamera': + if vendor != 'libcamera': ns = 'libcamera::{}::{}::'.format(mode, vendor) container = vendor else: diff --git a/src/py/libcamera/py_controls_generated.cpp.in b/src/py/libcamera/py_controls_generated.cpp.in index ec4b55ef2011..8d282ce51856 100644 --- a/src/py/libcamera/py_controls_generated.cpp.in +++ b/src/py/libcamera/py_controls_generated.cpp.in @@ -17,16 +17,11 @@ class PyControls { }; -class PyDraftControls -{ -}; - ${vendors_class_def} void init_py_controls_generated(py::module& m) { auto controls = py::class_(m, "controls"); - auto draft = py::class_(controls, "draft"); ${vendors_defs} ${controls} diff --git a/src/py/libcamera/py_properties_generated.cpp.in b/src/py/libcamera/py_properties_generated.cpp.in index f7b5ec8c635d..e3802b81a075 100644 --- a/src/py/libcamera/py_properties_generated.cpp.in +++ b/src/py/libcamera/py_properties_generated.cpp.in @@ -17,16 +17,11 @@ class PyProperties { }; -class PyDraftProperties -{ -}; - ${vendors_class_def} void init_py_properties_generated(py::module& m) { auto controls = py::class_(m, "properties"); - auto draft = py::class_(controls, "draft"); ${vendors_defs} ${controls} diff --git a/utils/gen-controls.py b/utils/gen-controls.py index 8e592148af3d..6cd5e362c66f 100755 --- a/utils/gen-controls.py +++ b/utils/gen-controls.py @@ -86,11 +86,6 @@ class Control(object): """Is the control an enumeration""" return self.__enum_values is not None - @property - def is_draft(self): - """Is the control a draft control""" - return self.__data.get('draft') is not None - @property def vendor(self): """The vendor string, or None""" @@ -101,12 +96,6 @@ class Control(object): """The control name (CamelCase)""" return self.__name - @property - def q_name(self): - """The control name, qualified with a namespace""" - ns = 'draft::' if self.is_draft else '' - return ns + self.__name - @property def type(self): typ = self.__data.get('type') @@ -159,7 +148,7 @@ ${description} for ctrl in controls: id_name = snake_case(ctrl.name).upper() - vendor = 'draft' if ctrl.is_draft else ctrl.vendor + vendor = ctrl.vendor if vendor not in ctrls_doc: ctrls_doc[vendor] = [] ctrls_def[vendor] = [] @@ -208,7 +197,8 @@ ${description} target_doc.append(doc_template.substitute(info)) target_def.append(def_template.substitute(info)) - ctrls_map.append('\t{ ' + id_name + ', &' + ctrl.q_name + ' },') + vendor_ns = vendor + '::' if vendor != "libcamera" else '' + ctrls_map.append('\t{ ' + vendor_ns + id_name + ', &' + vendor_ns + ctrl.name + ' },') vendor_ctrl_doc_sub = [] vendor_ctrl_template = string.Template(''' @@ -221,18 +211,16 @@ ${vendor_controls_str} } /* namespace ${vendor} */''') - for vendor in [v for v in ctrls_doc.keys() if v not in ['libcamera', 'draft']]: + for vendor in [v for v in ctrls_doc.keys() if v not in ['libcamera']]: vendor_ctrl_doc_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n\n'.join(ctrls_doc[vendor])})) vendor_ctrl_def_sub = [] - for vendor in [v for v in ctrls_def.keys() if v not in ['libcamera', 'draft']]: + for vendor in [v for v in ctrls_def.keys() if v not in ['libcamera']]: vendor_ctrl_def_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n'.join(ctrls_def[vendor])})) return { 'controls_doc': '\n\n'.join(ctrls_doc['libcamera']), 'controls_def': '\n'.join(ctrls_def['libcamera']), - 'draft_controls_doc': '\n\n'.join(ctrls_doc['draft']), - 'draft_controls_def': '\n\n'.join(ctrls_def['draft']), 'controls_map': '\n'.join(ctrls_map), 'vendor_controls_doc': '\n'.join(vendor_ctrl_doc_sub), 'vendor_controls_def': '\n'.join(vendor_ctrl_def_sub), @@ -252,7 +240,7 @@ def generate_h(controls, mode, ranges): for ctrl in controls: id_name = snake_case(ctrl.name).upper() - vendor = 'draft' if ctrl.is_draft else ctrl.vendor + vendor = ctrl.vendor if vendor not in ctrls: if vendor not in ranges.keys(): raise RuntimeError(f'Control id range is not defined for vendor {vendor}') @@ -260,8 +248,7 @@ def generate_h(controls, mode, ranges): ids[vendor] = [] ctrls[vendor] = [] - # Core and draft controls use the same ID value - target_ids = ids['libcamera'] if vendor in ['libcamera', 'draft'] else ids[vendor] + target_ids = ids[vendor] target_ids.append('\t' + id_name + ' = ' + str(id_value[vendor]) + ',') info = { @@ -269,11 +256,7 @@ def generate_h(controls, mode, ranges): 'type': ctrl.type, } - target_ctrls = ctrls['libcamera'] - if ctrl.is_draft: - target_ctrls = ctrls['draft'] - elif vendor != 'libcamera': - target_ctrls = ctrls[vendor] + target_ctrls = ctrls[vendor] if ctrl.is_enum: target_ctrls.append(enum_template_start.substitute(info)) @@ -312,7 +295,7 @@ ${vendor_controls} ''') vendor_sub = [] - for vendor in [v for v in ctrls.keys() if v not in ['libcamera', 'draft']]: + for vendor in [v for v in ctrls.keys() if v != 'libcamera']: vendor_sub.append(vendor_template.substitute({'mode': mode.upper(), 'vendor': vendor, 'vendor_def': vendor.upper(), @@ -322,7 +305,6 @@ ${vendor_controls} return { 'ids': '\n'.join(ids['libcamera']), 'controls': '\n'.join(ctrls['libcamera']), - 'draft_controls': '\n'.join(ctrls['draft']), 'vendor_controls': '\n'.join(vendor_sub) }