[RFC] delayed_controls: avoid reading undefined control value

Kieran Bingham kieran.bingham at ideasonboard.com
Tue Dec 10 23:39:50 CET 2024


Quoting Stanislaw Gruszka (2024-12-06 11:27:43)
> Limit ControlRingBuffer index by number of queued entries in order do
> avoid reading undefined control value with type ControlTypeNone .
> 
> It can happen at the begging of streaming when ControlRingBuffer is

s/begging/beginning/

> not yet filled and there are errors on CSI-2 bus resulting dropping
> frames. Then we can call to DelayedControls::get() with frame number
> that exceed number of saved entries and get below assertion failure:
> 
> ../src/libcamera/delayed_controls.cpp:227:
> libcamera::ControlList libcamera::DelayedControls::get(uint32_t):
> Assertion `info.type() != ControlTypeNone' failed
> 
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=241
> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka at linux.intel.com>
> ---
> Notes: When debugging this I notice that the push() and get() are
> done in different threads. Maybe mutex should be
> used? Not sure how synchronization works for mojom signals
> handlers.

I thought they would be in the same thread as the CameraManager event
loop...  Perhaps we could/should have an assertion that the thread is
the same - otherwise - yes it would probably need a lock if there's a
reader and a writer on both ends of the queue.

I'd double check the threading first.

> Also I'm not sure if similar change like in this patch
> is not needed for rpi DelayedControls

Probably. There's very little different between the two implementations,
so we should probably keep them aligned with bugfixes at least until
someone tries to realign them both again.

It looks like the cookie feature was easier to fork than to add, I can't
remember all the details ;_(


> Alternative fix would be to pre-fill ControlRingBuffer with
> valid control values. Should we care about possibility
> of queueCount_ overflowing ? 

I'm not sure what 'valid' control values would be ? I think just
clamping to the most recent data is probably the best we can do ? And 'I
think' would reflect the most up to date information we have about
what's configured on the sensor - so I think it's still even the 'most
correct' (and probably even 'is' correct) data we can return in the
get() call in this event.


I think I can already throw this on here, it seems like a sane input
parameter validation:


Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>

> 
>  src/libcamera/delayed_controls.cpp | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp
> index 94d0a575..78b0b8f7 100644
> --- a/src/libcamera/delayed_controls.cpp
> +++ b/src/libcamera/delayed_controls.cpp
> @@ -202,7 +202,7 @@ bool DelayedControls::push(const ControlList &controls)
>   */
>  ControlList DelayedControls::get(uint32_t sequence)
>  {
> -       unsigned int index = std::max<int>(0, sequence - maxDelay_);
> +       unsigned int index = std::clamp<int>(sequence - maxDelay_, 0, queueCount_ - 1);
> 
>         ControlList out(device_->controls());
>         for (const auto &ctrl : values_) {
> --
> 2.43.0
>


More information about the libcamera-devel mailing list