libcamera: controls: Use vendor tags for draft controls and properties

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@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Naushir Patuck 2023-11-09 12:30:18 +00:00
parent d3365b358f
commit e18a007b9d
15 changed files with 286 additions and 352 deletions

View file

@ -26,12 +26,6 @@ ${controls}
extern const ControlIdMap controls; extern const ControlIdMap controls;
namespace draft {
${draft_controls}
} /* namespace draft */
${vendor_controls} ${vendor_controls}
} /* namespace controls */ } /* namespace controls */

View file

@ -34,10 +34,12 @@ libcamera_headers_install_dir = get_option('includedir') / libcamera_include_dir
controls_map = { controls_map = {
'controls': { 'controls': {
'draft': 'control_ids_draft.yaml',
'core': 'control_ids_core.yaml', 'core': 'control_ids_core.yaml',
}, },
'properties': { 'properties': {
'draft': 'property_ids_draft.yaml',
'core': 'property_ids_core.yaml', 'core': 'property_ids_core.yaml',
} }
} }

View file

@ -23,12 +23,6 @@ ${ids}
${controls} ${controls}
namespace draft {
${draft_controls}
} /* namespace draft */
extern const ControlIdMap properties; extern const ControlIdMap properties;
${vendor_controls} ${vendor_controls}

View file

@ -1024,7 +1024,7 @@ void IpaBase::applyControls(const ControlList &controls)
break; break;
} }
case controls::NOISE_REDUCTION_MODE: case controls::draft::NOISE_REDUCTION_MODE:
/* Handled below in handleControls() */ /* Handled below in handleControls() */
libcameraMetadata_.set(controls::draft::NoiseReductionMode, libcameraMetadata_.set(controls::draft::NoiseReductionMode,
ctrl.second.get<int32_t>()); ctrl.second.get<int32_t>());

View file

