[libcamera-devel] Concurrent camera usage in libcamera
Kieran Bingham
kieran.bingham at ideasonboard.com
Fri Oct 28 12:24:27 CEST 2022
Quoting Naushir Patuck via libcamera-devel (2022-10-28 10:42:55)
> Hi all,
>
> I wonder if I could get some thoughts regarding a problem we are seeing
> with running multiple cameras in separate libcamera processes on Raspberry
> Pi (this probably affects any/all platforms though).
>
> In my scenario, I have libcamera process 1 running "cam -c 1 -C" and
> streaming from imx477 using the Raspberry Pi pipeline handler. In process
> 2, I have "cam -c 2 -C" running streaming from a USB camera using the
> uvcvideo pipeline handler. If I exit process 2, I get the following error
> messages:
>
> [0:01:33.155169911] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241
> /dev/video2[16:cap]: Unable to request 0 buffers: Device or resource busy
> [0:01:33.155359910] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241
> /dev/video3[17:cap]: Unable to request 0 buffers: Device or resource busy
> [0:01:33.155460595] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241
> /dev/video13[18:out]: Unable to request 0 buffers: Device or resource busy
> [0:01:33.155564354] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241
> /dev/video14[19:cap]: Unable to request 0 buffers: Device or resource busy
> [0:01:33.155664150] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241
> /dev/video15[20:cap]: Unable to request 0 buffers: Device or resource busy
> [0:01:33.155763483] [1392] ERROR V4L2 v4l2_videodevice.cpp:1241
> /dev/video16[21:cap]: Unable to request 0 buffers: Device or resource busy
>
> These errors come up because the V4L2VideoDevice destructor in process 2 is
> indirectly calling ioctl(REQBUFS, 0) on all the Unicam and ISP device nodes
> while the device driver buffer queues are actively owned and used by
> process 1. This does not actively interfere with process 1 running, it
> continues happily enough.
>
> The error here stems from the fact that the RPi pipeline handler
> PipelineHandler::match() opens all the device nodes for every Camera object
> registered through PipelineHandler::registerCamera(). So even if the
> Camera was never used by a process, when terminating the V4L2VideoDevice
> destructor will call ioctl(REQBUFS, 0) for every single device. This
> behavior is exactly the same for the ipu3 and rkisp1 pipeline handlers.
>
> So the question is how to fix this and avoid the error messages?
>
> 1) The V4L2VideoDevice destructor should not call ioctl(REQBUFS, 0) if it
> has not allocated buffers for the device:
>
> diff --git a/src/libcamera/v4l2_videodevice.cpp
> b/src/libcamera/v4l2_videodevice.cpp
> index e30858c9fa02..108e60f035ab 100644
> --- a/src/libcamera/v4l2_videodevice.cpp
> +++ b/src/libcamera/v4l2_videodevice.cpp
> @@ -758,7 +758,8 @@ void V4L2VideoDevice::close()
> if (!isOpen())
> return;
>
> - releaseBuffers();
> + if (cache_)
> + releaseBuffers();
> delete fdBufferNotifier_;
>
> 2) All pipeline handlers need to change and avoid calling device open() in
> PipelineHandler::match(), and defer this call to when configure() gets
> called.
>
> Option 2 is not trivial, as (at least in the RPi pipeline handler) a bunch
> of validation occurs in PipelineHandler::match() that needs the device
> nodes to be open. In my opinion, option 1 seems to be the correct thing to
> do.
>
> Any other suggestions or thoughts?
As a quick reply, without looking through code - then yes, opeion 1
seems most reasonable. We should not be trying to release things that we
haven't claimed in that process.
At least the kernel is preventing it from actually releasing any memory
- (I believe) - but indeed - it's not a good position to be in, trying
to free someone elses buffers.
I'd check that releaseBuffers() isn't called anywhere else explicitly (I
expect this is just the destructor code path?) which might make the
cache_ check better suited in releaseBuffers() itself ... but otherwise
it seems sane to make sure we only release resources we acquire.
--
Kieran
>
> Regards,
> Naush
More information about the libcamera-devel
mailing list