[PATCH v1] gstreamer: Use `Control<>` objects when setting controls

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Apr 1 20:25:07 CEST 2025


On Tue, Apr 01, 2025 at 05:57:24PM +0100, Kieran Bingham wrote:
> Quoting Laurent Pinchart (2025-03-28 17:33:49)
> > Hi Barnabás,
> > 
> > Thank you for the patch.
> > 
> > On Fri, Mar 28, 2025 at 05:07:36PM +0100, Barnabás Pőcze wrote:
> > > `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`.
> > 
> > Oops... good catch !
> > 
> > > 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
> > > Signed-off-by: Barnabás Pőcze <barnabas.pocze at ideasonboard.com>
> > > ---
> > > There is a simpler fix to this issue as well:
> > > 
> > >       diff --git a/src/gstreamer/gstlibcamera-controls.cpp.in b/src/gstreamer/gstlibcamera-controls.cpp.in
> > >       index d937b19e6..8378b5fd0 100644
> > >       --- a/src/gstreamer/gstlibcamera-controls.cpp.in
> > >       +++ b/src/gstreamer/gstlibcamera-controls.cpp.in
> > >       @@ -271,7 +271,7 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
> > >                       }
> > >                       Rectangle val = value_get_rectangle(value);
> > >       {%- else %}
> > >       -               auto val = g_value_get_{{ ctrl.gtype }}(value);
> > >       +               {{ ctrl.element_type }} val = g_value_get_{{ ctrl.gtype }}(value);
> > 
> > I knew auto was bad :-D
> > 
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 
> Is this reviewing the simple fix, or the fix below?
> 
> If there's a simpler fix - what's the rationale for the longer fix
> below?

The fix below, I should have been more explicit.

> I don't mind which one is merged, they both have lots of templating
> magic which makes this hard to review, but fixing the bug is nice ;-)
> 
> For which ever of these approaches is desired/appropriate:
> 
> Acked-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> 
> > You fixed the bug even before I had a chance to look at the bug report.
> > Kudos !
> > 
> > >       {%- endif %}
> > >                       control.set(val);
> > >       {%- endif %}
> > > 
> > > ---
> > >  src/gstreamer/gstlibcamera-controls.cpp.in | 13 ++++---------
> > >  1 file changed, 4 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/src/gstreamer/gstlibcamera-controls.cpp.in b/src/gstreamer/gstlibcamera-controls.cpp.in
> > > index d937b19e6..89c530da0 100644
> > > --- a/src/gstreamer/gstlibcamera-controls.cpp.in
> > > +++ b/src/gstreamer/gstlibcamera-controls.cpp.in
> > > @@ -223,7 +223,6 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
> > >  {%- for ctrl in ctrls %}
> > > 
> > >       case controls::{{ ctrl.namespace }}{{ ctrl.name|snake_case|upper }}: {
> > > -             ControlValue control;
> > >  {%- if ctrl.is_array %}
> > >               size_t size = gst_value_array_get_size(value);
> > >  {%- if ctrl.size != 0 %}
> > > @@ -254,12 +253,9 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
> > >               }
> > > 
> > >  {%- if ctrl.size == 0 %}
> > > -             control.set(Span<const {{ ctrl.element_type }}>(values.data(),
> > > -                                                             size));
> > > +             Span<const {{ ctrl.element_type }}> val(values.data(), size);
> > >  {%- else %}
> > > -             control.set(Span<const {{ ctrl.element_type }},
> > > -                              {{ ctrl.size }}>(values.data(),
> > > -                                               {{ ctrl.size }}));
> > > +             Span<const {{ ctrl.element_type }}, {{ ctrl.size }}> val(values.data(), size);
> > >  {%- endif %}
> > >  {%- else %}
> > >  {%- if ctrl.is_rectangle %}
> > > @@ -273,10 +269,9 @@ bool GstCameraControls::setProperty(guint propId, const GValue *value,
> > >  {%- else %}
> > >               auto val = g_value_get_{{ ctrl.gtype }}(value);
> > >  {%- endif %}
> > > -             control.set(val);
> > >  {%- endif %}
> > > -             controls_.set(propId, control);
> > > -             controls_acc_.set(propId, control);
> > > +             controls_.set(controls::{{ ctrl.namespace }}{{ ctrl.name }}, val);
> > > +             controls_acc_.set(controls::{{ ctrl.namespace }}{{ ctrl.name }}, val);
> > >               return true;
> > >       }
> > >  {%- endfor %}

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list