[libcamera-devel] [PATCH v2 5/6] libcamera: controls: Use vendor tags for draft controls and properties

Laurent Pinchart laurent.pinchart at ideasonboard.com
Thu Nov 23 10:30:04 CET 2023


Hi Naush,

Thank you for the patch.

On Tue, Nov 21, 2023 at 02:53:49PM +0000, Naushir Patuck via libcamera-devel wrote:
> 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 <naush at raspberrypi.com>
> ---
>  include/libcamera/control_ids.h.in            |   6 -
>  include/libcamera/meson.build                 |   3 +-
>  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              |  16 +-
>  src/libcamera/control_ids.yaml                | 232 -----------------
>  src/libcamera/control_ids_draft.yaml          | 240 ++++++++++++++++++
>  src/libcamera/meson.build                     |   2 +-
>  src/libcamera/property_ids.cpp.in             |  16 +-
>  src/libcamera/property_ids.yaml               |  33 ---
>  src/libcamera/property_ids_draft.yaml         |  39 +++
>  src/py/libcamera/gen-py-controls.py           |   5 +-
>  src/py/libcamera/meson.build                  |   6 +-
>  src/py/libcamera/py_controls_generated.cpp.in |   5 -
>  .../libcamera/py_properties_generated.cpp.in  |   3 +-
>  utils/gen-controls.py                         |  39 +--
>  17 files changed, 303 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 6cac385fdee4..63fc120a0818 100644
> --- a/include/libcamera/meson.build
> +++ b/include/libcamera/meson.build
> @@ -76,7 +76,8 @@ foreach header, mode : control_source_files
>          vendor_prop_files = vendor_files
>      endif
>  
> -    input_files = files('../../src/libcamera/' + header + '.yaml')
> +    input_files = files(['../../src/libcamera/' + header +'.yaml',
> +                         '../../src/libcamera/' + header +'_draft.yaml'])
>  
>      foreach file : vendor_files
>          input_files += files('../../src/libcamera/' + file)
> 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<int32_t>());
> 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<RPiController::DenoiseAlgorithm *>(
>  				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 d26eb930b30c..284589567cfb 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,13 +33,8 @@ ${vendor_controls_doc}
>   */
>  ${controls_def}
>  
> -namespace draft {
> -
> -${draft_controls_def}
> -
> -} /* namespace draft */
> -
>  ${vendor_controls_def}
> +
>  #endif
>  
>  /**
> diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml
> index ff74ce1deedb..76fb9347d8e3 100644
> --- a/src/libcamera/control_ids.yaml
> +++ b/src/libcamera/control_ids.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..e4f53ea51d7a
> --- /dev/null
> +++ b/src/libcamera/control_ids_draft.yaml
> @@ -0,0 +1,240 @@
> +# 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
> +      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/meson.build b/src/libcamera/meson.build
> index 303eee84a77e..e965b72e015a 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -128,7 +128,7 @@ endif
>  control_sources = []
>  
>  foreach source, mode : control_source_files
> -    input_files = files(source +'.yaml')
> +    input_files = files([source +'.yaml', source + '_draft.yaml'])
>  
>      # Add the vendor specific files to the input.
>      if mode == 'controls'
> diff --git a/src/libcamera/property_ids.cpp.in b/src/libcamera/property_ids.cpp.in
> index ddbe714c3f00..b72e12e4cc70 100644
> --- a/src/libcamera/property_ids.cpp.in
> +++ b/src/libcamera/property_ids.cpp.in
> @@ -23,14 +23,7 @@ namespace properties {
>  
>  ${controls_doc}
>  
> -/**
> - * \brief Namespace for libcamera draft properties
> - */
> -namespace draft {
> -
> -${draft_controls_doc}
> -
> -} /* namespace draft */
> +${vendor_controls_doc}
>  
>  ${vendor_controls_doc}

This doesn't look right, vendor_controls_doc is used twice.

>  
> @@ -41,13 +34,8 @@ ${vendor_controls_doc}
>   */
>  ${controls_def}
>  
> -namespace draft {
> -
> -${draft_controls_def}
> -
> -} /* namespace draft */
> -
>  ${vendor_controls_def}
> +
>  #endif
>  
>  /**
> diff --git a/src/libcamera/property_ids.yaml b/src/libcamera/property_ids.yaml
> index 45f3609b4236..834454a4e087 100644
> --- a/src/libcamera/property_ids.yaml
> +++ b/src/libcamera/property_ids.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 e2ddad8581fd..e0695635dbcc 100755
> --- a/src/py/libcamera/gen-py-controls.py
> +++ b/src/py/libcamera/gen-py-controls.py
> @@ -36,10 +36,7 @@ def generate_py(controls, mode):
>                  vendor_defs.append('\tauto {} = py::class_<Py{}Controls>(controls, \"{}\");'.format(vendor, vendor, 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/meson.build b/src/py/libcamera/meson.build
> index ea38ad6ca829..9641862a4e9b 100644
> --- a/src/py/libcamera/meson.build
> +++ b/src/py/libcamera/meson.build
> @@ -28,7 +28,8 @@ pycamera_sources = files([
>  
>  # Generate controls
>  
> -gen_py_controls_input_files = files('../../libcamera/control_ids.yaml')
> +gen_py_controls_input_files = files(['../../libcamera/control_ids.yaml',
> +                                     '../../libcamera/control_ids_draft.yaml'])
>  gen_py_controls_template = files('py_controls_generated.cpp.in')
>  
>  gen_py_controls = files('gen-py-controls.py')
> @@ -45,7 +46,8 @@ pycamera_sources += custom_target('py_gen_controls',
>  
>  # Generate properties
>  
> -gen_py_property_enums_input_files = files('../../libcamera/property_ids.yaml')
> +gen_py_property_enums_input_files = files(['../../libcamera/property_ids.yaml',
> +                                           '../../libcamera/property_ids_draft.yaml'])
>  gen_py_properties_template = files('py_properties_generated.cpp.in')
>  
>  foreach file : vendor_prop_files
> 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_<PyControls>(m, "controls");
> -	auto draft = py::class_<PyDraftControls>(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..1fa1967a9672 100644
> --- a/src/py/libcamera/py_properties_generated.cpp.in
> +++ b/src/py/libcamera/py_properties_generated.cpp.in
> @@ -26,8 +26,7 @@ ${vendors_class_def}
>  void init_py_properties_generated(py::module& m)
>  {
>  	auto controls = py::class_<PyProperties>(m, "properties");
> -	auto draft = py::class_<PyDraftProperties>(controls, "draft");
> -${vendors_defs}
> +${vendors_defs}	

Trailing whitespace here.

With those small issues addressed,

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

>  
>  ${controls}
>  }
> diff --git a/utils/gen-controls.py b/utils/gen-controls.py
> index 9eede8940f24..f20e4eafcc2f 100755
> --- a/utils/gen-controls.py
> +++ b/utils/gen-controls.py
> @@ -85,11 +85,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"""
> @@ -100,12 +95,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')
> @@ -158,7 +147,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] = []
> @@ -209,7 +198,7 @@ ${description}
>          target_doc.append(doc_template.substitute(info))
>          target_def.append(def_template.substitute(info))
>  
> -        target_ctrls_map.append('\t{ ' + id_name + ', &' + ctrl.q_name + ' },')
> +        target_ctrls_map.append('\t{ ' + id_name + ', &' + ctrl.name + ' },')
>  
>      vendor_ctrl_doc_sub = []
>      vendor_ctrl_template = string.Template('''
> @@ -219,11 +208,11 @@ ${vendor_controls_str}
>  
>  } /* namespace ${vendor} */''')
>  
> -    for vendor in [v for v in ctrls_map.keys() if v not in ['libcamera', 'draft']]:
> +    for vendor in [v for v in ctrls_map.keys() if v != '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_map.keys() if v not in ['libcamera', 'draft']]:
> +    for vendor in [v for v in ctrls_map.keys() if v != 'libcamera']:
>          vendor_ctrl_def_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n'.join(ctrls_def[vendor])}))
>  
>      vendor_ctrl_map_sub = []
> @@ -241,16 +230,14 @@ ${vendor_controls_map}
>  } /* namespace ${vendor} */
>  ''')
>  
> -    for vendor in [v for v in ctrls_map.keys() if v not in ['libcamera', 'draft']]:
> +    for vendor in [v for v in ctrls_map.keys() if v != 'libcamera']:
>          vendor_ctrl_map_sub.append(vendor_ctrl_template.substitute({'vendor': vendor,
>                                                                      'vendor_controls_map': '\n'.join(ctrls_map[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['libcamera'] + ctrls_map['draft']),
> +        'controls_map': '\n'.join(ctrls_map['libcamera']),
>          'vendor_controls_doc': '\n'.join(vendor_ctrl_doc_sub),
>          'vendor_controls_def': '\n'.join(vendor_ctrl_def_sub),
>          'vendor_controls_map': '\n'.join(vendor_ctrl_map_sub),
> @@ -270,7 +257,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}')
> @@ -278,8 +265,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 = {
> @@ -287,11 +273,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))
> @@ -332,7 +314,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(),
> @@ -342,7 +324,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)
>      }
>  

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list