gstreamer: Use Control<> objects when setting controls

`g_value_get_boolean()` returns `gboolean`, which is actually `int`. Thus

  // ControlValue x;
  auto val = g_value_get_boolean(...);
  x.set(val);

will cause `ControlValue::set<int, ...>(const int&)` to be called, which
will save the value as `ControlTypeInteger32`, not `ControlTypeBoolean`.

Then, if something tries to retrieve the boolean value, it will run into an
assertion failure:

  Assertion `type_ == details::control_type<std::remove_cv_t<T>>::value' failed.

in `ControlValue::set()`.

Fix this by using the appropriately typed `Control<>` object when setting
the value in the `ControlList` as this ensures that the value will be
converted to the actual type of the control.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=261
Fixes: 27cece6653 ("gstreamer: Generate controls from control_ids_*.yaml files")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Barnabás Pőcze 2025-03-28 16:20:46 +01:00
parent 7cd8818da8
commit 66fc6d2656

View file

@ -223,7 +223,6 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
{%- for ctrl in ctrls %} {%- for ctrl in ctrls %}
case controls::{{ ctrl.namespace }}{{ ctrl.name|snake_case|upper }}: { case controls::{{ ctrl.namespace }}{{ ctrl.name|snake_case|upper }}: {
ControlValue control;
{%- if ctrl.is_array %} {%- if ctrl.is_array %}
size_t size = gst_value_array_get_size(value); size_t size = gst_value_array_get_size(value);
{%- if ctrl.size != 0 %} {%- if ctrl.size != 0 %}
@ -254,12 +253,9 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
} }
{%- if ctrl.size == 0 %} {%- if ctrl.size == 0 %}
control.set(Span<const {{ ctrl.element_type }}>(values.data(), Span<const {{ ctrl.element_type }}> val(values.data(), size);
size));
{%- else %} {%- else %}
control.set(Span<const {{ ctrl.element_type }}, Span<const {{ ctrl.element_type }}, {{ ctrl.size }}> val(values.data(), size);
{{ ctrl.size }}>(values.data(),
{{ ctrl.size }}));
{%- endif %} {%- endif %}
{%- else %} {%- else %}
{%- if ctrl.is_rectangle %} {%- if ctrl.is_rectangle %}
@ -273,10 +269,9 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
{%- else %} {%- else %}
auto val = g_value_get_{{ ctrl.gtype }}(value); auto val = g_value_get_{{ ctrl.gtype }}(value);
{%- endif %} {%- endif %}
control.set(val);
{%- endif %} {%- endif %}
controls_.set(propId, control); controls_.set(controls::{{ ctrl.namespace }}{{ ctrl.name }}, val);
controls_acc_.set(propId, control); controls_acc_.set(controls::{{ ctrl.namespace }}{{ ctrl.name }}, val);
return true; return true;
} }
{%- endfor %} {%- endfor %}