[RFC,v1] libcamera: controls: Remove common enum prefix
diff mbox series

Message ID 20250516154131.84787-1-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • [RFC,v1] libcamera: controls: Remove common enum prefix
Related show

Commit Message

Barnabás Pőcze May 16, 2025, 3:41 p.m. UTC
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 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@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(-)

Comments

Paul Elder May 22, 2025, 1:31 p.m. UTC | #1
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 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@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.

Reviewed-by: Paul Elder <paul.elder@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':
> -- 
> 2.49.0
>
Kieran Bingham May 22, 2025, 1:47 p.m. UTC | #2
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 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@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


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?

--
Kieran


> 
> Reviewed-by: Paul Elder <paul.elder@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':
> > -- 
> > 2.49.0
> >
Barnabás Pőcze May 22, 2025, 2:22 p.m. UTC | #3
Hi

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

Adding the `deprecated` attribute is I think a good idea, but more changes
would be needed to warn about deprecations in the configuration files.


Regards,
Barnabás Pőcze

> 
> --
> Kieran
> 
> 
>>
>> Reviewed-by: Paul Elder <paul.elder@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':
>>> -- 
>>> 2.49.0
>>>
Laurent Pinchart May 22, 2025, 3:01 p.m. UTC | #4
Hi Barnabás,

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

> 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@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':
Barnabás Pőcze May 22, 2025, 3:10 p.m. UTC | #5
Hi

2025. 05. 22. 17:01 keltezéssel, Laurent Pinchart írta:
> Hi Barnabás,
> 
> 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@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".


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@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':
>
Laurent Pinchart May 22, 2025, 3:22 p.m. UTC | #6
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@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 ?

> >> 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@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':
Barnabás Pőcze May 22, 2025, 3:28 p.m. UTC | #7
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@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@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':
>

Patch
diff mbox series

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':