[RFC PATCH v1] libcamera: controls: Remove common enum prefix

Barnabás Pőcze barnabas.pocze at ideasonboard.com
Thu May 22 17:28:40 CEST 2025


2025. 05. 22. 17:22 keltezéssel, Laurent Pinchart írta:
> On Thu, May 22, 2025 at 05:10:20PM +0200, Barnabás Pőcze wrote:
>> 2025. 05. 22. 17:01 keltezéssel, Laurent Pinchart írta:
>>> On Thu, May 22, 2025 at 04:22:00PM +0200, Barnabás Pőcze wrote:
>>>> 2025. 05. 22. 15:47 keltezéssel, Kieran Bingham írta:
>>>>> Quoting Paul Elder (2025-05-22 14:31:34)
>>>>>> Quoting Barnabás Pőcze (2025-05-17 00:41:31)
>>>>>>> At the moment all enumerators have a common prefix, in many cases
>>>>>>> the name of the control, but not always. This is reasonable for
>>>>>>> C++ because currently non-scoped enumerations are used, so some
>>>>>>> kind of prefix is needed to differentiate common names like `Auto`,
>>>>>>> `Manual`, `On`, `Off`, etc.
>>>>>>>
>>>>>>> However, for e.g. language bindings, it might be more desirable to
>>>>>>> have access to the the unprefixed name. (This is even the case for
>>>>>>> C++ scoped enumerations.)
>>>>>>>
>>>>>>> Currently, both the gstreamer and python bindings have extra code
>>>>>>> to strip the common prefix. So instead of doing that separately in
>>>>>>> every binding, etc. store the unprefixed name in the source of truth,
>>>>>>> the control/property definition yaml files.
>>>
>>> This is a good idea.
>>>
>>> There's a paragraph missing here. The patch does more than changing the
>>> YAML files, it also affects the generated code, the effect should be
>>> explained here.
>>>
>>>>>>> This is an API break, but it only affects C++ because gst and py already
>>>>>>> strip the common prefix (TODO: recheck again). And in case of C++ it is
>>>>>>> only an API break for enum controls where the common prefix is not the
>>>>>>> same as the control name:
>>>>>>>
>>>>>>>       * properties::Location
>>>>>>>       * properties::draft::ColorFilterArrangement
>>>>>>>       * controls::AwbMode
>>>>>>>       * controls::AeConstraintMode
>>>>>>>       * controls::AeFlickerMode
>>>>>>>       * controls::AeMeteringMode
>>>>>>>       * controls::AeExposureMode
>>>>>>>       * controls::draft::ColorCorrectionAberrationMode
>>>>>>>       * TODO: check again
>>>>>>>
>>>>>>> Signed-off-by: Barnabás Pőcze <barnabas.pocze at ideasonboard.com>
>>>>>>
>>>>>> Looks good to me, both the idea and the implementation. I guess we just have to
>>>>>> check how bad the ABI and API breakages are to see when we can merge it. Which
>>>>>> means we need to ask Kieran.
>>>>>
>>>>> I'm fine in principle with the patch too indeed, but I'd like to get at
>>>>> least the next release out with out ABI breakage.
>>>>>
>>>>> Fortunately that's 'very soon' as the next kernel release is this
>>>>> weekend.
>>>>>
>>>>> But wait, this is API only breakage. I wonder - is there anything we can
>>>>> do here with a preprocessor to support it in the interim with something
>>>>> like:
>>>>>
>>>>> [[deprecated("CameraLocationExternal is deprecated. Use LocationExternal instead.")]]
>>>>> #define CameraLocationExternal LocationExternal
>>>
>>> Attributes can't be applied to macros.
>>>
>>>>> or something like
>>>>>
>>>>> [[deprecated("Use LocationExternal instead")]]
>>>>> constexpr auto CameraLocationExternal = LocationExternal;
>>>>>
>>>>> ?
>>>>>
>>>>> With that - we could already merge this as I think it
>>>>> wouldn't directly "break" users(compilation) - and there's no underlying
>>>>> ABI break?
>>>>
>>>> I think the most significant effect is that some configuration parsers:
>>>>
>>>>      * ipa::AgcMeanLuminance::parseConstraintModes: ipu3, mali-c55, rkisp1
>>>>      * ipa::AwbAlgorithm::parseModeConfigs: rkisp1
>>>>      * ipa::rkisp1::algorithms::Agc::parseMeteringModes: rkisp1
>>>>      * ConfigParser::parseLocation: virtual
>>>>
>>>> use the `XYZNameValueMap`s, so this has an effect on configuration files.
>>>
>>> Why do we need to change configuration files ? We may want to, to keep
>>> the configuration file names in sync with the enum names, but it's a
>>> separate change that I would split to a separate patch.
>>
>> Because some configuration files are parsed directly based on the names
>> of the enumerators, via the `XYZNameValueMap` map generated for each enum.
>> So if the enumerators' names' are changed, then the certain configuration
>> files will no longer be "valid".
> 
> Ah :-/
> 
> Are there any affected configuration file other than the virtual
> pipeline handler configuration file ?

I was able to find only one:
   * utils/tuning/config-example.yaml

(PSA: There are files that I have missed in this patch.)


Regards,
Barnabás Pőcze

