From patchwork Thu Dec 12 05:24:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 22295 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 17797BD80A for ; Thu, 12 Dec 2024 05:25:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BA63567EBF; Thu, 12 Dec 2024 06:25:09 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="IaY058vn"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D3F0E6189C for ; Thu, 12 Dec 2024 06:25:08 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:39eb:989c:b016:217b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 522C7B9A; Thu, 12 Dec 2024 06:24:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733981075; bh=TobcTZ2RB+aGF4vyg8hn4PQkzvFwOYo9yUF/Dgu4+Jk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IaY058vn6c5zl/EXBNblTkrakMV8MAjjW65yqRIC48p0TB84tU+MZr5wbWCh76H/Z 0uVPHg2YkKqSCC1ihYesRJZ8ApLmqYtED7Nqa8arEfyqdsoZNmjv/tcoHgFySTjaEZ rQ4YG//rN3d3th8KpRsnEPdYvoQZQ65NPWDrmOIo= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Kieran Bingham Subject: [PATCH v4 1/4] libcamera: controls: Populate direction field in control definitions Date: Thu, 12 Dec 2024 14:24:35 +0900 Message-Id: <20241212052438.1547410-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241212052438.1547410-1-paul.elder@ideasonboard.com> References: <20241212052438.1547410-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In preparation for adding support for querying direction information from controls, populate the corresponding field in the control ID defintions. Signed-off-by: Paul Elder Reviewed-by: Kieran Bingham Reviewed-by: Stefan Klug --- Changes in v4: - fix a few direction entries No change in v3 Changes in v2: - add missing entries - add entries for all controls, since this field shoul dbe mandatory --- src/libcamera/control_ids_core.yaml | 44 ++++++++++++++++++++++++++++ src/libcamera/control_ids_draft.yaml | 15 ++++++++++ src/libcamera/control_ids_rpi.yaml | 3 ++ 3 files changed, 62 insertions(+) diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml index d45cf8e56187..073e0611d47c 100644 --- a/src/libcamera/control_ids_core.yaml +++ b/src/libcamera/control_ids_core.yaml @@ -10,6 +10,7 @@ vendor: libcamera controls: - AeEnable: type: bool + direction: inout description: | Enable or disable the AE. @@ -17,6 +18,7 @@ controls: - AeLocked: type: bool + direction: out description: | Report the lock status of a running AE algorithm. @@ -31,6 +33,7 @@ controls: # - Better handling of custom types. - AeMeteringMode: type: int32_t + direction: inout description: | Specify a metering mode for the AE algorithm to use. @@ -56,6 +59,7 @@ controls: # - Better handling of custom types. - AeConstraintMode: type: int32_t + direction: inout description: | Specify a constraint mode for the AE algorithm to use. @@ -98,6 +102,7 @@ controls: # - Better handling of custom types. - AeExposureMode: type: int32_t + direction: inout description: | Specify an exposure mode for the AE algorithm to use. @@ -120,6 +125,7 @@ controls: - ExposureValue: type: float + direction: inout description: | Specify an Exposure Value (EV) parameter. @@ -134,6 +140,7 @@ controls: - ExposureTime: type: int32_t + direction: inout description: | Exposure time for the frame applied in the sensor device. @@ -153,6 +160,7 @@ controls: - AnalogueGain: type: float + direction: inout description: | Analogue gain value applied in the sensor device. @@ -173,6 +181,7 @@ controls: - AeFlickerMode: type: int32_t + direction: inout description: | Set the flicker avoidance mode for AGC/AEC. @@ -215,6 +224,7 @@ controls: - AeFlickerPeriod: type: int32_t + direction: inout description: | Manual flicker period in microseconds. @@ -235,6 +245,7 @@ controls: - AeFlickerDetected: type: int32_t + direction: out description: | Flicker period detected in microseconds. @@ -257,6 +268,7 @@ controls: - Brightness: type: float + direction: inout description: | Specify a fixed brightness parameter. @@ -265,6 +277,7 @@ controls: - Contrast: type: float + direction: inout description: | Specify a fixed contrast parameter. @@ -273,6 +286,7 @@ controls: - Lux: type: float + direction: out description: | Report an estimate of the current illuminance level in lux. @@ -280,6 +294,7 @@ controls: - AwbEnable: type: bool + direction: inout description: | Enable or disable the AWB. @@ -290,6 +305,7 @@ controls: # - Better handling of custom types. - AwbMode: type: int32_t + direction: inout description: | Specify the range of illuminants to use for the AWB algorithm. @@ -323,6 +339,7 @@ controls: - AwbLocked: type: bool + direction: out description: | Report the lock status of a running AWB algorithm. @@ -334,6 +351,7 @@ controls: - ColourGains: type: float + direction: inout description: | Pair of gain values for the Red and Blue colour channels, in that order. @@ -345,6 +363,7 @@ controls: - ColourTemperature: type: int32_t + direction: out description: | Report the estimate of the colour temperature for the frame, in kelvin. @@ -352,6 +371,7 @@ controls: - Saturation: type: float + direction: inout description: | Specify a fixed saturation parameter. @@ -360,6 +380,7 @@ controls: - SensorBlackLevels: type: int32_t + direction: out description: | Reports the sensor black levels used for processing a frame. @@ -370,6 +391,7 @@ controls: - Sharpness: type: float + direction: inout description: | Intensity of the sharpening applied to the image. @@ -384,6 +406,7 @@ controls: - FocusFoM: type: int32_t + direction: out description: | Reports a Figure of Merit (FoM) to indicate how in-focus the frame is. @@ -396,6 +419,7 @@ controls: - ColourCorrectionMatrix: type: float + direction: inout description: | The 3x3 matrix that converts camera RGB to sRGB within the imaging pipeline. @@ -409,6 +433,7 @@ controls: - ScalerCrop: type: Rectangle + direction: inout description: | Sets the image portion that will be scaled to form the whole of the final output image. @@ -424,6 +449,7 @@ controls: - DigitalGain: type: float + direction: inout description: | Digital gain value applied during the processing steps applied to the image as captured from the sensor. @@ -441,6 +467,7 @@ controls: - FrameDuration: type: int64_t + direction: out description: | The instantaneous frame duration from start of frame exposure to start of next exposure, expressed in microseconds. @@ -449,6 +476,7 @@ controls: - FrameDurationLimits: type: int64_t + direction: inout description: | The minimum and maximum (in that order) frame duration, expressed in microseconds. @@ -485,6 +513,7 @@ controls: - SensorTemperature: type: float + direction: out description: | Temperature measure from the camera sensor in Celsius. @@ -497,6 +526,7 @@ controls: - SensorTimestamp: type: int64_t + direction: out description: | The time when the first row of the image sensor active array is exposed. @@ -511,6 +541,7 @@ controls: - AfMode: type: int32_t + direction: inout description: | The mode of the AF (autofocus) algorithm. @@ -575,6 +606,7 @@ controls: - AfRange: type: int32_t + direction: inout description: | The range of focus distances that is scanned. @@ -602,6 +634,7 @@ controls: - AfSpeed: type: int32_t + direction: inout description: | Determine whether the AF is to move the lens as quickly as possible or more steadily. @@ -620,6 +653,7 @@ controls: - AfMetering: type: int32_t + direction: inout description: | The parts of the image used by the AF algorithm to measure focus. enum: @@ -636,6 +670,7 @@ controls: - AfWindows: type: Rectangle + direction: inout description: | The focus windows used by the AF algorithm when AfMetering is set to AfMeteringWindows. @@ -665,6 +700,7 @@ controls: - AfTrigger: type: int32_t + direction: in description: | Start an autofocus scan. @@ -690,6 +726,7 @@ controls: - AfPause: type: int32_t + direction: in description: | Pause lens movements when in continuous autofocus mode. @@ -734,6 +771,7 @@ controls: - LensPosition: type: float + direction: inout description: | Set and report the focus lens position. @@ -768,6 +806,7 @@ controls: - AfState: type: int32_t + direction: out description: | The current state of the AF algorithm. @@ -825,6 +864,7 @@ controls: - AfPauseState: type: int32_t + direction: out description: | Report whether the autofocus is currently running, paused or pausing. @@ -860,6 +900,7 @@ controls: - HdrMode: type: int32_t + direction: inout description: | Set the mode to be used for High Dynamic Range (HDR) imaging. @@ -926,6 +967,7 @@ controls: - HdrChannel: type: int32_t + direction: out description: | The HDR channel used to capture the frame. @@ -960,6 +1002,7 @@ controls: - Gamma: type: float + direction: inout description: | Specify a fixed gamma value. @@ -968,6 +1011,7 @@ controls: - DebugMetadataEnable: type: bool + direction: inout description: | Enable or disable the debug metadata. diff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml index 1b284257f601..87e4e02db482 100644 --- a/src/libcamera/control_ids_draft.yaml +++ b/src/libcamera/control_ids_draft.yaml @@ -10,6 +10,7 @@ vendor: draft controls: - AePrecaptureTrigger: type: int32_t + direction: inout description: | Control for AE metering trigger. Currently identical to ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER. @@ -31,6 +32,7 @@ controls: - NoiseReductionMode: type: int32_t + direction: inout description: | Control to select the noise reduction algorithm mode. Currently identical to ANDROID_NOISE_REDUCTION_MODE. @@ -59,6 +61,7 @@ controls: - ColorCorrectionAberrationMode: type: int32_t + direction: inout description: | Control to select the color correction aberration mode. Currently identical to ANDROID_COLOR_CORRECTION_ABERRATION_MODE. @@ -79,6 +82,7 @@ controls: - AeState: type: int32_t + direction: out description: | Control to report the current AE algorithm state. Currently identical to ANDROID_CONTROL_AE_STATE. @@ -108,6 +112,7 @@ controls: - AwbState: type: int32_t + direction: out description: | Control to report the current AWB algorithm state. Currently identical to ANDROID_CONTROL_AWB_STATE. @@ -129,6 +134,7 @@ controls: - SensorRollingShutterSkew: type: int64_t + direction: out 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 @@ -136,6 +142,7 @@ controls: - LensShadingMapMode: type: int32_t + direction: inout description: | Control to report if the lens shading map is available. Currently identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE. @@ -149,6 +156,7 @@ controls: - PipelineDepth: type: int32_t + direction: out 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 @@ -163,6 +171,7 @@ controls: - MaxLatency: type: int32_t + direction: out 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 @@ -172,6 +181,7 @@ controls: - TestPatternMode: type: int32_t + direction: inout description: | Control to select the test pattern mode. Currently identical to ANDROID_SENSOR_TEST_PATTERN_MODE. @@ -229,6 +239,7 @@ controls: - FaceDetectMode: type: int32_t + direction: inout description: | Control to select the face detection mode used by the pipeline. @@ -262,6 +273,7 @@ controls: - FaceDetectFaceRectangles: type: Rectangle + direction: out description: | Boundary rectangles of the detected faces. The number of values is the number of detected faces. @@ -273,6 +285,7 @@ controls: - FaceDetectFaceScores: type: uint8_t + direction: out description: | Confidence score of each of the detected faces. The range of score is [0, 100]. The number of values should be the number of faces reported @@ -285,6 +298,7 @@ controls: - FaceDetectFaceLandmarks: type: Point + direction: out description: | Array of human face landmark coordinates in format [..., left_eye_i, right_eye_i, mouth_i, left_eye_i+1, ...], with i = index of face. The @@ -298,6 +312,7 @@ controls: - FaceDetectFaceIds: type: int32_t + direction: out description: | Each detected face is given a unique ID that is valid for as long as the face is visible to the camera device. A face that leaves the field of diff --git a/src/libcamera/control_ids_rpi.yaml b/src/libcamera/control_ids_rpi.yaml index 34bbdfc863c5..7524c5d23258 100644 --- a/src/libcamera/control_ids_rpi.yaml +++ b/src/libcamera/control_ids_rpi.yaml @@ -9,6 +9,7 @@ vendor: rpi controls: - StatsOutputEnable: type: bool + direction: inout description: | Toggles the Raspberry Pi IPA to output the hardware generated statistics. @@ -21,6 +22,7 @@ controls: - Bcm2835StatsOutput: type: uint8_t size: [n] + direction: out description: | Span of the BCM2835 ISP generated statistics for the current frame. @@ -33,6 +35,7 @@ controls: - ScalerCrops: type: Rectangle size: [n] + direction: out description: | An array of rectangles, where each singular value has identical functionality to the ScalerCrop control. This control allows the From patchwork Thu Dec 12 05:24:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 22296 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 DA52DBD80A for ; Thu, 12 Dec 2024 05:25:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4C5A967EC5; Thu, 12 Dec 2024 06:25:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="VP6zqVvV"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 52EC86189C for ; Thu, 12 Dec 2024 06:25:11 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:39eb:989c:b016:217b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 10D2A316; Thu, 12 Dec 2024 06:24:35 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733981077; bh=xnVIcCiAACAOLERCR3AbRwxwKTcjNddH1QuE+z0sb6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VP6zqVvVbM5brogsUAcDwnTCIfNgchcZcKJ/exvF1spSNR7610XQBkfWiHqq757AZ bwGuLsD6OyqUiYTT1RIlbbiGpRi5aLoxajJ5J6TexQ4wEkLyD2WERuAYTq7Mth/Cbj 3usuA5diIOdTRvM+3lLK6r1YPyitHpf+u149Az2o= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Laurent Pinchart , Kieran Bingham Subject: [PATCH v4 2/4] utils: codegen: controls.py: Parse direction information Date: Thu, 12 Dec 2024 14:24:36 +0900 Message-Id: <20241212052438.1547410-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241212052438.1547410-1-paul.elder@ideasonboard.com> References: <20241212052438.1547410-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In preparation for adding support for querying direction information from controls, parse the direction information from control ID definitions. This can later be plugged in directly to the IPA code generators simply by using ctrl.direction. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Stefan Klug --- No change in v4 Changes in v3: - minor reordering Changes in v2: - prevent errors in parsing properties, since the direction field is now required yet properties can only be out - do this by expanding the Control constructor to take the mode argument, so that needs to be passed in by the users of Control --- src/py/libcamera/gen-py-controls.py | 2 +- utils/codegen/controls.py | 24 +++++++++++++++++++++++- utils/codegen/gen-controls.py | 2 +- utils/codegen/gen-gst-controls.py | 2 +- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py index cf09c146084d..d43a7c1c7eab 100755 --- a/src/py/libcamera/gen-py-controls.py +++ b/src/py/libcamera/gen-py-controls.py @@ -83,7 +83,7 @@ def main(argv): vendors.append(vendor) for ctrl in data['controls']: - ctrl = Control(*ctrl.popitem(), vendor) + ctrl = Control(*ctrl.popitem(), vendor, args.mode) controls.append(extend_control(ctrl, args.mode)) data = { diff --git a/utils/codegen/controls.py b/utils/codegen/controls.py index 03c77cc64abe..602f15b25fb6 100644 --- a/utils/codegen/controls.py +++ b/utils/codegen/controls.py @@ -28,7 +28,7 @@ class ControlEnum(object): class Control(object): - def __init__(self, name, data, vendor): + def __init__(self, name, data, vendor, mode): self.__name = name self.__data = data self.__enum_values = None @@ -60,6 +60,16 @@ class Control(object): self.__size = num_elems + if mode == 'properties': + self.__direction = 'out' + else: + direction = self.__data.get('direction') + if direction is None: + raise RuntimeError(f'Control `{self.__name}` missing required field `{direction}`') + if direction not in ['in', 'out', 'inout']: + raise RuntimeError(f'Control `{self.__name}` direction `{direction}` is invalid; must be one of `in`, `out`, or `inout`') + self.__direction = direction + @property def description(self): """The control description""" @@ -111,6 +121,18 @@ class Control(object): else: return f"Span" + @property + def direction(self): + in_flag = 'ControlId::Direction::In' + out_flag = 'ControlId::Direction::Out' + + if self.__direction == 'inout': + return f'{in_flag} | {out_flag}' + if self.__direction == 'in': + return in_flag + if self.__direction == 'out': + return out_flag + @property def element_type(self): return self.__data.get('type') diff --git a/utils/codegen/gen-controls.py b/utils/codegen/gen-controls.py index 3034e9a54760..59b716c1c48c 100755 --- a/utils/codegen/gen-controls.py +++ b/utils/codegen/gen-controls.py @@ -71,7 +71,7 @@ def main(argv): ctrls = controls.setdefault(vendor, []) for i, ctrl in enumerate(data['controls']): - ctrl = Control(*ctrl.popitem(), vendor) + ctrl = Control(*ctrl.popitem(), vendor, args.mode) ctrls.append(extend_control(ctrl, i, ranges)) # Sort the vendors by range numerical value diff --git a/utils/codegen/gen-gst-controls.py b/utils/codegen/gen-gst-controls.py index 2601a67588a3..df0988266294 100755 --- a/utils/codegen/gen-gst-controls.py +++ b/utils/codegen/gen-gst-controls.py @@ -154,7 +154,7 @@ def main(argv): ctrls = controls.setdefault(vendor, []) for ctrl in data['controls']: - ctrl = Control(*ctrl.popitem(), vendor) + ctrl = Control(*ctrl.popitem(), vendor, mode='controls') if ctrl.name in exposed_controls: ctrls.append(extend_control(ctrl)) From patchwork Thu Dec 12 05:24:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 22297 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 79333BD80A for ; Thu, 12 Dec 2024 05:25:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DA5FB67ECA; Thu, 12 Dec 2024 06:25:16 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dEZ2BEP0"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C60667EB2 for ; Thu, 12 Dec 2024 06:25:12 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:39eb:989c:b016:217b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 10BADEA7; Thu, 12 Dec 2024 06:24:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733981079; bh=+tOYTHbKt1U1jIPeNyKKAlXLmakSNDIjyfwflaylxfE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dEZ2BEP0je/lxFHTbpV6/pTXtMfe7K+3Xvxy9NX/5zAC8A1c7ksnDd0gPZxI8ndKF qJ6BbGQ5IQ2jl2R5G3lCxoOOLFlaFVcQTYxVJHsOe0Ip3X8vVE4CiwZxNqANVyDuma 8j7kucqX7ttS2Hq1N7hcrKtCu+IoRAnnP6pXybys= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Laurent Pinchart Subject: [PATCH v4 3/4] libcamera: controls: Add support for querying direction information Date: Thu, 12 Dec 2024 14:24:37 +0900 Message-Id: <20241212052438.1547410-4-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241212052438.1547410-1-paul.elder@ideasonboard.com> References: <20241212052438.1547410-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support to ControlId for querying direction information. This allows applications to query whether a ControlId is meant for being set in controls or to be returned in metadata or both. This also has a side effect of properly encoding this information, as previously it was only mentioned losely and inconsistently in the control id definition. Signed-off-by: Paul Elder Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- Changes in v4: - add ControlId::direction() Changes in v3: - make direction parameter to ControlId and Control consutrctors mandatory - this entails expanding the control serializer/deserializer for V4L2Device and ControlSerializer to properly handle the direction - also the constructor parameters have to be reordered, compared to the last vesrion at least Changes in v2: - simplify code --- include/libcamera/controls.h | 20 +++++++++- include/libcamera/ipa/ipa_controls.h | 3 +- src/libcamera/control_ids.cpp.in | 4 +- src/libcamera/control_serializer.cpp | 8 +++- src/libcamera/controls.cpp | 56 ++++++++++++++++++++++++++-- src/libcamera/v4l2_device.cpp | 10 ++++- 6 files changed, 91 insertions(+), 10 deletions(-) diff --git a/include/libcamera/controls.h b/include/libcamera/controls.h index b24336cc280f..7c7828ae5db0 100644 --- a/include/libcamera/controls.h +++ b/include/libcamera/controls.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -249,14 +250,25 @@ private: class ControlId { public: + enum class Direction { + In = (1 << 0), + Out = (1 << 1), + }; + + using DirectionFlags = Flags; + ControlId(unsigned int id, const std::string &name, const std::string &vendor, - ControlType type, std::size_t size = 0, + ControlType type, DirectionFlags direction, + std::size_t size = 0, const std::map &enumStrMap = {}); unsigned int id() const { return id_; } const std::string &name() const { return name_; } const std::string &vendor() const { return vendor_; } ControlType type() const { return type_; } + DirectionFlags direction() const { return direction_; } + bool isInput() const { return !!(direction_ & Direction::In); } + bool isOutput() const { return !!(direction_ & Direction::Out); } bool isArray() const { return size_ > 0; } std::size_t size() const { return size_; } const std::map &enumerators() const { return reverseMap_; } @@ -268,11 +280,14 @@ private: std::string name_; std::string vendor_; ControlType type_; + DirectionFlags direction_; std::size_t size_; std::map enumStrMap_; std::map reverseMap_; }; +LIBCAMERA_FLAGS_ENABLE_OPERATORS(ControlId::Direction) + static inline bool operator==(unsigned int lhs, const ControlId &rhs) { return lhs == rhs.id(); @@ -300,9 +315,10 @@ public: using type = T; Control(unsigned int id, const char *name, const char *vendor, + ControlId::DirectionFlags direction, const std::map &enumStrMap = {}) : ControlId(id, name, vendor, details::control_type>::value, - details::control_type>::size, enumStrMap) + direction, details::control_type>::size, enumStrMap) { } diff --git a/include/libcamera/ipa/ipa_controls.h b/include/libcamera/ipa/ipa_controls.h index 5fd13394fcef..980668c86bcc 100644 --- a/include/libcamera/ipa/ipa_controls.h +++ b/include/libcamera/ipa/ipa_controls.h @@ -46,7 +46,8 @@ struct ipa_control_info_entry { uint32_t id; uint32_t type; uint32_t offset; - uint32_t padding[1]; + uint8_t direction; + uint8_t padding[3]; }; #ifdef __cplusplus diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in index afe9e2c96610..65668d486dbc 100644 --- a/src/libcamera/control_ids.cpp.in +++ b/src/libcamera/control_ids.cpp.in @@ -89,9 +89,9 @@ extern const std::map {{ctrl.name}}NameValueMap = { { "{{enum.name}}", {{enum.name}} }, {%- endfor %} }; -extern const Control<{{ctrl.type}}> {{ctrl.name}}({{ctrl.name|snake_case|upper}}, "{{ctrl.name}}", "{{vendor}}", {{ctrl.name}}NameValueMap); +extern const Control<{{ctrl.type}}> {{ctrl.name}}({{ctrl.name|snake_case|upper}}, "{{ctrl.name}}", "{{vendor}}", {{ctrl.direction}}, {{ctrl.name}}NameValueMap); {% else -%} -extern const Control<{{ctrl.type}}> {{ctrl.name}}({{ctrl.name|snake_case|upper}}, "{{ctrl.name}}", "{{vendor}}"); +extern const Control<{{ctrl.type}}> {{ctrl.name}}({{ctrl.name|snake_case|upper}}, "{{ctrl.name}}", "{{vendor}}", {{ctrl.direction}}); {% endif -%} {%- endfor %} diff --git a/src/libcamera/control_serializer.cpp b/src/libcamera/control_serializer.cpp index 0a5e8220a0ff..17834648c3f0 100644 --- a/src/libcamera/control_serializer.cpp +++ b/src/libcamera/control_serializer.cpp @@ -281,6 +281,7 @@ int ControlSerializer::serialize(const ControlInfoMap &infoMap, entry.id = id->id(); entry.type = id->type(); entry.offset = values.offset(); + entry.direction = static_cast(id->direction()); entries.write(&entry); store(info, values); @@ -493,12 +494,17 @@ ControlInfoMap ControlSerializer::deserialize(ByteStreamBuffer & /* If we're using a local id map, populate it. */ if (localIdMap) { + ControlId::DirectionFlags flags{ + static_cast(entry->direction) + }; + /** * \todo Find a way to preserve the control name for * debugging purpose. */ controlIds_.emplace_back(std::make_unique(entry->id, - "", "local", type)); + "", "local", type, + flags)); (*localIdMap)[entry->id] = controlIds_.back().get(); } diff --git a/src/libcamera/controls.cpp b/src/libcamera/controls.cpp index 65eeef2db9c2..6296aac6fff2 100644 --- a/src/libcamera/controls.cpp +++ b/src/libcamera/controls.cpp @@ -412,15 +412,16 @@ void ControlValue::reserve(ControlType type, bool isArray, std::size_t numElemen * \param[in] name The control name * \param[in] vendor The vendor name * \param[in] type The control data type + * \param[in] direction The direction of the control, if it can be used in Controls or Metadata * \param[in] size The size of the array control, or 0 if scalar control * \param[in] enumStrMap The map from enum names to values (optional) */ ControlId::ControlId(unsigned int id, const std::string &name, const std::string &vendor, ControlType type, - std::size_t size, + DirectionFlags direction, std::size_t size, const std::map &enumStrMap) - : id_(id), name_(name), vendor_(vendor), type_(type), size_(size), - enumStrMap_(enumStrMap) + : id_(id), name_(name), vendor_(vendor), type_(type), + direction_(direction), size_(size), enumStrMap_(enumStrMap) { for (const auto &pair : enumStrMap_) reverseMap_[pair.second] = pair.first; @@ -450,6 +451,37 @@ ControlId::ControlId(unsigned int id, const std::string &name, * \return The control data type */ +/** + * \fn DirectionFlags direction() const + * \brief Return the direction that the control can be used in + * + * This is similar to \sa isInput() and \sa isOutput(), but returns the flags + * direction instead of booleans for each direction. + * + * \return The direction flags corresponding to if the control can be used as + * an input control or as output metadata + */ + +/** + * \fn bool ControlId::isInput() const + * \brief Determine if the control is available to be used as an input control + * + * Controls can be used either as input in controls, or as output in metadata. + * This function checks if the control is allowed to be used as the former. + * + * \return True if the control can be used as an input control, false otherwise + */ + +/** + * \fn bool ControlId::isOutput() const + * \brief Determine if the control is available to be used in output metadata + * + * Controls can be used either as input in controls, or as output in metadata. + * This function checks if the control is allowed to be used as the latter. + * + * \return True if the control can be returned in output metadata, false otherwise + */ + /** * \fn bool ControlId::isArray() const * \brief Determine if the control is an array control @@ -487,6 +519,22 @@ ControlId::ControlId(unsigned int id, const std::string &name, * \return True if \a lhs.id() is equal to \a rhs, false otherwise */ +/** + * \enum ControlId::Direction + * \brief The direction the control is capable of being passed from/to + * + * \var ControlId::Direction::In + * \brief The control can be passed as input in controls + * + * \var ControlId::Direction::Out + * \brief The control can be returned as output in metadata + */ + +/** + * \typedef ControlId::DirectionFlags + * \brief A wrapper for ControlId::Direction so that it can be used as flags + */ + /** * \class Control * \brief Describe a control and its intrinsic properties @@ -520,6 +568,8 @@ ControlId::ControlId(unsigned int id, const std::string &name, * \param[in] id The control numerical ID * \param[in] name The control name * \param[in] vendor The vendor name + * \param[in] direction The direction of the control, if it can be used in + * Controls or Metadata * \param[in] enumStrMap The map from enum names to values (optional) * * The control data type is automatically deduced from the template type T. diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp index 664b74afe6a1..2f65a43a0547 100644 --- a/src/libcamera/v4l2_device.cpp +++ b/src/libcamera/v4l2_device.cpp @@ -565,7 +565,15 @@ std::unique_ptr V4L2Device::v4l2ControlId(const v4l2_query_ext_ctrl & const std::string name(static_cast(ctrl.name), len); const ControlType type = v4l2CtrlType(ctrl.type); - return std::make_unique(ctrl.id, name, "v4l2", type); + ControlId::DirectionFlags flags; + if (ctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) + flags = ControlId::Direction::Out; + else if (ctrl.flags & V4L2_CTRL_FLAG_WRITE_ONLY) + flags = ControlId::Direction::In; + else + flags = ControlId::Direction::In | ControlId::Direction::Out; + + return std::make_unique(ctrl.id, name, "v4l2", type, flags); } /** From patchwork Thu Dec 12 05:24:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 22298 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 4B0C0C3260 for ; Thu, 12 Dec 2024 05:25:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B431667ECC; Thu, 12 Dec 2024 06:25:19 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="sj+8+o4+"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 91D6E67EC7 for ; Thu, 12 Dec 2024 06:25:14 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:39eb:989c:b016:217b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C7A25316; Thu, 12 Dec 2024 06:24:39 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1733981081; bh=8IyJy90D4lCm9eoq8UzJz+G25Kc2WGnEHEjOERbx1n0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sj+8+o4+VJh4qGFxRcGaoj2i1EUa1r8hwVWEPxnp1YfoMq8XthxkVZUs1Z7LZw81K HPPkJMKfJe7uPjxusrZ4ue//C0mXXbA3VlkEBEA8YSCpP91pjf8PZzAdnbXZ6cMZGI 7GTlUIalP6zcGlckBlTc3uHOGn8TbnEw2EWK37fs= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Kieran Bingham , Laurent Pinchart Subject: [PATCH v4 4/4] apps: cam: Print control direction information Date: Thu, 12 Dec 2024 14:24:38 +0900 Message-Id: <20241212052438.1547410-5-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20241212052438.1547410-1-paul.elder@ideasonboard.com> References: <20241212052438.1547410-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 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: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that there is support for retrieving the allowed directions of a control, print this information when listing controls. Sample output: $ cam --list-controls -c 2 Using camera Virtual0 as cam0 Control: [inout] draft::FaceDetectMode: - FaceDetectModeOff (0) Control: [inout] libcamera::FrameDurationLimits: [16666..33333] Size: 2 Signed-off-by: Paul Elder Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- No change in v4 No change in v3 Changes in v2: - s/i/in/, s/o/out/ so that the output is easier to read --- src/apps/cam/camera_session.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp index 6e9890ccfda1..9e93482775c3 100644 --- a/src/apps/cam/camera_session.cpp +++ b/src/apps/cam/camera_session.cpp @@ -159,12 +159,18 @@ CameraSession::~CameraSession() void CameraSession::listControls() const { for (const auto &[id, info] : camera_->controls()) { + std::stringstream io; + io << "[" + << (id->isInput() ? "in" : " ") + << (id->isOutput() ? "out" : " ") + << "] "; + if (info.values().empty()) { - std::cout << "Control: " + std::cout << "Control: " << io.str() << id->vendor() << "::" << id->name() << ": " << info.toString() << std::endl; } else { - std::cout << "Control: " + std::cout << "Control: " << io.str() << id->vendor() << "::" << id->name() << ":" << std::endl; for (const auto &value : info.values()) {