@ -260,7 +260,7 @@ void IpaVc4::handleControls(const ControlList &controls)
for (auto const &ctrl : controls) { for (auto const &ctrl : controls) {
switch (ctrl.first) { switch (ctrl.first) {
case controls::NOISE_REDUCTION_MODE: { case controls::draft::NOISE_REDUCTION_MODE: {
RPiController::DenoiseAlgorithm *sdn = dynamic_cast<RPiController::DenoiseAlgorithm *>( RPiController::DenoiseAlgorithm *sdn = dynamic_cast<RPiController::DenoiseAlgorithm *>(
controller_.getAlgorithm("SDN")); controller_.getAlgorithm("SDN"));
/* Some platforms may have a combined "denoise" algorithm instead. */ /* Some platforms may have a combined "denoise" algorithm instead. */

View file

@ -24,15 +24,6 @@ namespace controls {
${controls_doc} ${controls_doc}
/**
* \brief Namespace for libcamera draft controls
*/
namespace draft {
${draft_controls_doc}
} /* namespace draft */
${vendor_controls_doc} ${vendor_controls_doc}
#ifndef __DOXYGEN__ #ifndef __DOXYGEN__
@ -42,12 +33,6 @@ ${vendor_controls_doc}
*/ */
${controls_def} ${controls_def}
namespace draft {
${draft_controls_def}
} /* namespace draft */
${vendor_controls_def} ${vendor_controls_def}
#endif #endif

View file

@ -865,236 +865,4 @@ controls:
description: | description: |
This is a long exposure image. 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).
... ...

View file

@ -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).
...

View file

@ -23,15 +23,6 @@ namespace properties {
${controls_doc} ${controls_doc}
/**
* \brief Namespace for libcamera draft properties
*/
namespace draft {
${draft_controls_doc}
} /* namespace draft */
${vendor_controls_doc} ${vendor_controls_doc}
#ifndef __DOXYGEN__ #ifndef __DOXYGEN__
@ -41,12 +32,6 @@ ${vendor_controls_doc}
*/ */
${controls_def} ${controls_def}
namespace draft {
${draft_controls_def}
} /* namespace draft */
${vendor_controls_def} ${vendor_controls_def}
#endif #endif

View file

@ -701,37 +701,4 @@ controls:
Different cameras may report identical devices. 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.
... ...

View file

@ -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.
...

View file

@ -32,14 +32,12 @@ def generate_py(controls, mode):
name, ctrl = ctrls.popitem() name, ctrl = ctrls.popitem()
if vendor not in vendors and vendor != 'libcamera': if vendor not in vendors and vendor != 'libcamera':
vendors_class_def.append('class Py{}Controls\n{{\n}};\n'.format(vendor)) vendor_mode_str = f'{vendor.capitalize()}{mode.capitalize()}'
vendor_defs.append('\tauto {} = py::class_<Py{}Controls>(controls, \"{}\");'.format(vendor, vendor, vendor)) vendors_class_def.append('class Py{}\n{{\n}};\n'.format(vendor_mode_str))
vendor_defs.append('\tauto {} = py::class_<Py{}>(controls, \"{}\");'.format(vendor, vendor_mode_str, vendor))
vendors.append(vendor) vendors.append(vendor)
if ctrl.get('draft'): if vendor != 'libcamera':
ns = 'libcamera::{}::draft::'.format(mode)
container = 'draft'
elif vendor != 'libcamera':
ns = 'libcamera::{}::{}::'.format(mode, vendor) ns = 'libcamera::{}::{}::'.format(mode, vendor)
container = vendor container = vendor
else: else:

View file

@ -17,16 +17,11 @@ class PyControls
{ {
}; };
class PyDraftControls
{
};
${vendors_class_def} ${vendors_class_def}
void init_py_controls_generated(py::module& m) void init_py_controls_generated(py::module& m)
{ {
auto controls = py::class_<PyControls>(m, "controls"); auto controls = py::class_<PyControls>(m, "controls");
auto draft = py::class_<PyDraftControls>(controls, "draft");
${vendors_defs} ${vendors_defs}
${controls} ${controls}

View file

@ -17,16 +17,11 @@ class PyProperties
{ {
}; };
class PyDraftProperties
{
};
${vendors_class_def} ${vendors_class_def}
void init_py_properties_generated(py::module& m) void init_py_properties_generated(py::module& m)
{ {
auto controls = py::class_<PyProperties>(m, "properties"); auto controls = py::class_<PyProperties>(m, "properties");
auto draft = py::class_<PyDraftProperties>(controls, "draft");
${vendors_defs} ${vendors_defs}
${controls} ${controls}

View file

@ -86,11 +86,6 @@ class Control(object):
"""Is the control an enumeration""" """Is the control an enumeration"""
return self.__enum_values is not None 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 @property
def vendor(self): def vendor(self):
"""The vendor string, or None""" """The vendor string, or None"""
@ -101,12 +96,6 @@ class Control(object):
"""The control name (CamelCase)""" """The control name (CamelCase)"""
return self.__name 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 @property
def type(self): def type(self):
typ = self.__data.get('type') typ = self.__data.get('type')
@ -159,7 +148,7 @@ ${description}
for ctrl in controls: for ctrl in controls:
id_name = snake_case(ctrl.name).upper() 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: if vendor not in ctrls_doc:
ctrls_doc[vendor] = [] ctrls_doc[vendor] = []
ctrls_def[vendor] = [] ctrls_def[vendor] = []
@ -208,7 +197,8 @@ ${description}
target_doc.append(doc_template.substitute(info)) target_doc.append(doc_template.substitute(info))
target_def.append(def_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_doc_sub = []
vendor_ctrl_template = string.Template(''' vendor_ctrl_template = string.Template('''
@ -221,18 +211,16 @@ ${vendor_controls_str}
} /* namespace ${vendor} */''') } /* 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_doc_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n\n'.join(ctrls_doc[vendor])}))
vendor_ctrl_def_sub = [] 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])})) vendor_ctrl_def_sub.append(vendor_ctrl_template.substitute({'vendor': vendor, 'vendor_controls_str': '\n'.join(ctrls_def[vendor])}))
return { return {
'controls_doc': '\n\n'.join(ctrls_doc['libcamera']), 'controls_doc': '\n\n'.join(ctrls_doc['libcamera']),
'controls_def': '\n'.join(ctrls_def['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), 'controls_map': '\n'.join(ctrls_map),
'vendor_controls_doc': '\n'.join(vendor_ctrl_doc_sub), 'vendor_controls_doc': '\n'.join(vendor_ctrl_doc_sub),
'vendor_controls_def': '\n'.join(vendor_ctrl_def_sub), 'vendor_controls_def': '\n'.join(vendor_ctrl_def_sub),
@ -252,7 +240,7 @@ def generate_h(controls, mode, ranges):
for ctrl in controls: for ctrl in controls:
id_name = snake_case(ctrl.name).upper() 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 ctrls:
if vendor not in ranges.keys(): if vendor not in ranges.keys():
raise RuntimeError(f'Control id range is not defined for vendor {vendor}') raise RuntimeError(f'Control id range is not defined for vendor {vendor}')
@ -260,8 +248,7 @@ def generate_h(controls, mode, ranges):
ids[vendor] = [] ids[vendor] = []
ctrls[vendor] = [] ctrls[vendor] = []
# Core and draft controls use the same ID value target_ids = ids[vendor]
target_ids = ids['libcamera'] if vendor in ['libcamera', 'draft'] else ids[vendor]
target_ids.append('\t' + id_name + ' = ' + str(id_value[vendor]) + ',') target_ids.append('\t' + id_name + ' = ' + str(id_value[vendor]) + ',')
info = { info = {
@ -269,11 +256,7 @@ def generate_h(controls, mode, ranges):
'type': ctrl.type, 'type': ctrl.type,
} }
target_ctrls = ctrls['libcamera'] target_ctrls = ctrls[vendor]
if ctrl.is_draft:
target_ctrls = ctrls['draft']
elif vendor != 'libcamera':
target_ctrls = ctrls[vendor]
if ctrl.is_enum: if ctrl.is_enum:
target_ctrls.append(enum_template_start.substitute(info)) target_ctrls.append(enum_template_start.substitute(info))
@ -312,7 +295,7 @@ ${vendor_controls}
''') ''')
vendor_sub = [] 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_sub.append(vendor_template.substitute({'mode': mode.upper(),
'vendor': vendor, 'vendor': vendor,
'vendor_def': vendor.upper(), 'vendor_def': vendor.upper(),
@ -322,7 +305,6 @@ ${vendor_controls}
return { return {
'ids': '\n'.join(ids['libcamera']), 'ids': '\n'.join(ids['libcamera']),
'controls': '\n'.join(ctrls['libcamera']), 'controls': '\n'.join(ctrls['libcamera']),
'draft_controls': '\n'.join(ctrls['draft']),
'vendor_controls': '\n'.join(vendor_sub) 'vendor_controls': '\n'.join(vendor_sub)
} }