> 
>>>> Adding the `deprecated` attribute is I think a good idea, but more changes
>>>> would be needed to warn about deprecations in the configuration files.
>>>>
>>>>>> Reviewed-by: Paul Elder <paul.elder at ideasonboard.com>
>>>>>>
>>>>>>> ---
>>>>>>>     include/libcamera/control_ids.h.in            |   2 +-
>>>>>>>     src/android/camera_device.cpp                 |   6 +-
>>>>>>>     src/android/camera_hal_manager.cpp            |   2 +-
>>>>>>>     src/apps/cam/main.cpp                         |   6 +-
>>>>>>>     src/apps/qcam/cam_select_dialog.cpp           |   6 +-
>>>>>>>     src/gstreamer/gstlibcamera-controls.cpp.in    |   4 +-
>>>>>>>     src/ipa/libipa/agc_mean_luminance.cpp         |   4 +-
>>>>>>>     src/ipa/libipa/awb_bayes.cpp                  |   4 +-
>>>>>>>     src/ipa/rpi/common/ipa_base.cpp               |  54 ++--
>>>>>>>     src/libcamera/control_ids.cpp.in              |   6 +-
>>>>>>>     src/libcamera/control_ids_core.yaml           | 240 +++++++++---------
>>>>>>>     src/libcamera/control_ids_draft.yaml          |  54 ++--
>>>>>>>     src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |   4 +-
>>>>>>>     src/libcamera/pipeline/virtual/README.md      |   2 +-
>>>>>>>     .../pipeline/virtual/config_parser.cpp        |   4 +-
>>>>>>>     .../pipeline/virtual/data/virtual.yaml        |   6 +-
>>>>>>>     src/libcamera/property_ids_core.yaml          |   6 +-
>>>>>>>     src/libcamera/sensor/camera_sensor_legacy.cpp |  18 +-
>>>>>>>     src/libcamera/sensor/camera_sensor_raw.cpp    |  18 +-
>>>>>>>     src/py/libcamera/gen-py-controls.py           |  28 --
>>>>>>>     src/py/libcamera/py_controls_generated.cpp.in |   2 +-
>>>>>>>     utils/codegen/controls.py                     |  19 +-
>>>>>>>     utils/codegen/gen-gst-controls.py             |  17 --
>>>>>>>     23 files changed, 242 insertions(+), 270 deletions(-)
>>>>>>>
>>>>>>> diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in
>>>>>>> index 5d0594c68..2baa59bbd 100644
>>>>>>> --- a/include/libcamera/control_ids.h.in
>>>>>>> +++ b/include/libcamera/control_ids.h.in
>>>>>>> @@ -42,7 +42,7 @@ enum {
>>>>>>>     {% if ctrl.is_enum -%}
>>>>>>>     enum {{ctrl.name}}Enum {
>>>>>>>     {%- for enum in ctrl.enum_values %}
>>>>>>> -       {{enum.name}} = {{enum.value}},
>>>>>>> +       {{enum.prefixed_name}} = {{enum.value}},
>>>>>>>     {%- endfor %}
>>>>>>>     };
>>>>>>>     extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.name}}Values;
>>>>>>> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
>>>>>>> index a038131ae..21e245bf8 100644
>>>>>>> --- a/src/android/camera_device.cpp
>>>>>>> +++ b/src/android/camera_device.cpp
>>>>>>> @@ -310,13 +310,13 @@ int CameraDevice::initialize(const CameraConfigData *cameraConfigData)
>>>>>>>            const auto &location = properties.get(properties::Location);
>>>>>>>            if (location) {
>>>>>>>                    switch (*location) {
>>>>>>> -               case properties::CameraLocationFront:
>>>>>>> +               case properties::LocationFront:
>>>>>>>                            facing_ = CAMERA_FACING_FRONT;
>>>>>>>                            break;
>>>>>>> -               case properties::CameraLocationBack:
>>>>>>> +               case properties::LocationBack:
>>>>>>>                            facing_ = CAMERA_FACING_BACK;
>>>>>>>                            break;
>>>>>>> -               case properties::CameraLocationExternal:
>>>>>>> +               case properties::LocationExternal:
>>>>>>>                            /*
>>>>>>>                             * If the camera is reported as external, but the
>>>>>>>                             * CameraHalManager has overriden it, use what is
>>>>>>> diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp
>>>>>>> index 7500c749b..c44003309 100644
>>>>>>> --- a/src/android/camera_hal_manager.cpp
>>>>>>> +++ b/src/android/camera_hal_manager.cpp
>>>>>>> @@ -125,7 +125,7 @@ void CameraHalManager::cameraAdded(std::shared_ptr<Camera> cam)
>>>>>>>                     * Now check if this is an external camera and assign
>>>>>>>                     * its id accordingly.
>>>>>>>                     */
>>>>>>> -               if (cameraLocation(cam.get()) == properties::CameraLocationExternal) {
>>>>>>> +               if (cameraLocation(cam.get()) == properties::LocationExternal) {
>>>>>>>                            isCameraExternal = true;
>>>>>>>                            id = nextExternalCameraId_;
>>>>>>>                    } else {
>>>>>>> diff --git a/src/apps/cam/main.cpp b/src/apps/cam/main.cpp
>>>>>>> index fa266eca6..5a9989922 100644
>>>>>>> --- a/src/apps/cam/main.cpp
>>>>>>> +++ b/src/apps/cam/main.cpp
>>>>>>> @@ -316,15 +316,15 @@ std::string CamApp::cameraName(const Camera *camera)
>>>>>>>            const auto &location = props.get(properties::Location);
>>>>>>>            if (location) {
>>>>>>>                    switch (*location) {
>>>>>>> -               case properties::CameraLocationFront:
>>>>>>> +               case properties::LocationFront:
>>>>>>>                            addModel = false;
>>>>>>>                            name = "Internal front camera ";
>>>>>>>                            break;
>>>>>>> -               case properties::CameraLocationBack:
>>>>>>> +               case properties::LocationBack:
>>>>>>>                            addModel = false;
>>>>>>>                            name = "Internal back camera ";
>>>>>>>                            break;
>>>>>>> -               case properties::CameraLocationExternal:
>>>>>>> +               case properties::LocationExternal:
>>>>>>>                            name = "External camera ";
>>>>>>>                            break;
>>>>>>>                    }
>>>>>>> diff --git a/src/apps/qcam/cam_select_dialog.cpp b/src/apps/qcam/cam_select_dialog.cpp
>>>>>>> index 6b6d0713c..2f8417b34 100644
>>>>>>> --- a/src/apps/qcam/cam_select_dialog.cpp
>>>>>>> +++ b/src/apps/qcam/cam_select_dialog.cpp
>>>>>>> @@ -98,13 +98,13 @@ void CameraSelectorDialog::updateCameraInfo(QString cameraId)
>>>>>>>            const auto &location = properties.get(libcamera::properties::Location);
>>>>>>>            if (location) {
>>>>>>>                    switch (*location) {
>>>>>>> -               case libcamera::properties::CameraLocationFront:
>>>>>>> +               case libcamera::properties::LocationFront:
>>>>>>>                            cameraLocation_->setText("Internal front camera");
>>>>>>>                            break;
>>>>>>> -               case libcamera::properties::CameraLocationBack:
>>>>>>> +               case libcamera::properties::LocationBack:
>>>>>>>                            cameraLocation_->setText("Internal back camera");
>>>>>>>                            break;
>>>>>>> -               case libcamera::properties::CameraLocationExternal:
>>>>>>> +               case libcamera::properties::LocationExternal:
>>>>>>>                            cameraLocation_->setText("External camera");
>>>>>>>                            break;
>>>>>>>                    default:
>>>>>>> diff --git a/src/gstreamer/gstlibcamera-controls.cpp.in b/src/gstreamer/gstlibcamera-controls.cpp.in
>>>>>>> index 89c530da0..592865bc2 100644
>>>>>>> --- a/src/gstreamer/gstlibcamera-controls.cpp.in
>>>>>>> +++ b/src/gstreamer/gstlibcamera-controls.cpp.in
>>>>>>> @@ -63,9 +63,9 @@ static Rectangle value_get_rectangle(const GValue *value)
>>>>>>>     static const GEnumValue {{ ctrl.name|snake_case }}_types[] = {
>>>>>>>     {%- for enum in ctrl.enum_values %}
>>>>>>>            {
>>>>>>> -               controls::{{ ctrl.namespace }}{{ enum.name }},
>>>>>>> +               controls::{{ ctrl.namespace }}{{ enum.prefixed_name }},
>>>>>>>                    {{ enum.description|format_description|indent_str('\t\t') }},
>>>>>>> -               "{{ enum.gst_name }}"
>>>>>>> +               "{{ enum.name|kebab_case }}"
>>>>>>>            },
>>>>>>>     {%- endfor %}
>>>>>>>            {0, NULL, NULL}
>>>>>>> diff --git a/src/ipa/libipa/agc_mean_luminance.cpp b/src/ipa/libipa/agc_mean_luminance.cpp
>>>>>>> index f617fde81..98d250b42 100644
>>>>>>> --- a/src/ipa/libipa/agc_mean_luminance.cpp
>>>>>>> +++ b/src/ipa/libipa/agc_mean_luminance.cpp
>>>>>>> @@ -215,8 +215,8 @@ int AgcMeanLuminance::parseConstraintModes(const YamlObject &tuningData)
>>>>>>>                            0.5
>>>>>>>                    };
>>>>>>>     
>>>>>>> -               constraintModes_[controls::ConstraintNormal].insert(
>>>>>>> -                       constraintModes_[controls::ConstraintNormal].begin(),
>>>>>>> +               constraintModes_[controls::AeConstraintModeNormal].insert(
>>>>>>> +                       constraintModes_[controls::AeConstraintModeNormal].begin(),
>>>>>>>                            constraint);
>>>>>>>                    availableConstraintModes.push_back(
>>>>>>>                            AeConstraintModeNameValueMap.at("ConstraintNormal"));
>>>>>>> diff --git a/src/ipa/libipa/awb_bayes.cpp b/src/ipa/libipa/awb_bayes.cpp
>>>>>>> index d1d0eaf0e..3d3123508 100644
>>>>>>> --- a/src/ipa/libipa/awb_bayes.cpp
>>>>>>> +++ b/src/ipa/libipa/awb_bayes.cpp
>>>>>>> @@ -170,13 +170,13 @@ int AwbBayes::init(const YamlObject &tuningData)
>>>>>>>                    return ret;
>>>>>>>            }
>>>>>>>     
>>>>>>> -       ret = parseModeConfigs(tuningData, controls::AwbAuto);
>>>>>>> +       ret = parseModeConfigs(tuningData, controls::AwbModeAuto);
>>>>>>>            if (ret) {
>>>>>>>                    LOG(Awb, Error)
>>>>>>>                            << "Failed to parse mode parameter from tuning file";
>>>>>>>                    return ret;
>>>>>>>            }
>>>>>>> -       currentMode_ = &modes_[controls::AwbAuto];
>>>>>>> +       currentMode_ = &modes_[controls::AwbModeAuto];
>>>>>>>     
>>>>>>>            transversePos_ = tuningData["transversePos"].get<double>(0.01);
>>>>>>>            transverseNeg_ = tuningData["transverseNeg"].get<double>(0.01);
>>>>>>> diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
>>>>>>> index e0a93daa9..543f31880 100644
>>>>>>> --- a/src/ipa/rpi/common/ipa_base.cpp
>>>>>>> +++ b/src/ipa/rpi/common/ipa_base.cpp
>>>>>>> @@ -72,9 +72,9 @@ const ControlInfoMap::Map ipaControls{
>>>>>>>            { &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
>>>>>>>            { &controls::AeExposureMode, ControlInfo(controls::AeExposureModeValues) },
>>>>>>>            { &controls::ExposureValue, ControlInfo(-8.0f, 8.0f, 0.0f) },
>>>>>>> -       { &controls::AeFlickerMode, ControlInfo(static_cast<int>(controls::FlickerOff),
>>>>>>> -                                               static_cast<int>(controls::FlickerManual),
>>>>>>> -                                               static_cast<int>(controls::FlickerOff)) },
>>>>>>> +       { &controls::AeFlickerMode, ControlInfo(static_cast<int>(controls::AeFlickerModeOff),
>>>>>>> +                                               static_cast<int>(controls::AeFlickerModeManual),
>>>>>>> +                                               static_cast<int>(controls::AeFlickerModeOff)) },
>>>>>>>            { &controls::AeFlickerPeriod, ControlInfo(100, 1000000) },
>>>>>>>            { &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
>>>>>>>            { &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
>>>>>>> @@ -174,7 +174,7 @@ int32_t IpaBase::init(const IPASettings &settings, const InitParams &params, Ini
>>>>>>>            if (platformCtrlsIt != platformControls.end())
>>>>>>>                    ctrlMap.merge(ControlInfoMap::Map(platformCtrlsIt->second));
>>>>>>>     
>>>>>>> -       monoSensor_ = params.sensorInfo.cfaPattern == properties::draft::ColorFilterArrangementEnum::MONO;
>>>>>>> +       monoSensor_ = params.sensorInfo.cfaPattern == properties::draft::ColorFilterArrangementMONO;
>>>>>>>            if (!monoSensor_)
>>>>>>>                    ctrlMap.merge(ControlInfoMap::Map(ipaColourControls));
>>>>>>>     
>>>>>>> @@ -679,35 +679,35 @@ bool IpaBase::validateLensControls()
>>>>>>>      * must be kept up-to-date by hand.
>>>>>>>      */
>>>>>>>     static const std::map<int32_t, std::string> MeteringModeTable = {
>>>>>>> -       { controls::MeteringCentreWeighted, "centre-weighted" },
>>>>>>> -       { controls::MeteringSpot, "spot" },
>>>>>>> -       { controls::MeteringMatrix, "matrix" },
>>>>>>> -       { controls::MeteringCustom, "custom" },
>>>>>>> +       { controls::AeMeteringModeCentreWeighted, "centre-weighted" },
>>>>>>> +       { controls::AeMeteringModeSpot, "spot" },
>>>>>>> +       { controls::AeMeteringModeMatrix, "matrix" },
>>>>>>> +       { controls::AeMeteringModeCustom, "custom" },
>>>>>>>     };
>>>>>>>     
>>>>>>>     static const std::map<int32_t, std::string> ConstraintModeTable = {
>>>>>>> -       { controls::ConstraintNormal, "normal" },
>>>>>>> -       { controls::ConstraintHighlight, "highlight" },
>>>>>>> -       { controls::ConstraintShadows, "shadows" },
>>>>>>> -       { controls::ConstraintCustom, "custom" },
>>>>>>> +       { controls::AeConstraintModeNormal, "normal" },
>>>>>>> +       { controls::AeConstraintModeHighlight, "highlight" },
>>>>>>> +       { controls::AeConstraintModeShadows, "shadows" },
>>>>>>> +       { controls::AeConstraintModeCustom, "custom" },
>>>>>>>     };
>>>>>>>     
>>>>>>>     static const std::map<int32_t, std::string> ExposureModeTable = {
>>>>>>> -       { controls::ExposureNormal, "normal" },
>>>>>>> -       { controls::ExposureShort, "short" },
>>>>>>> -       { controls::ExposureLong, "long" },
>>>>>>> -       { controls::ExposureCustom, "custom" },
>>>>>>> +       { controls::AeExposureModeNormal, "normal" },
>>>>>>> +       { controls::AeExposureModeShort, "short" },
>>>>>>> +       { controls::AeExposureModeLong, "long" },
>>>>>>> +       { controls::AeExposureModeCustom, "custom" },
>>>>>>>     };
>>>>>>>     
>>>>>>>     static const std::map<int32_t, std::string> AwbModeTable = {
>>>>>>> -       { controls::AwbAuto, "auto" },
>>>>>>> -       { controls::AwbIncandescent, "incandescent" },
>>>>>>> -       { controls::AwbTungsten, "tungsten" },
>>>>>>> -       { controls::AwbFluorescent, "fluorescent" },
>>>>>>> -       { controls::AwbIndoor, "indoor" },
>>>>>>> -       { controls::AwbDaylight, "daylight" },
>>>>>>> -       { controls::AwbCloudy, "cloudy" },
>>>>>>> -       { controls::AwbCustom, "custom" },
>>>>>>> +       { controls::AwbModeAuto, "auto" },
>>>>>>> +       { controls::AwbModeIncandescent, "incandescent" },
>>>>>>> +       { controls::AwbModeTungsten, "tungsten" },
>>>>>>> +       { controls::AwbModeFluorescent, "fluorescent" },
>>>>>>> +       { controls::AwbModeIndoor, "indoor" },
>>>>>>> +       { controls::AwbModeDaylight, "daylight" },
>>>>>>> +       { controls::AwbModeCloudy, "cloudy" },
>>>>>>> +       { controls::AwbModeCustom, "custom" },
>>>>>>>     };
>>>>>>>     
>>>>>>>     static const std::map<int32_t, RPiController::AfAlgorithm::AfMode> AfModeTable = {
>>>>>>> @@ -970,12 +970,12 @@ void IpaBase::applyControls(const ControlList &controls)
>>>>>>>                            bool modeValid = true;
>>>>>>>     
>>>>>>>                            switch (mode) {
>>>>>>> -                       case controls::FlickerOff:
>>>>>>> +                       case controls::AeFlickerModeOff:
>>>>>>>                                    agc->setFlickerPeriod(0us);
>>>>>>>     
>>>>>>>                                    break;
>>>>>>>     
>>>>>>> -                       case controls::FlickerManual:
>>>>>>> +                       case controls::AeFlickerModeManual:
>>>>>>>                                    agc->setFlickerPeriod(flickerState_.manualPeriod);
>>>>>>>     
>>>>>>>                                    break;
>>>>>>> @@ -1009,7 +1009,7 @@ void IpaBase::applyControls(const ControlList &controls)
>>>>>>>                             * We note that it makes no difference if the mode gets set to "manual"
>>>>>>>                             * first, and the period updated after, or vice versa.
>>>>>>>                             */
>>>>>>> -                       if (flickerState_.mode == controls::FlickerManual)
>>>>>>> +                       if (flickerState_.mode == controls::AeFlickerModeManual)
>>>>>>>                                    agc->setFlickerPeriod(flickerState_.manualPeriod);
>>>>>>>     
>>>>>>>                            break;
>>>>>>> diff --git a/src/libcamera/control_ids.cpp.in b/src/libcamera/control_ids.cpp.in
>>>>>>> index 65668d486..c80d12d01 100644
>>>>>>> --- a/src/libcamera/control_ids.cpp.in
>>>>>>> +++ b/src/libcamera/control_ids.cpp.in
>>>>>>> @@ -39,7 +39,7 @@ namespace {{vendor}} {
>>>>>>>      * \brief Supported {{ctrl.name}} values
>>>>>>>     {%- for enum in ctrl.enum_values %}
>>>>>>>      *
>>>>>>> - * \var {{enum.name}}
>>>>>>> + * \var {{enum.prefixed_name}}
>>>>>>>      * \brief {{enum.description|format_description}}
>>>>>>>     {%- endfor %}
>>>>>>>      */
>>>>>>> @@ -81,12 +81,12 @@ namespace {{vendor}} {
>>>>>>>     {% if ctrl.is_enum -%}
>>>>>>>     extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.name}}Values = {
>>>>>>>     {%- for enum in ctrl.enum_values %}
>>>>>>> -       static_cast<{{ctrl.type}}>({{enum.name}}),
>>>>>>> +       static_cast<{{ctrl.type}}>({{enum.prefixed_name}}),
>>>>>>>     {%- endfor %}
>>>>>>>     };
>>>>>>>     extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap = {
>>>>>>>     {%- for enum in ctrl.enum_values %}
>>>>>>> -       { "{{enum.name}}", {{enum.name}} },
>>>>>>> +       { "{{enum.name}}", {{enum.prefixed_name}} },
>>>>>>>     {%- endfor %}
>>>>>>>     };
>>>>>>>     extern const Control<{{ctrl.type}}> {{ctrl.name}}({{ctrl.name|snake_case|upper}}, "{{ctrl.name}}", "{{vendor}}", {{ctrl.direction}}, {{ctrl.name}}NameValueMap);
>>>>>>> diff --git a/src/libcamera/control_ids_core.yaml b/src/libcamera/control_ids_core.yaml
>>>>>>> index aa7448645..97346973b 100644
>>>>>>> --- a/src/libcamera/control_ids_core.yaml
>>>>>>> +++ b/src/libcamera/control_ids_core.yaml
>>>>>>> @@ -42,7 +42,7 @@ controls:
>>>>>>>     
>>>>>>>             When both the exposure time and analogue gain values are configured to
>>>>>>>             be in Manual mode, the AEGC algorithm is quiescent and does not actively
>>>>>>> -        compute any value and the AeState control will report AeStateIdle.
>>>>>>> +        compute any value and the AeState control will report AeState.Idle.
>>>>>>>     
>>>>>>>             When at least the exposure time or analogue gain are configured to be
>>>>>>>             computed by the AEGC algorithm, the AeState control will report if the
>>>>>>> @@ -53,7 +53,7 @@ controls:
>>>>>>>             \sa ExposureTimeMode
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: AeStateIdle
>>>>>>> +        - name: Idle
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 The AEGC algorithm is inactive.
>>>>>>> @@ -61,7 +61,7 @@ controls:
>>>>>>>                 This state is returned when both AnalogueGainMode and
>>>>>>>                 ExposureTimeMode are set to Manual and the algorithm is not
>>>>>>>                 actively computing any value.
>>>>>>> -        - name: AeStateSearching
>>>>>>> +        - name: Searching
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 The AEGC algorithm is actively computing new values, for either the
>>>>>>> @@ -73,8 +73,8 @@ controls:
>>>>>>>     
>>>>>>>                 The AEGC algorithm converges once stable values are computed for
>>>>>>>                 all of the controls set to be computed in Auto mode. Once the
>>>>>>> -            algorithm converges the state is moved to AeStateConverged.
>>>>>>> -        - name: AeStateConverged
>>>>>>> +            algorithm converges the state is moved to AeState.Converged.
>>>>>>> +        - name: Converged
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 The AEGC algorithm has converged.
>>>>>>> @@ -85,7 +85,7 @@ controls:
>>>>>>>     
>>>>>>>                 If the measurements move too far away from the convergence point
>>>>>>>                 then the AEGC algorithm might start adjusting again, in which case
>>>>>>> -            the state is moved to AeStateSearching.
>>>>>>> +            the state is moved to AeState.Searching.
>>>>>>>     
>>>>>>>       # AeMeteringMode needs further attention:
>>>>>>>       # - Auto-generate max enum value.
>>>>>>> @@ -100,16 +100,16 @@ controls:
>>>>>>>             determine the scene brightness. Metering modes may be platform specific
>>>>>>>             and not all metering modes may be supported.
>>>>>>>           enum:
>>>>>>> -        - name: MeteringCentreWeighted
>>>>>>> +        - name: CentreWeighted
>>>>>>>               value: 0
>>>>>>>               description: Centre-weighted metering mode.
>>>>>>> -        - name: MeteringSpot
>>>>>>> +        - name: Spot
>>>>>>>               value: 1
>>>>>>>               description: Spot metering mode.
>>>>>>> -        - name: MeteringMatrix
>>>>>>> +        - name: Matrix
>>>>>>>               value: 2
>>>>>>>               description: Matrix metering mode.
>>>>>>> -        - name: MeteringCustom
>>>>>>> +        - name: Custom
>>>>>>>               value: 3
>>>>>>>               description: Custom metering mode.
>>>>>>>     
>>>>>>> @@ -126,7 +126,7 @@ controls:
>>>>>>>             adjusted to reach the desired target exposure. Constraint modes may be
>>>>>>>             platform specific, and not all constraint modes may be supported.
>>>>>>>           enum:
>>>>>>> -        - name: ConstraintNormal
>>>>>>> +        - name: Normal
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 Default constraint mode.
>>>>>>> @@ -135,7 +135,7 @@ controls:
>>>>>>>                 image so as to reach a reasonable average level. However, highlights
>>>>>>>                 in the image may appear over-exposed and lowlights may appear
>>>>>>>                 under-exposed.
>>>>>>> -        - name: ConstraintHighlight
>>>>>>> +        - name: Highlight
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Highlight constraint mode.
>>>>>>> @@ -143,7 +143,7 @@ controls:
>>>>>>>                 This mode adjusts the exposure levels in order to try and avoid
>>>>>>>                 over-exposing the brightest parts (highlights) of an image.
>>>>>>>                 Other non-highlight parts of the image may appear under-exposed.
>>>>>>> -        - name: ConstraintShadows
>>>>>>> +        - name: Shadows
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 Shadows constraint mode.
>>>>>>> @@ -151,7 +151,7 @@ controls:
>>>>>>>                 This mode adjusts the exposure levels in order to try and avoid
>>>>>>>                 under-exposing the dark parts (shadows) of an image. Other normally
>>>>>>>                 exposed parts of the image may appear over-exposed.
>>>>>>> -        - name: ConstraintCustom
>>>>>>> +        - name: Custom
>>>>>>>               value: 3
>>>>>>>               description: |
>>>>>>>                 Custom constraint mode.
>>>>>>> @@ -176,16 +176,16 @@ controls:
>>>>>>>             \sa ExposureTimeMode
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: ExposureNormal
>>>>>>> +        - name: Normal
>>>>>>>               value: 0
>>>>>>>               description: Default exposure mode.
>>>>>>> -        - name: ExposureShort
>>>>>>> +        - name: Short
>>>>>>>               value: 1
>>>>>>>               description: Exposure mode allowing only short exposure times.
>>>>>>> -        - name: ExposureLong
>>>>>>> +        - name: Long
>>>>>>>               value: 2
>>>>>>>               description: Exposure mode allowing long exposure times.
>>>>>>> -        - name: ExposureCustom
>>>>>>> +        - name: Custom
>>>>>>>               value: 3
>>>>>>>               description: Custom exposure mode.
>>>>>>>     
>>>>>>> @@ -244,7 +244,7 @@ controls:
>>>>>>>             or Auto is not supported by the camera), the camera should use a
>>>>>>>             best-effort default value.
>>>>>>>     
>>>>>>> -        If ExposureTimeModeManual is supported, the ExposureTime control must
>>>>>>> +        If ExposureTimeMode.Manual is supported, the ExposureTime control must
>>>>>>>             also be supported.
>>>>>>>     
>>>>>>>             Cameras that support manual control of the sensor shall support manual
>>>>>>> @@ -258,7 +258,7 @@ controls:
>>>>>>>     
>>>>>>>             \par Flickerless exposure mode transitions
>>>>>>>     
>>>>>>> -        Applications that wish to transition from ExposureTimeModeAuto to direct
>>>>>>> +        Applications that wish to transition from ExposureTimeMode.Auto to direct
>>>>>>>             control of the exposure time without causing extra flicker can do so by
>>>>>>>             selecting an ExposureTime value as close as possible to the last value
>>>>>>>             computed by the auto exposure algorithm in order to avoid any visible
>>>>>>> @@ -272,7 +272,7 @@ controls:
>>>>>>>             immediately specify an ExposureTime value in the same request where
>>>>>>>             ExposureTimeMode is set to Manual. They should instead wait for the
>>>>>>>             first Request where ExposureTimeMode is reported as
>>>>>>> -        ExposureTimeModeManual in the Request metadata, and use the reported
>>>>>>> +        ExposureTimeMode.Manual in the Request metadata, and use the reported
>>>>>>>             ExposureTime to populate the control value in the next Request to be
>>>>>>>             queued to the Camera.
>>>>>>>     
>>>>>>> @@ -295,7 +295,7 @@ controls:
>>>>>>>     
>>>>>>>             \sa ExposureTime
>>>>>>>           enum:
>>>>>>> -        - name: ExposureTimeModeAuto
>>>>>>> +        - name: Auto
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 The exposure time will be calculated automatically and set by the
>>>>>>> @@ -306,7 +306,7 @@ controls:
>>>>>>>     
>>>>>>>                 When transitioning from Manual to Auto mode, the AEGC should start
>>>>>>>                 its adjustments based on the last set manual ExposureTime value.
>>>>>>> -        - name: ExposureTimeModeManual
>>>>>>> +        - name: Manual
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 The exposure time will not be updated by the AE algorithm.
>>>>>>> @@ -356,7 +356,7 @@ controls:
>>>>>>>             or Auto is not supported by the camera), the camera should use a
>>>>>>>             best-effort default value.
>>>>>>>     
>>>>>>> -        If AnalogueGainModeManual is supported, the AnalogueGain control must
>>>>>>> +        If AnalogueGainMode.Manual is supported, the AnalogueGain control must
>>>>>>>             also be supported.
>>>>>>>     
>>>>>>>             For cameras where we have control over the ISP, both ExposureTimeMode
>>>>>>> @@ -376,7 +376,7 @@ controls:
>>>>>>>             \sa ExposureTimeMode
>>>>>>>             \sa AnalogueGain
>>>>>>>           enum:
>>>>>>> -        - name: AnalogueGainModeAuto
>>>>>>> +        - name: Auto
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 The analogue gain will be calculated automatically and set by the
>>>>>>> @@ -387,7 +387,7 @@ controls:
>>>>>>>     
>>>>>>>                 When transitioning from Manual to Auto mode, the AEGC should start
>>>>>>>                 its adjustments based on the last set manual AnalogueGain value.
>>>>>>> -        - name: AnalogueGainModeManual
>>>>>>> +        - name: Manual
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 The analogue gain will not be updated by the AEGC algorithm.
>>>>>>> @@ -418,11 +418,11 @@ controls:
>>>>>>>             supported, otherwise the flicker mode will be set to FlickerOff.
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: FlickerOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 No flicker avoidance is performed.
>>>>>>> -        - name: FlickerManual
>>>>>>> +        - name: Manual
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Manual flicker avoidance.
>>>>>>> @@ -430,7 +430,7 @@ controls:
>>>>>>>                 Suppress flicker effects caused by lighting running with a period
>>>>>>>                 specified by the AeFlickerPeriod control.
>>>>>>>                 \sa AeFlickerPeriod
>>>>>>> -        - name: FlickerAuto
>>>>>>> +        - name: Auto
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 Automatic flicker period detection and avoidance.
>>>>>>> @@ -543,28 +543,28 @@ controls:
>>>>>>>             The modes supported are platform specific, and not all modes may be
>>>>>>>             supported.
>>>>>>>           enum:
>>>>>>> -        - name: AwbAuto
>>>>>>> +        - name: Auto
>>>>>>>               value: 0
>>>>>>>               description: Search over the whole colour temperature range.
>>>>>>> -        - name: AwbIncandescent
>>>>>>> +        - name: Incandescent
>>>>>>>               value: 1
>>>>>>>               description: Incandescent AWB lamp mode.
>>>>>>> -        - name: AwbTungsten
>>>>>>> +        - name: Tungsten
>>>>>>>               value: 2
>>>>>>>               description: Tungsten AWB lamp mode.
>>>>>>> -        - name: AwbFluorescent
>>>>>>> +        - name: Fluorescent
>>>>>>>               value: 3
>>>>>>>               description: Fluorescent AWB lamp mode.
>>>>>>> -        - name: AwbIndoor
>>>>>>> +        - name: Indoor
>>>>>>>               value: 4
>>>>>>>               description: Indoor AWB lighting mode.
>>>>>>> -        - name: AwbDaylight
>>>>>>> +        - name: Daylight
>>>>>>>               value: 5
>>>>>>>               description: Daylight AWB lighting mode.
>>>>>>> -        - name: AwbCloudy
>>>>>>> +        - name: Cloudy
>>>>>>>               value: 6
>>>>>>>               description: Cloudy AWB lighting mode.
>>>>>>> -        - name: AwbCustom
>>>>>>> +        - name: Custom
>>>>>>>               value: 7
>>>>>>>               description: Custom AWB mode.
>>>>>>>     
>>>>>>> @@ -801,7 +801,7 @@ controls:
>>>>>>>             An implementation may choose not to implement all the modes.
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: AfModeManual
>>>>>>> +        - name: Manual
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 The AF algorithm is in manual mode.
>>>>>>> @@ -809,15 +809,15 @@ controls:
>>>>>>>                 In this mode it will never perform any action nor move the lens of
>>>>>>>                 its own accord, but an application can specify the desired lens
>>>>>>>                 position using the LensPosition control. The AfState will always
>>>>>>> -            report AfStateIdle.
>>>>>>> +            report AfState.Idle.
>>>>>>>     
>>>>>>> -            If the camera is started in AfModeManual, it will move the focus
>>>>>>> +            If the camera is started in AfMode.Manual, it will move the focus
>>>>>>>                 lens to the position specified by the LensPosition control.
>>>>>>>     
>>>>>>>                 This mode is the recommended default value for the AfMode control.
>>>>>>>                 External cameras (as reported by the Location property set to
>>>>>>> -            CameraLocationExternal) may use a different default value.
>>>>>>> -        - name: AfModeAuto
>>>>>>> +            Location.External) may use a different default value.
>>>>>>> +        - name: Auto
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 The AF algorithm is in auto mode.
>>>>>>> @@ -827,18 +827,18 @@ controls:
>>>>>>>                 used to initiate a focus scan, the results of which will be
>>>>>>>                 reported by AfState.
>>>>>>>     
>>>>>>> -            If the autofocus algorithm is moved from AfModeAuto to another mode
>>>>>>> +            If the autofocus algorithm is moved from AfMode.Auto to another mode
>>>>>>>                 while a scan is in progress, the scan is cancelled immediately,
>>>>>>>                 without waiting for the scan to finish.
>>>>>>>     
>>>>>>> -            When first entering this mode the AfState will report AfStateIdle.
>>>>>>> -            When a trigger control is sent, AfState will report AfStateScanning
>>>>>>> -            for a period before spontaneously changing to AfStateFocused or
>>>>>>> -            AfStateFailed, depending on the outcome of the scan. It will remain
>>>>>>> +            When first entering this mode the AfState will report AfState.Idle.
>>>>>>> +            When a trigger control is sent, AfState will report AfState.Scanning
>>>>>>> +            for a period before spontaneously changing to AfState.Focused or
>>>>>>> +            AfState.Failed, depending on the outcome of the scan. It will remain
>>>>>>>                 in this state until another scan is initiated by the AfTrigger
>>>>>>>                 control. If a scan is cancelled (without changing to another mode),
>>>>>>> -            AfState will return to AfStateIdle.
>>>>>>> -        - name: AfModeContinuous
>>>>>>> +            AfState will return to AfState.Idle.
>>>>>>> +        - name: Continuous
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 The AF algorithm is in continuous mode.
>>>>>>> @@ -853,9 +853,9 @@ controls:
>>>>>>>                 scanning by using the AfPause control. This allows video or still
>>>>>>>                 images to be captured whilst guaranteeing that the focus is fixed.
>>>>>>>     
>>>>>>> -            When set to AfModeContinuous, the system will immediately initiate a
>>>>>>> -            scan so AfState will report AfStateScanning, and will settle on one
>>>>>>> -            of AfStateFocused or AfStateFailed, depending on the scan result.
>>>>>>> +            When set to AfMode.Continuous, the system will immediately initiate a
>>>>>>> +            scan so AfState will report AfState.Scanning, and will settle on one
>>>>>>> +            of AfState.Focused or AfState.Failed, depending on the scan result.
>>>>>>>     
>>>>>>>       - AfRange:
>>>>>>>           type: int32_t
>>>>>>> @@ -865,7 +865,7 @@ controls:
>>>>>>>     
>>>>>>>             An implementation may choose not to implement all the options here.
>>>>>>>           enum:
>>>>>>> -        - name: AfRangeNormal
>>>>>>> +        - name: Normal
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 A wide range of focus distances is scanned.
>>>>>>> @@ -873,16 +873,16 @@ controls:
>>>>>>>                 Scanned distances cover all the way from infinity down to close
>>>>>>>                 distances, though depending on the implementation, possibly not
>>>>>>>                 including the very closest macro positions.
>>>>>>> -        - name: AfRangeMacro
>>>>>>> +        - name: Macro
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Only close distances are scanned.
>>>>>>> -        - name: AfRangeFull
>>>>>>> +        - name: Full
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 The full range of focus distances is scanned.
>>>>>>>     
>>>>>>> -            This range is similar to AfRangeNormal but includes the very
>>>>>>> +            This range is similar to Normal but includes the very
>>>>>>>                 closest macro positions.
>>>>>>>     
>>>>>>>       - AfSpeed:
>>>>>>> @@ -897,10 +897,10 @@ controls:
>>>>>>>             capture) it may be helpful to move the lens as quickly as is reasonably
>>>>>>>             possible.
>>>>>>>           enum:
>>>>>>> -        - name: AfSpeedNormal
>>>>>>> +        - name: Normal
>>>>>>>               value: 0
>>>>>>>               description: Move the lens at its usual speed.
>>>>>>> -        - name: AfSpeedFast
>>>>>>> +        - name: Fast
>>>>>>>               value: 1
>>>>>>>               description: Move the lens more quickly.
>>>>>>>     
>>>>>>> @@ -910,11 +910,11 @@ controls:
>>>>>>>           description: |
>>>>>>>             The parts of the image used by the AF algorithm to measure focus.
>>>>>>>           enum:
>>>>>>> -        - name: AfMeteringAuto
>>>>>>> +        - name: Auto
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 Let the AF algorithm decide for itself where it will measure focus.
>>>>>>> -        - name: AfMeteringWindows
>>>>>>> +        - name: Windows
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Use the rectangles defined by the AfWindows control to measure focus.
>>>>>>> @@ -957,19 +957,19 @@ controls:
>>>>>>>           description: |
>>>>>>>             Start an autofocus scan.
>>>>>>>     
>>>>>>> -        This control starts an autofocus scan when AfMode is set to AfModeAuto,
>>>>>>> -        and is ignored if AfMode is set to AfModeManual or AfModeContinuous. It
>>>>>>> +        This control starts an autofocus scan when AfMode is set to AfMode.Auto,
>>>>>>> +        and is ignored if AfMode is set to AfMode.Manual or AfMode.Continuous. It
>>>>>>>             can also be used to terminate a scan early.
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: AfTriggerStart
>>>>>>> +        - name: Start
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 Start an AF scan.
>>>>>>>     
>>>>>>> -            Setting the control to AfTriggerStart is ignored if a scan is in
>>>>>>> +            Setting the control to AfTrigger.Start is ignored if a scan is in
>>>>>>>                 progress.
>>>>>>> -        - name: AfTriggerCancel
>>>>>>> +        - name: Cancel
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Cancel an AF scan.
>>>>>>> @@ -984,43 +984,43 @@ controls:
>>>>>>>             Pause lens movements when in continuous autofocus mode.
>>>>>>>     
>>>>>>>             This control has no effect except when in continuous autofocus mode
>>>>>>> -        (AfModeContinuous). It can be used to pause any lens movements while
>>>>>>> +        (AfMode.Continuous). It can be used to pause any lens movements while
>>>>>>>             (for example) images are captured. The algorithm remains inactive
>>>>>>>             until it is instructed to resume.
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: AfPauseImmediate
>>>>>>> +        - name: Immediate
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 Pause the continuous autofocus algorithm immediately.
>>>>>>>     
>>>>>>>                 The autofocus algorithm is paused whether or not any kind of scan
>>>>>>>                 is underway. AfPauseState will subsequently report
>>>>>>> -            AfPauseStatePaused. AfState may report any of AfStateScanning,
>>>>>>> -            AfStateFocused or AfStateFailed, depending on the algorithm's state
>>>>>>> +            AfPauseState.Paused. AfState may report any of AfState.Scanning,
>>>>>>> +            AfState.Focused or AfState.Failed, depending on the algorithm's state
>>>>>>>                 when it received this control.
>>>>>>> -        - name: AfPauseDeferred
>>>>>>> +        - name: Deferred
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Pause the continuous autofocus algorithm at the end of the scan.
>>>>>>>     
>>>>>>> -            This is similar to AfPauseImmediate, and if the AfState is
>>>>>>> -            currently reporting AfStateFocused or AfStateFailed it will remain
>>>>>>> -            in that state and AfPauseState will report AfPauseStatePaused.
>>>>>>> +            This is similar to AfPause.Immediate, and if the AfState is
>>>>>>> +            currently reporting AfState.Focused or AfState.Failed it will remain
>>>>>>> +            in that state and AfPauseState will report AfPauseState.Paused.
>>>>>>>     
>>>>>>> -            However, if the algorithm is scanning (AfStateScanning),
>>>>>>> -            AfPauseState will report AfPauseStatePausing until the scan is
>>>>>>> -            finished, at which point AfState will report one of AfStateFocused
>>>>>>> -            or AfStateFailed, and AfPauseState will change to
>>>>>>> -            AfPauseStatePaused.
>>>>>>> +            However, if the algorithm is scanning (AfState.Scanning),
>>>>>>> +            AfPauseState will report AfPauseState.Pausing until the scan is
>>>>>>> +            finished, at which point AfState will report one of AfState.Focused
>>>>>>> +            or AfState.Failed, and AfPauseState will change to
>>>>>>> +            AfPauseState.Paused.
>>>>>>>     
>>>>>>> -        - name: AfPauseResume
>>>>>>> +        - name: Resume
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 Resume continuous autofocus operation.
>>>>>>>     
>>>>>>>                 The algorithm starts again from exactly where it left off, and
>>>>>>> -            AfPauseState will report AfPauseStateRunning.
>>>>>>> +            AfPauseState will report AfPauseState.Running.
>>>>>>>     
>>>>>>>       - LensPosition:
>>>>>>>           type: float
>>>>>>> @@ -1032,7 +1032,7 @@ controls:
>>>>>>>             also reports back the position of the lens for each frame.
>>>>>>>     
>>>>>>>             The LensPosition control is ignored unless the AfMode is set to
>>>>>>> -        AfModeManual, though the value is reported back unconditionally in all
>>>>>>> +        AfMode.Manual, though the value is reported back unconditionally in all
>>>>>>>             modes.
>>>>>>>     
>>>>>>>             This value, which is generally a non-integer, is the reciprocal of the
>>>>>>> @@ -1069,50 +1069,50 @@ controls:
>>>>>>>             though we note the following state transitions that occur when the
>>>>>>>             AfMode is changed.
>>>>>>>     
>>>>>>> -        If the AfMode is set to AfModeManual, then the AfState will always
>>>>>>> -        report AfStateIdle (even if the lens is subsequently moved). Changing
>>>>>>> -        to the AfModeManual state does not initiate any lens movement.
>>>>>>> +        If the AfMode is set to AfMode.Manual, then the AfState will always
>>>>>>> +        report AfState.Idle (even if the lens is subsequently moved). Changing
>>>>>>> +        to the AfMode.Manual state does not initiate any lens movement.
>>>>>>>     
>>>>>>> -        If the AfMode is set to AfModeAuto then the AfState will report
>>>>>>> -        AfStateIdle. However, if AfModeAuto and AfTriggerStart are sent
>>>>>>> -        together then AfState will omit AfStateIdle and move straight to
>>>>>>> -        AfStateScanning (and start a scan).
>>>>>>> +        If the AfMode is set to AfMode.Auto then the AfState will report
>>>>>>> +        AfState.Idle. However, if AfMode.Auto and AfTrigger.Start are sent
>>>>>>> +        together then AfState will omit AfState.Idle and move straight to
>>>>>>> +        AfState.Scanning (and start a scan).
>>>>>>>     
>>>>>>> -        If the AfMode is set to AfModeContinuous then the AfState will
>>>>>>> -        initially report AfStateScanning.
>>>>>>> +        If the AfMode is set to AfMode.Continuous then the AfState will
>>>>>>> +        initially report AfState.Scanning.
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: AfStateIdle
>>>>>>> +        - name: Idle
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>> -            The AF algorithm is in manual mode (AfModeManual) or in auto mode
>>>>>>> -            (AfModeAuto) and a scan has not yet been triggered, or an
>>>>>>> +            The AF algorithm is in manual mode (AfMode.Manual) or in auto mode
>>>>>>> +            (AfMode.Auto) and a scan has not yet been triggered, or an
>>>>>>>                 in-progress scan was cancelled.
>>>>>>> -        - name: AfStateScanning
>>>>>>> +        - name: Scanning
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>> -            The AF algorithm is in auto mode (AfModeAuto), and a scan has been
>>>>>>> +            The AF algorithm is in auto mode (AfMode.Auto), and a scan has been
>>>>>>>                 started using the AfTrigger control.
>>>>>>>     
>>>>>>> -            The scan can be cancelled by sending AfTriggerCancel at which point
>>>>>>> -            the algorithm will either move back to AfStateIdle or, if the scan
>>>>>>> +            The scan can be cancelled by sending AfTrigger.Cancel at which point
>>>>>>> +            the algorithm will either move back to AfState.Idle or, if the scan
>>>>>>>                 actually completes before the cancel request is processed, to one
>>>>>>> -            of AfStateFocused or AfStateFailed.
>>>>>>> +            of AfState.Focused or AfState.Failed.
>>>>>>>     
>>>>>>>                 Alternatively the AF algorithm could be in continuous mode
>>>>>>> -            (AfModeContinuous) at which point it may enter this state
>>>>>>> +            (AfMode.Continuous) at which point it may enter this state
>>>>>>>                 spontaneously whenever it determines that a rescan is needed.
>>>>>>> -        - name: AfStateFocused
>>>>>>> +        - name: Focused
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>> -            The AF algorithm is in auto (AfModeAuto) or continuous
>>>>>>> -            (AfModeContinuous) mode and a scan has completed with the result
>>>>>>> +            The AF algorithm is in auto (AfMode.Auto) or continuous
>>>>>>> +            (AfMode.Continuous) mode and a scan has completed with the result
>>>>>>>                 that the algorithm believes the image is now in focus.
>>>>>>> -        - name: AfStateFailed
>>>>>>> +        - name: Failed
>>>>>>>               value: 3
>>>>>>>               description: |
>>>>>>> -            The AF algorithm is in auto (AfModeAuto) or continuous
>>>>>>> -            (AfModeContinuous) mode and a scan has completed with the result
>>>>>>> +            The AF algorithm is in auto (AfMode.Auto) or continuous
>>>>>>> +            (AfMode.Continuous) mode and a scan has completed with the result
>>>>>>>                 that the algorithm did not find a good focus position.
>>>>>>>     
>>>>>>>       - AfPauseState:
>>>>>>> @@ -1121,29 +1121,29 @@ controls:
>>>>>>>           description: |
>>>>>>>             Report whether the autofocus is currently running, paused or pausing.
>>>>>>>     
>>>>>>> -        This control is only applicable in continuous (AfModeContinuous) mode,
>>>>>>> +        This control is only applicable in continuous (AfMode.Continuous) mode,
>>>>>>>             and reports whether the algorithm is currently running, paused or
>>>>>>>             pausing (that is, will pause as soon as any in-progress scan
>>>>>>>             completes).
>>>>>>>     
>>>>>>> -        Any change to AfMode will cause AfPauseStateRunning to be reported.
>>>>>>> +        Any change to AfMode will cause AfPauseState.Running to be reported.
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: AfPauseStateRunning
>>>>>>> +        - name: Running
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 Continuous AF is running and the algorithm may restart a scan
>>>>>>>                 spontaneously.
>>>>>>> -        - name: AfPauseStatePausing
>>>>>>> +        - name: Pausing
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Continuous AF has been sent an AfPauseDeferred control, and will
>>>>>>>                 pause as soon as any in-progress scan completes.
>>>>>>>     
>>>>>>>                 When the scan completes, the AfPauseState control will report
>>>>>>> -            AfPauseStatePaused. No new scans will be start spontaneously until
>>>>>>> +            AfPauseState.Paused. No new scans will be start spontaneously until
>>>>>>>                 the AfPauseResume control is sent.
>>>>>>> -        - name: AfPauseStatePaused
>>>>>>> +        - name: Paused
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 Continuous AF is paused.
>>>>>>> @@ -1170,13 +1170,13 @@ controls:
>>>>>>>             \sa HdrChannel
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: HdrModeOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 HDR is disabled.
>>>>>>>     
>>>>>>>                 Metadata for this frame will not include the HdrChannel control.
>>>>>>> -        - name: HdrModeMultiExposureUnmerged
>>>>>>> +        - name: MultiExposureUnmerged
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Multiple exposures will be generated in an alternating fashion.
>>>>>>> @@ -1188,7 +1188,7 @@ controls:
>>>>>>>     
>>>>>>>                 The expectation is that an application using this mode would merge
>>>>>>>                 the frames to create HDR images for itself if it requires them.
>>>>>>> -        - name: HdrModeMultiExposure
>>>>>>> +        - name: MultiExposure
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 Multiple exposures will be generated and merged to create HDR
>>>>>>> @@ -1201,7 +1201,7 @@ controls:
>>>>>>>                 alternately as the short and long channel. Systems that use three
>>>>>>>                 channels for HDR will cycle through the short, medium and long
>>>>>>>                 channel before repeating.
>>>>>>> -        - name: HdrModeSingleExposure
>>>>>>> +        - name: SingleExposure
>>>>>>>               value: 3
>>>>>>>               description: |
>>>>>>>                 Multiple frames all at a single exposure will be used to create HDR
>>>>>>> @@ -1209,7 +1209,7 @@ controls:
>>>>>>>     
>>>>>>>                 These images should be reported as all corresponding to the HDR
>>>>>>>                 short channel.
>>>>>>> -        - name: HdrModeNight
>>>>>>> +        - name: Night
>>>>>>>               value: 4
>>>>>>>               description: |
>>>>>>>                 Multiple frames will be combined to produce "night mode" images.
>>>>>>> @@ -1235,20 +1235,20 @@ controls:
>>>>>>>             \sa HdrMode
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: HdrChannelNone
>>>>>>> +        - name: None
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 This image does not correspond to any of the captures used to create
>>>>>>>                 an HDR image.
>>>>>>> -        - name: HdrChannelShort
>>>>>>> +        - name: Short
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 This is a short exposure image.
>>>>>>> -        - name: HdrChannelMedium
>>>>>>> +        - name: Medium
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 This is a medium exposure image.
>>>>>>> -        - name: HdrChannelLong
>>>>>>> +        - name: Long
>>>>>>>               value: 3
>>>>>>>               description: |
>>>>>>>                 This is a long exposure image.
>>>>>>> diff --git a/src/libcamera/control_ids_draft.yaml b/src/libcamera/control_ids_draft.yaml
>>>>>>> index 03309eeac..c72675909 100644
>>>>>>> --- a/src/libcamera/control_ids_draft.yaml
>>>>>>> +++ b/src/libcamera/control_ids_draft.yaml
>>>>>>> @@ -18,13 +18,13 @@ controls:
>>>>>>>             Whether the camera device will trigger a precapture metering sequence
>>>>>>>             when it processes this request.
>>>>>>>           enum:
>>>>>>> -        - name: AePrecaptureTriggerIdle
>>>>>>> +        - name: Idle
>>>>>>>               value: 0
>>>>>>>               description: The trigger is idle.
>>>>>>> -        - name: AePrecaptureTriggerStart
>>>>>>> +        - name: Start
>>>>>>>               value: 1
>>>>>>>               description: The pre-capture AE metering is started by the camera.
>>>>>>> -        - name: AePrecaptureTriggerCancel
>>>>>>> +        - name: Cancel
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 The camera will cancel any active or completed metering sequence.
>>>>>>> @@ -39,22 +39,22 @@ controls:
>>>>>>>     
>>>>>>>             Mode of operation for the noise reduction algorithm.
>>>>>>>           enum:
>>>>>>> -        - name: NoiseReductionModeOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: No noise reduction is applied
>>>>>>> -        - name: NoiseReductionModeFast
>>>>>>> +        - name: Fast
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Noise reduction is applied without reducing the frame rate.
>>>>>>> -        - name: NoiseReductionModeHighQuality
>>>>>>> +        - name: HighQuality
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 High quality noise reduction at the expense of frame rate.
>>>>>>> -        - name: NoiseReductionModeMinimal
>>>>>>> +        - name: Minimal
>>>>>>>               value: 3
>>>>>>>               description: |
>>>>>>>                 Minimal noise reduction is applied without reducing the frame rate.
>>>>>>> -        - name: NoiseReductionModeZSL
>>>>>>> +        - name: ZSL
>>>>>>>               value: 4
>>>>>>>               description: |
>>>>>>>                 Noise reduction is applied at different levels to different streams.
>>>>>>> @@ -68,13 +68,13 @@ controls:
>>>>>>>     
>>>>>>>             Mode of operation for the chromatic aberration correction algorithm.
>>>>>>>           enum:
>>>>>>> -        - name: ColorCorrectionAberrationOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: No aberration correction is applied.
>>>>>>> -        - name: ColorCorrectionAberrationFast
>>>>>>> +        - name: Fast
>>>>>>>               value: 1
>>>>>>>               description: Aberration correction will not slow down the frame rate.
>>>>>>> -        - name: ColorCorrectionAberrationHighQuality
>>>>>>> +        - name: HighQuality
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 High quality aberration correction which might reduce the frame
>>>>>>> @@ -89,16 +89,16 @@ controls:
>>>>>>>     
>>>>>>>             Current state of the AWB algorithm.
>>>>>>>           enum:
>>>>>>> -        - name: AwbStateInactive
>>>>>>> +        - name: Inactive
>>>>>>>               value: 0
>>>>>>>               description: The AWB algorithm is inactive.
>>>>>>> -        - name: AwbStateSearching
>>>>>>> +        - name: Searching
>>>>>>>               value: 1
>>>>>>>               description: The AWB algorithm has not converged yet.
>>>>>>> -        - name: AwbConverged
>>>>>>> +        - name: Converged
>>>>>>>               value: 2
>>>>>>>               description: The AWB algorithm has converged.
>>>>>>> -        - name: AwbLocked
>>>>>>> +        - name: Locked
>>>>>>>               value: 3
>>>>>>>               description: The AWB algorithm is locked.
>>>>>>>     
>>>>>>> @@ -117,10 +117,10 @@ controls:
>>>>>>>            Control to report if the lens shading map is available. Currently
>>>>>>>            identical to ANDROID_STATISTICS_LENS_SHADING_MAP_MODE.
>>>>>>>           enum:
>>>>>>> -        - name: LensShadingMapModeOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: No lens shading map mode is available.
>>>>>>> -        - name: LensShadingMapModeOn
>>>>>>> +        - name: "On"
>>>>>>>               value: 1
>>>>>>>               description: The lens shading map mode is available.
>>>>>>>     
>>>>>>> @@ -156,18 +156,18 @@ controls:
>>>>>>>             Control to select the test pattern mode. Currently identical to
>>>>>>>             ANDROID_SENSOR_TEST_PATTERN_MODE.
>>>>>>>           enum:
>>>>>>> -        - name: TestPatternModeOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 No test pattern mode is used. The camera device returns frames from
>>>>>>>                 the image sensor.
>>>>>>> -        - name: TestPatternModeSolidColor
>>>>>>> +        - name: SolidColor
>>>>>>>               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
>>>>>>> +        - name: ColorBars
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 All pixel data is replaced with an 8-bar color pattern. The vertical
>>>>>>> @@ -177,10 +177,10 @@ controls:
>>>>>>>                 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
>>>>>>> +        - name: ColorBarsFadeToGray
>>>>>>>               value: 3
>>>>>>>               description: |
>>>>>>> -            The test pattern is similar to TestPatternModeColorBars,
>>>>>>> +            The test pattern is similar to TestPatternMode.ColorBars,
>>>>>>>                 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
>>>>>>> @@ -191,7 +191,7 @@ controls:
>>>>>>>                 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
>>>>>>> +        - name: Pn9
>>>>>>>               value: 4
>>>>>>>               description: |
>>>>>>>                 All pixel data is replaced by a pseudo-random sequence generated
>>>>>>> @@ -199,7 +199,7 @@ controls:
>>>>>>>                 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
>>>>>>> +        - name: Custom1
>>>>>>>               value: 256
>>>>>>>               description: |
>>>>>>>                 The first custom test pattern. All custom patterns that are
>>>>>>> @@ -221,19 +221,19 @@ controls:
>>>>>>>             \sa FaceDetectFaceIds
>>>>>>>     
>>>>>>>           enum:
>>>>>>> -        - name: FaceDetectModeOff
>>>>>>> +        - name: "Off"
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 Pipeline doesn't perform face detection and doesn't report any
>>>>>>>                 control related to face detection.
>>>>>>> -        - name: FaceDetectModeSimple
>>>>>>> +        - name: Simple
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 Pipeline performs face detection and reports the
>>>>>>>                 FaceDetectFaceRectangles and FaceDetectFaceScores controls for each
>>>>>>>                 detected face. FaceDetectFaceLandmarks and FaceDetectFaceIds are
>>>>>>>                 optional.
>>>>>>> -        - name: FaceDetectModeFull
>>>>>>> +        - name: Full
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 Pipeline performs face detection and reports all the controls
>>>>>>> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
>>>>>>> index 586e932d2..4273b8ef9 100644
>>>>>>> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
>>>>>>> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
>>>>>>> @@ -570,7 +570,7 @@ int UVCCameraData::init(MediaDevice *media)
>>>>>>>             * come from the ACPI _PLD, but that may be even more unreliable than
>>>>>>>             * the _UPC.
>>>>>>>             */
>>>>>>> -       properties::LocationEnum location = properties::CameraLocationExternal;
>>>>>>> +       properties::LocationEnum location = properties::LocationExternal;
>>>>>>>            std::ifstream file(video_->devicePath() + "/../removable");
>>>>>>>            if (file.is_open()) {
>>>>>>>                    std::string value;
>>>>>>> @@ -578,7 +578,7 @@ int UVCCameraData::init(MediaDevice *media)
>>>>>>>                    file.close();
>>>>>>>     
>>>>>>>                    if (value == "fixed")
>>>>>>> -                       location = properties::CameraLocationFront;
>>>>>>> +                       location = properties::LocationFront;
>>>>>>>            }
>>>>>>>     
>>>>>>>            properties_.set(properties::Location, location);
>>>>>>> diff --git a/src/libcamera/pipeline/virtual/README.md b/src/libcamera/pipeline/virtual/README.md
>>>>>>> index a9f39c151..c14d3b6da 100644
>>>>>>> --- a/src/libcamera/pipeline/virtual/README.md
>>>>>>> +++ b/src/libcamera/pipeline/virtual/README.md
>>>>>>> @@ -36,7 +36,7 @@ Each camera block is a dictionary, containing the following keys:
>>>>>>>         - The path to a directory ends with "/". The name of the images in the
>>>>>>>           directory are "{n}.jpg" with {n} is the sequence of images starting with 0.
>>>>>>>     - `location` (`string`, default="front"): The location of the camera. Support
>>>>>>> -  "CameraLocationFront", "CameraLocationBack", and "CameraLocationExternal".
>>>>>>> +  "Front", "Back", and "External".
>>>>>>>     - `model` (`string`, default="Unknown"): The model name of the camera.
>>>>>>>     
>>>>>>>     Check `data/virtual.yaml` as the sample config file.
>>>>>>> diff --git a/src/libcamera/pipeline/virtual/config_parser.cpp b/src/libcamera/pipeline/virtual/config_parser.cpp
>>>>>>> index d9900add6..f56cb80a1 100644
>>>>>>> --- a/src/libcamera/pipeline/virtual/config_parser.cpp
>>>>>>> +++ b/src/libcamera/pipeline/virtual/config_parser.cpp
>>>>>>> @@ -233,9 +233,9 @@ int ConfigParser::parseFrameGenerator(const YamlObject &cameraConfigData, Virtua
>>>>>>>     
>>>>>>>     int ConfigParser::parseLocation(const YamlObject &cameraConfigData, VirtualCameraData *data)
>>>>>>>     {
>>>>>>> -       std::string location = cameraConfigData["location"].get<std::string>("CameraLocationFront");
>>>>>>> +       std::string location = cameraConfigData["location"].get<std::string>("Front");
>>>>>>>     
>>>>>>> -       /* Default value is properties::CameraLocationFront */
>>>>>>> +       /* Default value is properties::LocationFront */
>>>>>>>            auto it = properties::LocationNameValueMap.find(location);
>>>>>>>            if (it == properties::LocationNameValueMap.end()) {
>>>>>>>                    LOG(Virtual, Error)
>>>>>>> diff --git a/src/libcamera/pipeline/virtual/data/virtual.yaml b/src/libcamera/pipeline/virtual/data/virtual.yaml
>>>>>>> index 20471bb94..767107bbe 100644
>>>>>>> --- a/src/libcamera/pipeline/virtual/data/virtual.yaml
>>>>>>> +++ b/src/libcamera/pipeline/virtual/data/virtual.yaml
>>>>>>> @@ -14,7 +14,7 @@
>>>>>>>         - 70
>>>>>>>         - 80
>>>>>>>       test_pattern: "lines"
>>>>>>> -  location: "CameraLocationFront"
>>>>>>> +  location: "Front"
>>>>>>>       model: "Virtual Video Device"
>>>>>>>     "Virtual1":
>>>>>>>       supported_formats:
>>>>>>> @@ -23,14 +23,14 @@
>>>>>>>         frame_rates:
>>>>>>>         - 60
>>>>>>>       test_pattern: "bars"
>>>>>>> -  location: "CameraLocationBack"
>>>>>>> +  location: "Back"
>>>>>>>       model: "Virtual Video Device1"
>>>>>>>     "Virtual2":
>>>>>>>       supported_formats:
>>>>>>>       - width: 400
>>>>>>>         height: 300
>>>>>>>       test_pattern: "lines"
>>>>>>> -  location: "CameraLocationFront"
>>>>>>> +  location: "Front"
>>>>>>>       model: "Virtual Video Device2"
>>>>>>>     "Virtual3":
>>>>>>>       test_pattern: "bars"
>>>>>>> diff --git a/src/libcamera/property_ids_core.yaml b/src/libcamera/property_ids_core.yaml
>>>>>>> index 834454a4e..f1da19ca3 100644
>>>>>>> --- a/src/libcamera/property_ids_core.yaml
>>>>>>> +++ b/src/libcamera/property_ids_core.yaml
>>>>>>> @@ -11,17 +11,17 @@ controls:
>>>>>>>           description: |
>>>>>>>             Camera mounting location
>>>>>>>           enum:
>>>>>>> -        - name: CameraLocationFront
>>>>>>> +        - name: Front
>>>>>>>               value: 0
>>>>>>>               description: |
>>>>>>>                 The camera is mounted on the front side of the device, facing the
>>>>>>>                 user
>>>>>>> -        - name: CameraLocationBack
>>>>>>> +        - name: Back
>>>>>>>               value: 1
>>>>>>>               description: |
>>>>>>>                 The camera is mounted on the back side of the device, facing away
>>>>>>>                 from the user
>>>>>>> -        - name: CameraLocationExternal
>>>>>>> +        - name: External
>>>>>>>               value: 2
>>>>>>>               description: |
>>>>>>>                 The camera is attached to the device in a way that allows it to
>>>>>>> diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp
>>>>>>> index 32989c19c..1a10ec227 100644
>>>>>>> --- a/src/libcamera/sensor/camera_sensor_legacy.cpp
>>>>>>> +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp
>>>>>>> @@ -580,13 +580,13 @@ int CameraSensorLegacy::initProperties()
>>>>>>>                                    << v4l2Orientation << ", setting to External";
>>>>>>>                            [[fallthrough]];
>>>>>>>                    case V4L2_CAMERA_ORIENTATION_EXTERNAL:
>>>>>>> -                       propertyValue = properties::CameraLocationExternal;
>>>>>>> +                       propertyValue = properties::LocationExternal;
>>>>>>>                            break;
>>>>>>>                    case V4L2_CAMERA_ORIENTATION_FRONT:
>>>>>>> -                       propertyValue = properties::CameraLocationFront;
>>>>>>> +                       propertyValue = properties::LocationFront;
>>>>>>>                            break;
>>>>>>>                    case V4L2_CAMERA_ORIENTATION_BACK:
>>>>>>> -                       propertyValue = properties::CameraLocationBack;
>>>>>>> +                       propertyValue = properties::LocationBack;
>>>>>>>                            break;
>>>>>>>                    }
>>>>>>>                    properties_.set(properties::Location, propertyValue);
>>>>>>> @@ -627,19 +627,19 @@ int CameraSensorLegacy::initProperties()
>>>>>>>                    int32_t cfa;
>>>>>>>                    switch (bayerFormat_->order) {
>>>>>>>                    case BayerFormat::BGGR:
>>>>>>> -                       cfa = properties::draft::BGGR;
>>>>>>> +                       cfa = properties::draft::ColorFilterArrangementBGGR;
>>>>>>>                            break;
>>>>>>>                    case BayerFormat::GBRG:
>>>>>>> -                       cfa = properties::draft::GBRG;
>>>>>>> +                       cfa = properties::draft::ColorFilterArrangementGBRG;
>>>>>>>                            break;
>>>>>>>                    case BayerFormat::GRBG:
>>>>>>> -                       cfa = properties::draft::GRBG;
>>>>>>> +                       cfa = properties::draft::ColorFilterArrangementGRBG;
>>>>>>>                            break;
>>>>>>>                    case BayerFormat::RGGB:
>>>>>>> -                       cfa = properties::draft::RGGB;
>>>>>>> +                       cfa = properties::draft::ColorFilterArrangementRGGB;
>>>>>>>                            break;
>>>>>>>                    case BayerFormat::MONO:
>>>>>>> -                       cfa = properties::draft::MONO;
>>>>>>> +                       cfa = properties::draft::ColorFilterArrangementMONO;
>>>>>>>                            break;
>>>>>>>                    }
>>>>>>>     
>>>>>>> @@ -900,7 +900,7 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const
>>>>>>>            info->outputSize = format.size;
>>>>>>>     
>>>>>>>            std::optional<int32_t> cfa = properties_.get(properties::draft::ColorFilterArrangement);
>>>>>>> -       info->cfaPattern = cfa ? *cfa : properties::draft::RGB;
>>>>>>> +       info->cfaPattern = cfa ? *cfa : properties::draft::ColorFilterArrangementRGB;
>>>>>>>     
>>>>>>>            /*
>>>>>>>             * Retrieve the pixel rate, line length and minimum/maximum frame
>>>>>>> diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp
>>>>>>> index ab75b1f82..e6bcd583c 100644
>>>>>>> --- a/src/libcamera/sensor/camera_sensor_raw.cpp
>>>>>>> +++ b/src/libcamera/sensor/camera_sensor_raw.cpp
>>>>>>> @@ -585,13 +585,13 @@ int CameraSensorRaw::initProperties()
>>>>>>>                                    << v4l2Orientation << ", setting to External";
>>>>>>>                            [[fallthrough]];
>>>>>>>                    case V4L2_CAMERA_ORIENTATION_EXTERNAL:
>>>>>>> -                       propertyValue = properties::CameraLocationExternal;
>>>>>>> +                       propertyValue = properties::LocationExternal;
>>>>>>>                            break;
>>>>>>>                    case V4L2_CAMERA_ORIENTATION_FRONT:
>>>>>>> -                       propertyValue = properties::CameraLocationFront;
>>>>>>> +                       propertyValue = properties::LocationFront;
>>>>>>>                            break;
>>>>>>>                    case V4L2_CAMERA_ORIENTATION_BACK:
>>>>>>> -                       propertyValue = properties::CameraLocationBack;
>>>>>>> +                       propertyValue = properties::LocationBack;
>>>>>>>                            break;
>>>>>>>                    }
>>>>>>>                    properties_.set(properties::Location, propertyValue);
>>>>>>> @@ -632,20 +632,20 @@ int CameraSensorRaw::initProperties()
>>>>>>>     
>>>>>>>            switch (cfaPattern_) {
>>>>>>>            case BayerFormat::BGGR:
>>>>>>> -               cfa = properties::draft::BGGR;
>>>>>>> +               cfa = properties::draft::ColorFilterArrangementBGGR;
>>>>>>>                    break;
>>>>>>>            case BayerFormat::GBRG:
>>>>>>> -               cfa = properties::draft::GBRG;
>>>>>>> +               cfa = properties::draft::ColorFilterArrangementGBRG;
>>>>>>>                    break;
>>>>>>>            case BayerFormat::GRBG:
>>>>>>> -               cfa = properties::draft::GRBG;
>>>>>>> +               cfa = properties::draft::ColorFilterArrangementGRBG;
>>>>>>>                    break;
>>>>>>>            case BayerFormat::RGGB:
>>>>>>> -               cfa = properties::draft::RGGB;
>>>>>>> +               cfa = properties::draft::ColorFilterArrangementRGGB;
>>>>>>>                    break;
>>>>>>>            case BayerFormat::MONO:
>>>>>>>            default:
>>>>>>> -               cfa = properties::draft::MONO;
>>>>>>> +               cfa = properties::draft::ColorFilterArrangementMONO;
>>>>>>>                    break;
>>>>>>>            }
>>>>>>>     
>>>>>>> @@ -1015,7 +1015,7 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const
>>>>>>>            info->outputSize = format.size;
>>>>>>>     
>>>>>>>            std::optional<int32_t> cfa = properties_.get(properties::draft::ColorFilterArrangement);
>>>>>>> -       info->cfaPattern = cfa ? *cfa : properties::draft::RGB;
>>>>>>> +       info->cfaPattern = cfa ? *cfa : properties::draft::ColorFilterArrangementRGB;
>>>>>>>     
>>>>>>>            /*
>>>>>>>             * Retrieve the pixel rate, line length and minimum/maximum frame
>>>>>>> diff --git a/src/py/libcamera/gen-py-controls.py b/src/py/libcamera/gen-py-controls.py
>>>>>>> index d43a7c1c7..a72521d62 100755
>>>>>>> --- a/src/py/libcamera/gen-py-controls.py
>>>>>>> +++ b/src/py/libcamera/gen-py-controls.py
>>>>>>> @@ -11,18 +11,6 @@ import yaml
>>>>>>>     from controls import Control
>>>>>>>     
>>>>>>>     
>>>>>>> -def find_common_prefix(strings):
>>>>>>> -    prefix = strings[0]
>>>>>>> -
>>>>>>> -    for string in strings[1:]:
>>>>>>> -        while string[:len(prefix)] != prefix and prefix:
>>>>>>> -            prefix = prefix[:len(prefix) - 1]
>>>>>>> -        if not prefix:
>>>>>>> -            break
>>>>>>> -
>>>>>>> -    return prefix
>>>>>>> -
>>>>>>> -
>>>>>>>     def extend_control(ctrl, mode):
>>>>>>>         if ctrl.vendor != 'libcamera':
>>>>>>>             ctrl.klass = ctrl.vendor
>>>>>>> @@ -31,22 +19,6 @@ def extend_control(ctrl, mode):
>>>>>>>             ctrl.klass = mode
>>>>>>>             ctrl.namespace = ''
>>>>>>>     
>>>>>>> -    if not ctrl.is_enum:
>>>>>>> -        return ctrl
>>>>>>> -
>>>>>>> -    if mode == 'controls':
>>>>>>> -        # Adjustments for controls
>>>>>>> -        if ctrl.name == 'LensShadingMapMode':
>>>>>>> -            prefix = 'LensShadingMapMode'
>>>>>>> -        else:
>>>>>>> -            prefix = find_common_prefix([e.name for e in ctrl.enum_values])
>>>>>>> -    else:
>>>>>>> -        # Adjustments for properties
>>>>>>> -        prefix = find_common_prefix([e.name for e in ctrl.enum_values])
>>>>>>> -
>>>>>>> -    for enum in ctrl.enum_values:
>>>>>>> -        enum.py_name = enum.name[len(prefix):]
>>>>>>> -
>>>>>>>         return ctrl
>>>>>>>     
>>>>>>>     
>>>>>>> diff --git a/src/py/libcamera/py_controls_generated.cpp.in b/src/py/libcamera/py_controls_generated.cpp.in
>>>>>>> index 22a132d19..b1a2817a5 100644
>>>>>>> --- a/src/py/libcamera/py_controls_generated.cpp.in
>>>>>>> +++ b/src/py/libcamera/py_controls_generated.cpp.in
>>>>>>> @@ -39,7 +39,7 @@ void init_py_{{mode}}_generated(py::module& m)
>>>>>>>     
>>>>>>>             py::enum_<libcamera::{{mode}}::{{ctrl.namespace}}{{ctrl.name}}Enum>({{ctrl.klass}}, "{{ctrl.name}}Enum")
>>>>>>>     {%- for enum in ctrl.enum_values %}
>>>>>>> -                .value("{{enum.py_name}}", libcamera::{{mode}}::{{ctrl.namespace}}{{enum.name}})
>>>>>>> +                .value("{{enum.name}}", libcamera::{{mode}}::{{ctrl.namespace}}{{enum.prefixed_name}})
>>>>>>>     {%- endfor %}
>>>>>>>             ;
>>>>>>>     {%- endif %}
>>>>>>> diff --git a/utils/codegen/controls.py b/utils/codegen/controls.py
>>>>>>> index e51610481..c2b9d171c 100644
>>>>>>> --- a/utils/codegen/controls.py
>>>>>>> +++ b/utils/codegen/controls.py
>>>>>>> @@ -21,6 +21,11 @@ class ControlEnum(object):
>>>>>>>             """The enum name"""
>>>>>>>             return self.__data.get('name')
>>>>>>>     
>>>>>>> +    @property
>>>>>>> +    def prefixed_name(self):
>>>>>>> +        """The prefixed enum name"""
>>>>>>> +        return self.__data.get('prefixed_name')
>>>>>>> +
>>>>>>>         @property
>>>>>>>         def value(self):
>>>>>>>             """The enum value"""
>>>>>>> @@ -37,7 +42,19 @@ class Control(object):
>>>>>>>     
>>>>>>>             enum_values = data.get('enum')
>>>>>>>             if enum_values is not None:
>>>>>>> -            self.__enum_values = [ControlEnum(enum) for enum in enum_values]
>>>>>>> +            for enum in enum_values:
>>>>>>> +                ename = enum['name']
>>>>>>> +                if type(ename) is not str:
>>>>>>> +                    raise ValueError(f'Control `{self.__name}` has an enumeration with a non-string name (values {enum["value"]}).')
>>>>>>> +                if not ename[0].isupper():
>>>>>>> +                    raise ValueError(f'Control `{self.__name}` enumeration `{ename}` must start with an uppercase letter.')
>>>>>>> +                if ename.startswith(name):
>>>>>>> +                    raise ValueError(f'Control `{self.__name}` enumeration `{ename}` must not be prefixed with the control name.')
>>>>>>> +
>>>>>>> +            self.__enum_values = [ControlEnum({
>>>>>>> +                **enum,
>>>>>>> +                'prefixed_name': name + enum['name'],
>>>>>>> +            }) for enum in enum_values]
>>>>>>>     
>>>>>>>             size = self.__data.get('size')
>>>>>>>             if size is not None:
>>>>>>> diff --git a/utils/codegen/gen-gst-controls.py b/utils/codegen/gen-gst-controls.py
>>>>>>> index 4ca76049e..43e869c07 100755
>>>>>>> --- a/utils/codegen/gen-gst-controls.py
>>>>>>> +++ b/utils/codegen/gen-gst-controls.py
>>>>>>> @@ -29,18 +29,6 @@ exposed_controls = [
>>>>>>>     ]
>>>>>>>     
>>>>>>>     
>>>>>>> -def find_common_prefix(strings):
>>>>>>> -    prefix = strings[0]
>>>>>>> -
>>>>>>> -    for string in strings[1:]:
>>>>>>> -        while string[:len(prefix)] != prefix and prefix:
>>>>>>> -            prefix = prefix[:len(prefix) - 1]
>>>>>>> -        if not prefix:
>>>>>>> -            break
>>>>>>> -
>>>>>>> -    return prefix
>>>>>>> -
>>>>>>> -
>>>>>>>     def format_description(description):
>>>>>>>         # Substitute doxygen keywords \sa (see also) and \todo
>>>>>>>         description = re.sub(r'\\sa((?: \w+)+)',
>>>>>>> @@ -94,11 +82,6 @@ def extend_control(ctrl):
>>>>>>>         ctrl.is_array = ctrl.size is not None
>>>>>>>     
>>>>>>>         if ctrl.is_enum:
>>>>>>> -        # Remove common prefix from enum variant names
>>>>>>> -        prefix = find_common_prefix([enum.name for enum in ctrl.enum_values])
>>>>>>> -        for enum in ctrl.enum_values:
>>>>>>> -            enum.gst_name = kebab_case(enum.name.removeprefix(prefix))
>>>>>>> -
>>>>>>>             ctrl.gtype = 'enum'
>>>>>>>             ctrl.default = '0'
>>>>>>>         elif ctrl.element_type == 'bool':
> 



More information about the libcamera-devel mailing list