[v11,01/19] libcamera: property: Add MinimumRequests property
diff mbox series

Message ID 20250428090413.38234-2-s.pueschel@pengutronix.de
State New
Headers show
Series
  • lc-compliance: Add test to queue more requests than hardware depth
Related show

Commit Message

Sven Püschel April 28, 2025, 9:02 a.m. UTC
From: Nícolas F. R. A. Prado <nfraprado@collabora.com>

The MinimumRequests property reports the minimum number of capture
requests that the camera pipeline requires to have queued in order to
sustain capture operations without frame drops. At this quantity,
there's no guarantee that manual per-frame controls will apply
correctly. The quantity needed for that may be added as a separate
property in the future.

The mali-c55 driver defines min_queued_buffers = 1 [1]. Therefore set
set the minimum requests to 2 to account one request in the userspace.

The dcmipp and j721e drivers both defines min_queued_buffers = 1
in the kernel under
drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
and drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c .
Therefore use these values, as they are added 1 more.

For the intel-ipu6, mtk-seninf simple devices and the virtual pipeline
use a conservative value of 3 minimumBuffers, as no further requirements
are known about them.

[1] https://lore.kernel.org/linux-media/20240131174355.GB20792@pendragon.ideasonboard.com/T/#t

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>

---
Changes in v11
- Add mali-c55, dcmipp, virtual, j721e, intel-ipu6 and mtk-seninf
- Hold only the minimum buffers instead of the whole deviceInfo pointer in SimpleCameraData
- Adjusted min_buffers_needed property to min_reqbufs_allocation in docs
- Relax property description from no frame drops -> only minimal frame
  drops, based on the comment from Naush [10]
- Changed property type from int32_t -> uint32_t to match all of the
  indirect casts to an unsigned value throughout the existing patchset.
- Removed Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- Removed Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>

[10] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html

Changes in v10:
- ipu3: add a constant to populate MinimumRequests, as we'll also use it
  elsewhere
- update pipeline handler guide to set vivid' MinimumRequests to 2
- expand the MinimumRequests property description to include a line
  about startup
- add isi

Changes in v9:
- rebased

Changes in v8:
- Changed the MinimumRequests property meaning to require that frames aren't
  dropped
- Set MinimumRequests on SimplePipeline depending on device and usage of
  converter
- Undid definition of default MinimumRequests on CameraSensor constructor
- Updated pipeline-handler guides with new MinimumRequests property

Changes in v7:
- Renamed property from MinNumRequests to MinimumRequests
- Changed MinimumRequests property's description

Changes in v6:
- Removed comment from Raspberrypi MinNumRequests setting
- Removed an extra blank line
---
 Documentation/guides/pipeline-handler.rst     | 20 ++++++---
 src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +
 src/libcamera/pipeline/ipu3/ipu3.cpp          |  4 ++
 src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  1 +
 src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  1 +
 .../pipeline/rpi/common/pipeline_base.cpp     |  2 +
 src/libcamera/pipeline/simple/simple.cpp      | 41 +++++++++++++++----
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +
 src/libcamera/pipeline/vimc/vimc.cpp          |  2 +
 src/libcamera/pipeline/virtual/virtual.cpp    |  1 +
 src/libcamera/property_ids_core.yaml          | 22 ++++++++++
 11 files changed, 85 insertions(+), 13 deletions(-)

Comments

Jacopo Mondi May 2, 2025, 4:28 p.m. UTC | #1
Hi Sevn,
  thanks for resurecting this!

Can I ask if this solves any actual problem and on which platform ?

On Mon, Apr 28, 2025 at 11:02:26AM +0200, Sven Püschel wrote:
> From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
>
> The MinimumRequests property reports the minimum number of capture
> requests that the camera pipeline requires to have queued in order to
> sustain capture operations without frame drops. At this quantity,
> there's no guarantee that manual per-frame controls will apply
> correctly. The quantity needed for that may be added as a separate
> property in the future.
>
> The mali-c55 driver defines min_queued_buffers = 1 [1]. Therefore set
> set the minimum requests to 2 to account one request in the userspace.
>
> The dcmipp and j721e drivers both defines min_queued_buffers = 1
> in the kernel under
> drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
> and drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c .
> Therefore use these values, as they are added 1 more.
>
> For the intel-ipu6, mtk-seninf simple devices and the virtual pipeline
> use a conservative value of 3 minimumBuffers, as no further requirements
> are known about them.
>
> [1] https://lore.kernel.org/linux-media/20240131174355.GB20792@pendragon.ideasonboard.com/T/#t
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> Acked-by: Umang Jain <umang.jain@ideasonboard.com>
> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
>
> ---
> Changes in v11
> - Add mali-c55, dcmipp, virtual, j721e, intel-ipu6 and mtk-seninf
> - Hold only the minimum buffers instead of the whole deviceInfo pointer in SimpleCameraData
> - Adjusted min_buffers_needed property to min_reqbufs_allocation in docs
> - Relax property description from no frame drops -> only minimal frame
>   drops, based on the comment from Naush [10]
> - Changed property type from int32_t -> uint32_t to match all of the
>   indirect casts to an unsigned value throughout the existing patchset.
> - Removed Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> - Removed Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
>
> [10] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
>
> Changes in v10:
> - ipu3: add a constant to populate MinimumRequests, as we'll also use it
>   elsewhere
> - update pipeline handler guide to set vivid' MinimumRequests to 2
> - expand the MinimumRequests property description to include a line
>   about startup
> - add isi
>
> Changes in v9:
> - rebased
>
> Changes in v8:
> - Changed the MinimumRequests property meaning to require that frames aren't
>   dropped
> - Set MinimumRequests on SimplePipeline depending on device and usage of
>   converter
> - Undid definition of default MinimumRequests on CameraSensor constructor
> - Updated pipeline-handler guides with new MinimumRequests property
>
> Changes in v7:
> - Renamed property from MinNumRequests to MinimumRequests
> - Changed MinimumRequests property's description
>
> Changes in v6:
> - Removed comment from Raspberrypi MinNumRequests setting
> - Removed an extra blank line
> ---
>  Documentation/guides/pipeline-handler.rst     | 20 ++++++---
>  src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +
>  src/libcamera/pipeline/ipu3/ipu3.cpp          |  4 ++
>  src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  1 +
>  src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  1 +
>  .../pipeline/rpi/common/pipeline_base.cpp     |  2 +
>  src/libcamera/pipeline/simple/simple.cpp      | 41 +++++++++++++++----
>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +
>  src/libcamera/pipeline/vimc/vimc.cpp          |  2 +
>  src/libcamera/pipeline/virtual/virtual.cpp    |  1 +
>  src/libcamera/property_ids_core.yaml          | 22 ++++++++++
>  11 files changed, 85 insertions(+), 13 deletions(-)
>

[snip]

> index 834454a4..cc28d677 100644
> --- a/src/libcamera/property_ids_core.yaml
> +++ b/src/libcamera/property_ids_core.yaml
> @@ -701,4 +701,26 @@ controls:
>
>          Different cameras may report identical devices.
>
> +  - MinimumRequests:

I'm still not at ease with the definition of this property, I'm
afraid.

It seems to be mixing two different things (maybe 3 :)

> +      type: uint32_t
> +      description: |
> +        The minimum number of capture requests that the camera pipeline requires
> +        to have queued in order to sustain capture operations with only minimal


The reference to "minimal frame drops" is a bit too loosely
specified ?

> +        frame drops. At this quantity, there's no guarantee that manual per
> +        frame controls will apply correctly. This is also the minimum number of

The per-frame control pipeline depth does depend on other factors
such as the sensor delays, specifically for manual AE/AWB control


> +        requests that must be queued before capture starts.

The number of buffers required to start streaming comes directly from
the min_queued_buffers variable defined by drivers (unfortunatetly not
available to users through any uAPI). One thing I would like to see
happening is drivers stop setting min_queued_buffers at all, or if not
possible maybe expose it through an api (a RO v4l2 control ?).

Drivers should allocate internal buffers and use them if the
application doesn't keep, and handle both the runtime underruns and
start streaming conditions using scratch buffers.

Even if this won't happen in drivers, the requirement should not be
exposed to libcamera users. In the "great scheme of things" the idea
is to decouple application's Requests from the frames pipeline, and
providing enough buffers to sustain the frame rate should be a
pipeline/IPA job.

True, for platforms where drivers already require min_queued_buffers
applications right now have to queue enough requests before
start receiving frames back, and we goofly report it through
StreamConfiguration::bufferCount.

Unless there's an actual use case or any angle I'm grossly
missing I don't think this property is a good idea..

> +
> +        This property is based on the minimum number of memory buffers
> +        needed to fill the capture pipeline composed of hardware processing
> +        blocks plus as many buffers as needed to take into account propagation
> +        delays and avoid dropping frames.
> +
> +        \todo Should this be a per-stream property?
> +
> +        \todo Extend this property to expose the different minimum buffer and
> +        request counts (the minimum number of buffers to be able to capture at
> +        all, the minimum number of buffers to sustain capture without frame
> +        drop, and the minimum number of requests to ensure proper operation of
> +        per-frame controls).
> +
>  ...
> --
> 2.49.0
>
Sven Püschel May 5, 2025, 12:23 p.m. UTC | #2
Hi Jacopo,

On 5/2/25 18:28, Jacopo Mondi wrote:
> Hi Sevn,
>    thanks for resurecting this!
>
> Can I ask if this solves any actual problem and on which platform ?

The problem I'm facing is that in a more complex setup with the rkisp1 
we need to keep multiple dmabufs in the userspace. But the hardcoded 
value of 4 buffers in the rkisp1 driver seems to expect that the 
application only hold around one buffer and have the other 3 buffers 
queued for a smooth frame capture. But due to holding more dmabufs, I'm 
running into massive frame drops due to usually only having one request 
queued and waiting for it to finish.

Therefore I want to allocate more dmabufs for this problematic use case 
and avoid patching libcamera to increase the hardcoded buffer count of 
rkisp1 (which would also apply globally).

Kieran then pointed me towards this patchset to allow the application to 
control the amount of dmabufs allocated.


> On Mon, Apr 28, 2025 at 11:02:26AM +0200, Sven Püschel wrote:
>> From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
>>
>> The MinimumRequests property reports the minimum number of capture
>> requests that the camera pipeline requires to have queued in order to
>> sustain capture operations without frame drops. At this quantity,
>> there's no guarantee that manual per-frame controls will apply
>> correctly. The quantity needed for that may be added as a separate
>> property in the future.
>>
>> The mali-c55 driver defines min_queued_buffers = 1 [1]. Therefore set
>> set the minimum requests to 2 to account one request in the userspace.
>>
>> The dcmipp and j721e drivers both defines min_queued_buffers = 1
>> in the kernel under
>> drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
>> and drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c .
>> Therefore use these values, as they are added 1 more.
>>
>> For the intel-ipu6, mtk-seninf simple devices and the virtual pipeline
>> use a conservative value of 3 minimumBuffers, as no further requirements
>> are known about them.
>>
>> [1] https://lore.kernel.org/linux-media/20240131174355.GB20792@pendragon.ideasonboard.com/T/#t
>>
>> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
>> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
>> Acked-by: Umang Jain <umang.jain@ideasonboard.com>
>> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
>>
>> ---
>> Changes in v11
>> - Add mali-c55, dcmipp, virtual, j721e, intel-ipu6 and mtk-seninf
>> - Hold only the minimum buffers instead of the whole deviceInfo pointer in SimpleCameraData
>> - Adjusted min_buffers_needed property to min_reqbufs_allocation in docs
>> - Relax property description from no frame drops -> only minimal frame
>>    drops, based on the comment from Naush [10]
>> - Changed property type from int32_t -> uint32_t to match all of the
>>    indirect casts to an unsigned value throughout the existing patchset.
>> - Removed Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> - Removed Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
>>
>> [10] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
>>
>> Changes in v10:
>> - ipu3: add a constant to populate MinimumRequests, as we'll also use it
>>    elsewhere
>> - update pipeline handler guide to set vivid' MinimumRequests to 2
>> - expand the MinimumRequests property description to include a line
>>    about startup
>> - add isi
>>
>> Changes in v9:
>> - rebased
>>
>> Changes in v8:
>> - Changed the MinimumRequests property meaning to require that frames aren't
>>    dropped
>> - Set MinimumRequests on SimplePipeline depending on device and usage of
>>    converter
>> - Undid definition of default MinimumRequests on CameraSensor constructor
>> - Updated pipeline-handler guides with new MinimumRequests property
>>
>> Changes in v7:
>> - Renamed property from MinNumRequests to MinimumRequests
>> - Changed MinimumRequests property's description
>>
>> Changes in v6:
>> - Removed comment from Raspberrypi MinNumRequests setting
>> - Removed an extra blank line
>> ---
>>   Documentation/guides/pipeline-handler.rst     | 20 ++++++---
>>   src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +
>>   src/libcamera/pipeline/ipu3/ipu3.cpp          |  4 ++
>>   src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  1 +
>>   src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  1 +
>>   .../pipeline/rpi/common/pipeline_base.cpp     |  2 +
>>   src/libcamera/pipeline/simple/simple.cpp      | 41 +++++++++++++++----
>>   src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +
>>   src/libcamera/pipeline/vimc/vimc.cpp          |  2 +
>>   src/libcamera/pipeline/virtual/virtual.cpp    |  1 +
>>   src/libcamera/property_ids_core.yaml          | 22 ++++++++++
>>   11 files changed, 85 insertions(+), 13 deletions(-)
>>
> [snip]
>
>> index 834454a4..cc28d677 100644
>> --- a/src/libcamera/property_ids_core.yaml
>> +++ b/src/libcamera/property_ids_core.yaml
>> @@ -701,4 +701,26 @@ controls:
>>
>>           Different cameras may report identical devices.
>>
>> +  - MinimumRequests:
> I'm still not at ease with the definition of this property, I'm
> afraid.
>
> It seems to be mixing two different things (maybe 3 :)
>> +      type: uint32_t
>> +      description: |
>> +        The minimum number of capture requests that the camera pipeline requires
>> +        to have queued in order to sustain capture operations with only minimal
>
> The reference to "minimal frame drops" is a bit too loosely
> specified ?

I've changed it due to Naushir's claim that there is no practical number 
to gurantee no frame drops [1]

[1] 
https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html


>> +        frame drops. At this quantity, there's no guarantee that manual per
>> +        frame controls will apply correctly. This is also the minimum number of
> The per-frame control pipeline depth does depend on other factors
> such as the sensor delays, specifically for manual AE/AWB control

and that is the reason it isn't or cannot be part of this property? Or 
what's your point?

>> +        requests that must be queued before capture starts.
> The number of buffers required to start streaming comes directly from
> the min_queued_buffers variable defined by drivers (unfortunatetly not
> available to users through any uAPI). One thing I would like to see
> happening is drivers stop setting min_queued_buffers at all, or if not
> possible maybe expose it through an api (a RO v4l2 control ?).
>
> Drivers should allocate internal buffers and use them if the
> application doesn't keep, and handle both the runtime underruns and
> start streaming conditions using scratch buffers.
>
> Even if this won't happen in drivers, the requirement should not be
> exposed to libcamera users. In the "great scheme of things" the idea
> is to decouple application's Requests from the frames pipeline, and
> providing enough buffers to sustain the frame rate should be a
> pipeline/IPA job.
>
> True, for platforms where drivers already require min_queued_buffers
> applications right now have to queue enough requests before
> start receiving frames back, and we goofly report it through
> StreamConfiguration::bufferCount.
>
> Unless there's an actual use case or any angle I'm grossly
> missing I don't think this property is a good idea..

I understand your problem with this property. But I don't know if we can 
get away without providing the application a hint how many dmabufs it 
should allocate at least.

To recall my problem, the rkisp1 driver seems to already use scratch 
buffers when it doesn't have enough buffers queued. So while queuing one 
buffer at a time worked, it wasn't desired due to the frame drops from 
the scratch buffers.

But the application developer cannot really know how many buffers are 
really required. From my perspective the current operation mode is that 
libcamera allocates a sensible fixed amount of dmabufs and application 
developers just queue all unused buffers to libcamera [2]. So when the 
allocation is now put into the hands of the application developer, it 
may just always allocate 2 buffers (to have still one queued when 
handling a completed buffer) and therefore only queue a maximum of 2 
buffers. The driver fills the lack of buffers with scratch buffers, 
which cause unintended frame drops.

One potential solution may be to pass the desired amount of buffers held 
in the application to the allocator. Then the pipeline could allocate a 
sensible amount of buffers (e.g. 1 requested for the application + 3 
queued => 4 buffers) and the application would queue all unused buffers 
as usual.

Other than that I don't see how libcamera could abstract this property 
away, as applications control which buffers are used for a given request.


[2] 
https://www.libcamera.org/guides/application-developer.html#request-queueing 



>> +        This property is based on the minimum number of memory buffers
>> +        needed to fill the capture pipeline composed of hardware processing
>> +        blocks plus as many buffers as needed to take into account propagation
>> +        delays and avoid dropping frames.
>> +
>> +        \todo Should this be a per-stream property?
>> +
>> +        \todo Extend this property to expose the different minimum buffer and
>> +        request counts (the minimum number of buffers to be able to capture at
>> +        all, the minimum number of buffers to sustain capture without frame
>> +        drop, and the minimum number of requests to ensure proper operation of
>> +        per-frame controls).
>> +
>>   ...
>> --
>> 2.49.0
>>
Jacopo Mondi May 5, 2025, 1:59 p.m. UTC | #3
Hi Sven

On Mon, May 05, 2025 at 02:23:13PM +0200, Sven Püschel wrote:
> Hi Jacopo,
>
> On 5/2/25 18:28, Jacopo Mondi wrote:
> > Hi Sevn,
> >    thanks for resurecting this!
> >
> > Can I ask if this solves any actual problem and on which platform ?
>
> The problem I'm facing is that in a more complex setup with the rkisp1 we
> need to keep multiple dmabufs in the userspace. But the hardcoded value of 4
> buffers in the rkisp1 driver seems to expect that the application only hold
> around one buffer and have the other 3 buffers queued for a smooth frame
> capture. But due to holding more dmabufs, I'm running into massive frame
> drops due to usually only having one request queued and waiting for it to
> finish.

Thanks for the overview.

Can't more buffers be allocated by setting a larger value in
StreamConfiguration::bufferCount (which is indeed now hardcoded to 4) ?

>
> Therefore I want to allocate more dmabufs for this problematic use case and
> avoid patching libcamera to increase the hardcoded buffer count of rkisp1
> (which would also apply globally).
>
> Kieran then pointed me towards this patchset to allow the application to
> control the amount of dmabufs allocated.
>
>
> > On Mon, Apr 28, 2025 at 11:02:26AM +0200, Sven Püschel wrote:
> > > From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> > >
> > > The MinimumRequests property reports the minimum number of capture
> > > requests that the camera pipeline requires to have queued in order to
> > > sustain capture operations without frame drops. At this quantity,
> > > there's no guarantee that manual per-frame controls will apply
> > > correctly. The quantity needed for that may be added as a separate
> > > property in the future.
> > >
> > > The mali-c55 driver defines min_queued_buffers = 1 [1]. Therefore set
> > > set the minimum requests to 2 to account one request in the userspace.
> > >
> > > The dcmipp and j721e drivers both defines min_queued_buffers = 1
> > > in the kernel under
> > > drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
> > > and drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c .
> > > Therefore use these values, as they are added 1 more.
> > >
> > > For the intel-ipu6, mtk-seninf simple devices and the virtual pipeline
> > > use a conservative value of 3 minimumBuffers, as no further requirements
> > > are known about them.
> > >
> > > [1] https://lore.kernel.org/linux-media/20240131174355.GB20792@pendragon.ideasonboard.com/T/#t
> > >
> > > Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> > > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> > > Acked-by: Umang Jain <umang.jain@ideasonboard.com>
> > > Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
> > >
> > > ---
> > > Changes in v11
> > > - Add mali-c55, dcmipp, virtual, j721e, intel-ipu6 and mtk-seninf
> > > - Hold only the minimum buffers instead of the whole deviceInfo pointer in SimpleCameraData
> > > - Adjusted min_buffers_needed property to min_reqbufs_allocation in docs
> > > - Relax property description from no frame drops -> only minimal frame
> > >    drops, based on the comment from Naush [10]
> > > - Changed property type from int32_t -> uint32_t to match all of the
> > >    indirect casts to an unsigned value throughout the existing patchset.
> > > - Removed Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > - Removed Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
> > >
> > > [10] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
> > >
> > > Changes in v10:
> > > - ipu3: add a constant to populate MinimumRequests, as we'll also use it
> > >    elsewhere
> > > - update pipeline handler guide to set vivid' MinimumRequests to 2
> > > - expand the MinimumRequests property description to include a line
> > >    about startup
> > > - add isi
> > >
> > > Changes in v9:
> > > - rebased
> > >
> > > Changes in v8:
> > > - Changed the MinimumRequests property meaning to require that frames aren't
> > >    dropped
> > > - Set MinimumRequests on SimplePipeline depending on device and usage of
> > >    converter
> > > - Undid definition of default MinimumRequests on CameraSensor constructor
> > > - Updated pipeline-handler guides with new MinimumRequests property
> > >
> > > Changes in v7:
> > > - Renamed property from MinNumRequests to MinimumRequests
> > > - Changed MinimumRequests property's description
> > >
> > > Changes in v6:
> > > - Removed comment from Raspberrypi MinNumRequests setting
> > > - Removed an extra blank line
> > > ---
> > >   Documentation/guides/pipeline-handler.rst     | 20 ++++++---
> > >   src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +
> > >   src/libcamera/pipeline/ipu3/ipu3.cpp          |  4 ++
> > >   src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  1 +
> > >   src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  1 +
> > >   .../pipeline/rpi/common/pipeline_base.cpp     |  2 +
> > >   src/libcamera/pipeline/simple/simple.cpp      | 41 +++++++++++++++----
> > >   src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +
> > >   src/libcamera/pipeline/vimc/vimc.cpp          |  2 +
> > >   src/libcamera/pipeline/virtual/virtual.cpp    |  1 +
> > >   src/libcamera/property_ids_core.yaml          | 22 ++++++++++
> > >   11 files changed, 85 insertions(+), 13 deletions(-)
> > >
> > [snip]
> >
> > > index 834454a4..cc28d677 100644
> > > --- a/src/libcamera/property_ids_core.yaml
> > > +++ b/src/libcamera/property_ids_core.yaml
> > > @@ -701,4 +701,26 @@ controls:
> > >
> > >           Different cameras may report identical devices.
> > >
> > > +  - MinimumRequests:
> > I'm still not at ease with the definition of this property, I'm
> > afraid.
> >
> > It seems to be mixing two different things (maybe 3 :)
> > > +      type: uint32_t
> > > +      description: |
> > > +        The minimum number of capture requests that the camera pipeline requires
> > > +        to have queued in order to sustain capture operations with only minimal
> >
> > The reference to "minimal frame drops" is a bit too loosely
> > specified ?
>
> I've changed it due to Naushir's claim that there is no practical number to
> gurantee no frame drops [1]
>
> [1] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
>
>
> > > +        frame drops. At this quantity, there's no guarantee that manual per
> > > +        frame controls will apply correctly. This is also the minimum number of
> > The per-frame control pipeline depth does depend on other factors
> > such as the sensor delays, specifically for manual AE/AWB control
>
> and that is the reason it isn't or cannot be part of this property? Or
> what's your point?
>

My point is that the pipeline depth (which would need a more formal
definition as we use it quite freely without having ever set in stone
its definition) is a property unrelated to the minium number of
buffers or requests that has to be queued.

I would leave pipeline depth and per-frame control out of the picture.

> > > +        requests that must be queued before capture starts.
> > The number of buffers required to start streaming comes directly from
> > the min_queued_buffers variable defined by drivers (unfortunatetly not
> > available to users through any uAPI). One thing I would like to see
> > happening is drivers stop setting min_queued_buffers at all, or if not
> > possible maybe expose it through an api (a RO v4l2 control ?).
> >
> > Drivers should allocate internal buffers and use them if the
> > application doesn't keep, and handle both the runtime underruns and
> > start streaming conditions using scratch buffers.
> >
> > Even if this won't happen in drivers, the requirement should not be
> > exposed to libcamera users. In the "great scheme of things" the idea
> > is to decouple application's Requests from the frames pipeline, and
> > providing enough buffers to sustain the frame rate should be a
> > pipeline/IPA job.
> >
> > True, for platforms where drivers already require min_queued_buffers
> > applications right now have to queue enough requests before
> > start receiving frames back, and we goofly report it through
> > StreamConfiguration::bufferCount.
> >
> > Unless there's an actual use case or any angle I'm grossly
> > missing I don't think this property is a good idea..
>
> I understand your problem with this property. But I don't know if we can get
> away without providing the application a hint how many dmabufs it should
> allocate at least.
>

Well, the default value set by generateConfiguration() should be an
indication of what value the pipeline expects.

> To recall my problem, the rkisp1 driver seems to already use scratch buffers

Yes, I would love all drivers to remove min_queued_buffers as it was
done for rkisp1
https://www.spinics.net/lists/linux-media/msg264330.html

> when it doesn't have enough buffers queued. So while queuing one buffer at a
> time worked, it wasn't desired due to the frame drops from the scratch
> buffers.

Keeping up with the frame rate shouldn't be a driver concern but an
application's one. But of course if you can't allocate enough buffers
to queue them back fast enough, you can't do that.

>
> But the application developer cannot really know how many buffers are really
> required. From my perspective the current operation mode is that libcamera

The fact is that "really required" is an ill-formed concepts. As said
there are many different aspects at play: keeping up with the sensor's
frame rate, the pipeline depth required to guarantee per-frame control
and the number of buffers required to start streaming.

We currently report some min number of buffers (most of the times, but
not always coming from min_queued_buffers in the driver) in
StreamConfiguration::bufferCount, but this is certainly is a
sub-optimal API.

> allocates a sensible fixed amount of dmabufs and application developers just
> queue all unused buffers to libcamera [2]. So when the allocation is now put
> into the hands of the application developer, it may just always allocate 2
> buffers (to have still one queued when handling a completed buffer) and
> therefore only queue a maximum of 2 buffers. The driver fills the lack of
> buffers with scratch buffers, which cause unintended frame drops.

That's what should happen in the driver. The alternative would be not
being able to dequeue buffers at all. Simply, if an application
allocates two buffers only, it's calling for troubles, isn't it ?

>
> One potential solution may be to pass the desired amount of buffers held in
> the application to the allocator. Then the pipeline could allocate a
> sensible amount of buffers (e.g. 1 requested for the application + 3 queued
> => 4 buffers) and the application would queue all unused buffers as usual.
>

I wonder why RkISP1Path::validate() reset bufferCount to 4.
We should allow apps to allocate more buffers if they want to.

Kieran, Stefan, ideas ?

> Other than that I don't see how libcamera could abstract this property away,
> as applications control which buffers are used for a given request.
>

We certainly need a way to allow apps to allocate more than 4 buffers.
My main problem is with this property, which mixes in too many things
and is ill-defined.

>
> [2]
> https://www.libcamera.org/guides/application-developer.html#request-queueing
>
>
>
> > > +        This property is based on the minimum number of memory buffers
> > > +        needed to fill the capture pipeline composed of hardware processing
> > > +        blocks plus as many buffers as needed to take into account propagation
> > > +        delays and avoid dropping frames.
> > > +
> > > +        \todo Should this be a per-stream property?
> > > +
> > > +        \todo Extend this property to expose the different minimum buffer and
> > > +        request counts (the minimum number of buffers to be able to capture at
> > > +        all, the minimum number of buffers to sustain capture without frame
> > > +        drop, and the minimum number of requests to ensure proper operation of
> > > +        per-frame controls).
> > > +
> > >   ...
> > > --
> > > 2.49.0
> > >
Stefan Klug May 5, 2025, 2:40 p.m. UTC | #4
Hi Jacopo,

On Mon, May 05, 2025 at 03:59:33PM +0200, Jacopo Mondi wrote:
> Hi Sven
> 
> On Mon, May 05, 2025 at 02:23:13PM +0200, Sven Püschel wrote:
> > Hi Jacopo,
> >
> > On 5/2/25 18:28, Jacopo Mondi wrote:
> > > Hi Sevn,
> > >    thanks for resurecting this!
> > >
> > > Can I ask if this solves any actual problem and on which platform ?
> >
> > The problem I'm facing is that in a more complex setup with the rkisp1 we
> > need to keep multiple dmabufs in the userspace. But the hardcoded value of 4
> > buffers in the rkisp1 driver seems to expect that the application only hold
> > around one buffer and have the other 3 buffers queued for a smooth frame
> > capture. But due to holding more dmabufs, I'm running into massive frame
> > drops due to usually only having one request queued and waiting for it to
> > finish.
> 
> Thanks for the overview.
> 
> Can't more buffers be allocated by setting a larger value in
> StreamConfiguration::bufferCount (which is indeed now hardcoded to 4) ?
> 
> >
> > Therefore I want to allocate more dmabufs for this problematic use case and
> > avoid patching libcamera to increase the hardcoded buffer count of rkisp1
> > (which would also apply globally).
> >
> > Kieran then pointed me towards this patchset to allow the application to
> > control the amount of dmabufs allocated.
> >
> >
> > > On Mon, Apr 28, 2025 at 11:02:26AM +0200, Sven Püschel wrote:
> > > > From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> > > >
> > > > The MinimumRequests property reports the minimum number of capture
> > > > requests that the camera pipeline requires to have queued in order to
> > > > sustain capture operations without frame drops. At this quantity,
> > > > there's no guarantee that manual per-frame controls will apply
> > > > correctly. The quantity needed for that may be added as a separate
> > > > property in the future.
> > > >
> > > > The mali-c55 driver defines min_queued_buffers = 1 [1]. Therefore set
> > > > set the minimum requests to 2 to account one request in the userspace.
> > > >
> > > > The dcmipp and j721e drivers both defines min_queued_buffers = 1
> > > > in the kernel under
> > > > drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
> > > > and drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c .
> > > > Therefore use these values, as they are added 1 more.
> > > >
> > > > For the intel-ipu6, mtk-seninf simple devices and the virtual pipeline
> > > > use a conservative value of 3 minimumBuffers, as no further requirements
> > > > are known about them.
> > > >
> > > > [1] https://lore.kernel.org/linux-media/20240131174355.GB20792@pendragon.ideasonboard.com/T/#t
> > > >
> > > > Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> > > > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> > > > Acked-by: Umang Jain <umang.jain@ideasonboard.com>
> > > > Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
> > > >
> > > > ---
> > > > Changes in v11
> > > > - Add mali-c55, dcmipp, virtual, j721e, intel-ipu6 and mtk-seninf
> > > > - Hold only the minimum buffers instead of the whole deviceInfo pointer in SimpleCameraData
> > > > - Adjusted min_buffers_needed property to min_reqbufs_allocation in docs
> > > > - Relax property description from no frame drops -> only minimal frame
> > > >    drops, based on the comment from Naush [10]
> > > > - Changed property type from int32_t -> uint32_t to match all of the
> > > >    indirect casts to an unsigned value throughout the existing patchset.
> > > > - Removed Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > > - Removed Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
> > > >
> > > > [10] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
> > > >
> > > > Changes in v10:
> > > > - ipu3: add a constant to populate MinimumRequests, as we'll also use it
> > > >    elsewhere
> > > > - update pipeline handler guide to set vivid' MinimumRequests to 2
> > > > - expand the MinimumRequests property description to include a line
> > > >    about startup
> > > > - add isi
> > > >
> > > > Changes in v9:
> > > > - rebased
> > > >
> > > > Changes in v8:
> > > > - Changed the MinimumRequests property meaning to require that frames aren't
> > > >    dropped
> > > > - Set MinimumRequests on SimplePipeline depending on device and usage of
> > > >    converter
> > > > - Undid definition of default MinimumRequests on CameraSensor constructor
> > > > - Updated pipeline-handler guides with new MinimumRequests property
> > > >
> > > > Changes in v7:
> > > > - Renamed property from MinNumRequests to MinimumRequests
> > > > - Changed MinimumRequests property's description
> > > >
> > > > Changes in v6:
> > > > - Removed comment from Raspberrypi MinNumRequests setting
> > > > - Removed an extra blank line
> > > > ---
> > > >   Documentation/guides/pipeline-handler.rst     | 20 ++++++---
> > > >   src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +
> > > >   src/libcamera/pipeline/ipu3/ipu3.cpp          |  4 ++
> > > >   src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  1 +
> > > >   src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  1 +
> > > >   .../pipeline/rpi/common/pipeline_base.cpp     |  2 +
> > > >   src/libcamera/pipeline/simple/simple.cpp      | 41 +++++++++++++++----
> > > >   src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +
> > > >   src/libcamera/pipeline/vimc/vimc.cpp          |  2 +
> > > >   src/libcamera/pipeline/virtual/virtual.cpp    |  1 +
> > > >   src/libcamera/property_ids_core.yaml          | 22 ++++++++++
> > > >   11 files changed, 85 insertions(+), 13 deletions(-)
> > > >
> > > [snip]
> > >
> > > > index 834454a4..cc28d677 100644
> > > > --- a/src/libcamera/property_ids_core.yaml
> > > > +++ b/src/libcamera/property_ids_core.yaml
> > > > @@ -701,4 +701,26 @@ controls:
> > > >
> > > >           Different cameras may report identical devices.
> > > >
> > > > +  - MinimumRequests:
> > > I'm still not at ease with the definition of this property, I'm
> > > afraid.
> > >
> > > It seems to be mixing two different things (maybe 3 :)
> > > > +      type: uint32_t
> > > > +      description: |
> > > > +        The minimum number of capture requests that the camera pipeline requires
> > > > +        to have queued in order to sustain capture operations with only minimal
> > >
> > > The reference to "minimal frame drops" is a bit too loosely
> > > specified ?
> >
> > I've changed it due to Naushir's claim that there is no practical number to
> > gurantee no frame drops [1]
> >
> > [1] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
> >
> >
> > > > +        frame drops. At this quantity, there's no guarantee that manual per
> > > > +        frame controls will apply correctly. This is also the minimum number of
> > > The per-frame control pipeline depth does depend on other factors
> > > such as the sensor delays, specifically for manual AE/AWB control
> >
> > and that is the reason it isn't or cannot be part of this property? Or
> > what's your point?
> >
> 
> My point is that the pipeline depth (which would need a more formal
> definition as we use it quite freely without having ever set in stone
> its definition) is a property unrelated to the minium number of
> buffers or requests that has to be queued.
> 
> I would leave pipeline depth and per-frame control out of the picture.
> 
> > > > +        requests that must be queued before capture starts.
> > > The number of buffers required to start streaming comes directly from
> > > the min_queued_buffers variable defined by drivers (unfortunatetly not
> > > available to users through any uAPI). One thing I would like to see
> > > happening is drivers stop setting min_queued_buffers at all, or if not
> > > possible maybe expose it through an api (a RO v4l2 control ?).
> > >
> > > Drivers should allocate internal buffers and use them if the
> > > application doesn't keep, and handle both the runtime underruns and
> > > start streaming conditions using scratch buffers.
> > >
> > > Even if this won't happen in drivers, the requirement should not be
> > > exposed to libcamera users. In the "great scheme of things" the idea
> > > is to decouple application's Requests from the frames pipeline, and
> > > providing enough buffers to sustain the frame rate should be a
> > > pipeline/IPA job.
> > >
> > > True, for platforms where drivers already require min_queued_buffers
> > > applications right now have to queue enough requests before
> > > start receiving frames back, and we goofly report it through
> > > StreamConfiguration::bufferCount.
> > >
> > > Unless there's an actual use case or any angle I'm grossly
> > > missing I don't think this property is a good idea..
> >
> > I understand your problem with this property. But I don't know if we can get
> > away without providing the application a hint how many dmabufs it should
> > allocate at least.
> >
> 
> Well, the default value set by generateConfiguration() should be an
> indication of what value the pipeline expects.
> 
> > To recall my problem, the rkisp1 driver seems to already use scratch buffers
> 
> Yes, I would love all drivers to remove min_queued_buffers as it was
> done for rkisp1
> https://www.spinics.net/lists/linux-media/msg264330.html
> 
> > when it doesn't have enough buffers queued. So while queuing one buffer at a
> > time worked, it wasn't desired due to the frame drops from the scratch
> > buffers.
> 
> Keeping up with the frame rate shouldn't be a driver concern but an
> application's one. But of course if you can't allocate enough buffers
> to queue them back fast enough, you can't do that.
> 
> >
> > But the application developer cannot really know how many buffers are really
> > required. From my perspective the current operation mode is that libcamera
> 
> The fact is that "really required" is an ill-formed concepts. As said
> there are many different aspects at play: keeping up with the sensor's
> frame rate, the pipeline depth required to guarantee per-frame control
> and the number of buffers required to start streaming.
> 
> We currently report some min number of buffers (most of the times, but
> not always coming from min_queued_buffers in the driver) in
> StreamConfiguration::bufferCount, but this is certainly is a
> sub-optimal API.
> 
> > allocates a sensible fixed amount of dmabufs and application developers just
> > queue all unused buffers to libcamera [2]. So when the allocation is now put
> > into the hands of the application developer, it may just always allocate 2
> > buffers (to have still one queued when handling a completed buffer) and
> > therefore only queue a maximum of 2 buffers. The driver fills the lack of
> > buffers with scratch buffers, which cause unintended frame drops.
> 
> That's what should happen in the driver. The alternative would be not
> being able to dequeue buffers at all. Simply, if an application
> allocates two buffers only, it's calling for troubles, isn't it ?
> 
> >
> > One potential solution may be to pass the desired amount of buffers held in
> > the application to the allocator. Then the pipeline could allocate a
> > sensible amount of buffers (e.g. 1 requested for the application + 3 queued
> > => 4 buffers) and the application would queue all unused buffers as usual.
> >
> 
> I wonder why RkISP1Path::validate() reset bufferCount to 4.
> We should allow apps to allocate more buffers if they want to.
> 
> Kieran, Stefan, ideas ?

That code dates back 5 years, so I can only guess that it was done to
ensure stable operation without becoming too laggy. I completely agree
that an application should be able to freely decide how many buffers to
allocate. The issue with RkISP1 is that the algorithm control loop has
the same length as the buffer count. So when you increase that hardcoded
value to a bigger value, the regulation get's awfully slow. If I
remember correctly this get's partially solved/worked around in this
series. It is also addressed in the PFC topics we'll discuss this week. 

So I think we need a bit of internal discussions to come up with a well
defined path forward.

Best regards,
Stefan

> 
> > Other than that I don't see how libcamera could abstract this property away,
> > as applications control which buffers are used for a given request.
> >
> 
> We certainly need a way to allow apps to allocate more than 4 buffers.
> My main problem is with this property, which mixes in too many things
> and is ill-defined.
> 
> >
> > [2]
> > https://www.libcamera.org/guides/application-developer.html#request-queueing
> >
> >
> >
> > > > +        This property is based on the minimum number of memory buffers
> > > > +        needed to fill the capture pipeline composed of hardware processing
> > > > +        blocks plus as many buffers as needed to take into account propagation
> > > > +        delays and avoid dropping frames.
> > > > +
> > > > +        \todo Should this be a per-stream property?
> > > > +
> > > > +        \todo Extend this property to expose the different minimum buffer and
> > > > +        request counts (the minimum number of buffers to be able to capture at
> > > > +        all, the minimum number of buffers to sustain capture without frame
> > > > +        drop, and the minimum number of requests to ensure proper operation of
> > > > +        per-frame controls).
> > > > +
> > > >   ...
> > > > --
> > > > 2.49.0
> > > >
Sven Püschel May 5, 2025, 4:43 p.m. UTC | #5
Hi Jacopo, hi Stefan,

On 5/5/25 16:40, Stefan Klug wrote:
> Hi Jacopo,
>
> On Mon, May 05, 2025 at 03:59:33PM +0200, Jacopo Mondi wrote:
>> Hi Sven
>>
>> On Mon, May 05, 2025 at 02:23:13PM +0200, Sven Püschel wrote:
>>> Hi Jacopo,
>>>
>>> On 5/2/25 18:28, Jacopo Mondi wrote:
>>>> Hi Sevn,
>>>>     thanks for resurecting this!
>>>>
>>>> Can I ask if this solves any actual problem and on which platform ?
>>> The problem I'm facing is that in a more complex setup with the rkisp1 we
>>> need to keep multiple dmabufs in the userspace. But the hardcoded value of 4
>>> buffers in the rkisp1 driver seems to expect that the application only hold
>>> around one buffer and have the other 3 buffers queued for a smooth frame
>>> capture. But due to holding more dmabufs, I'm running into massive frame
>>> drops due to usually only having one request queued and waiting for it to
>>> finish.
>> Thanks for the overview.
>>
>> Can't more buffers be allocated by setting a larger value in
>> StreamConfiguration::bufferCount (which is indeed now hardcoded to 4) ?

Currently the bufferCount value is just overwritten in the validation of 
most pipeline handlers. The documentation also provides this as an 
example to set the bufferCount value to a fixed value in the validate() 
method [1]. But I think the raspberrypi pipeline handler already allows 
the bufferCount to be set by the application. I wouldn't mind using the 
bufferCount to set the actual frame buffer values, as it would allow me 
to shrink this patchset down to the rkisp1 part and probably would also 
be easier to merge (as it doesn't change the allocate function signature).

[1] 
https://www.libcamera.org/guides/pipeline-handler.html#generating-a-default-configuration

>>> Therefore I want to allocate more dmabufs for this problematic use case and
>>> avoid patching libcamera to increase the hardcoded buffer count of rkisp1
>>> (which would also apply globally).
>>>
>>> Kieran then pointed me towards this patchset to allow the application to
>>> control the amount of dmabufs allocated.
>>>
>>>
>>>> On Mon, Apr 28, 2025 at 11:02:26AM +0200, Sven Püschel wrote:
>>>>> From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
>>>>>
>>>>> The MinimumRequests property reports the minimum number of capture
>>>>> requests that the camera pipeline requires to have queued in order to
>>>>> sustain capture operations without frame drops. At this quantity,
>>>>> there's no guarantee that manual per-frame controls will apply
>>>>> correctly. The quantity needed for that may be added as a separate
>>>>> property in the future.
>>>>>
>>>>> The mali-c55 driver defines min_queued_buffers = 1 [1]. Therefore set
>>>>> set the minimum requests to 2 to account one request in the userspace.
>>>>>
>>>>> The dcmipp and j721e drivers both defines min_queued_buffers = 1
>>>>> in the kernel under
>>>>> drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
>>>>> and drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c .
>>>>> Therefore use these values, as they are added 1 more.
>>>>>
>>>>> For the intel-ipu6, mtk-seninf simple devices and the virtual pipeline
>>>>> use a conservative value of 3 minimumBuffers, as no further requirements
>>>>> are known about them.
>>>>>
>>>>> [1] https://lore.kernel.org/linux-media/20240131174355.GB20792@pendragon.ideasonboard.com/T/#t
>>>>>
>>>>> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
>>>>> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
>>>>> Acked-by: Umang Jain <umang.jain@ideasonboard.com>
>>>>> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
>>>>>
>>>>> ---
>>>>> Changes in v11
>>>>> - Add mali-c55, dcmipp, virtual, j721e, intel-ipu6 and mtk-seninf
>>>>> - Hold only the minimum buffers instead of the whole deviceInfo pointer in SimpleCameraData
>>>>> - Adjusted min_buffers_needed property to min_reqbufs_allocation in docs
>>>>> - Relax property description from no frame drops -> only minimal frame
>>>>>     drops, based on the comment from Naush [10]
>>>>> - Changed property type from int32_t -> uint32_t to match all of the
>>>>>     indirect casts to an unsigned value throughout the existing patchset.
>>>>> - Removed Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>>>>> - Removed Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
>>>>>
>>>>> [10] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
>>>>>
>>>>> Changes in v10:
>>>>> - ipu3: add a constant to populate MinimumRequests, as we'll also use it
>>>>>     elsewhere
>>>>> - update pipeline handler guide to set vivid' MinimumRequests to 2
>>>>> - expand the MinimumRequests property description to include a line
>>>>>     about startup
>>>>> - add isi
>>>>>
>>>>> Changes in v9:
>>>>> - rebased
>>>>>
>>>>> Changes in v8:
>>>>> - Changed the MinimumRequests property meaning to require that frames aren't
>>>>>     dropped
>>>>> - Set MinimumRequests on SimplePipeline depending on device and usage of
>>>>>     converter
>>>>> - Undid definition of default MinimumRequests on CameraSensor constructor
>>>>> - Updated pipeline-handler guides with new MinimumRequests property
>>>>>
>>>>> Changes in v7:
>>>>> - Renamed property from MinNumRequests to MinimumRequests
>>>>> - Changed MinimumRequests property's description
>>>>>
>>>>> Changes in v6:
>>>>> - Removed comment from Raspberrypi MinNumRequests setting
>>>>> - Removed an extra blank line
>>>>> ---
>>>>>    Documentation/guides/pipeline-handler.rst     | 20 ++++++---
>>>>>    src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +
>>>>>    src/libcamera/pipeline/ipu3/ipu3.cpp          |  4 ++
>>>>>    src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  1 +
>>>>>    src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  1 +
>>>>>    .../pipeline/rpi/common/pipeline_base.cpp     |  2 +
>>>>>    src/libcamera/pipeline/simple/simple.cpp      | 41 +++++++++++++++----
>>>>>    src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +
>>>>>    src/libcamera/pipeline/vimc/vimc.cpp          |  2 +
>>>>>    src/libcamera/pipeline/virtual/virtual.cpp    |  1 +
>>>>>    src/libcamera/property_ids_core.yaml          | 22 ++++++++++
>>>>>    11 files changed, 85 insertions(+), 13 deletions(-)
>>>>>
>>>> [snip]
>>>>
>>>>> index 834454a4..cc28d677 100644
>>>>> --- a/src/libcamera/property_ids_core.yaml
>>>>> +++ b/src/libcamera/property_ids_core.yaml
>>>>> @@ -701,4 +701,26 @@ controls:
>>>>>
>>>>>            Different cameras may report identical devices.
>>>>>
>>>>> +  - MinimumRequests:
>>>> I'm still not at ease with the definition of this property, I'm
>>>> afraid.
>>>>
>>>> It seems to be mixing two different things (maybe 3 :)
>>>>> +      type: uint32_t
>>>>> +      description: |
>>>>> +        The minimum number of capture requests that the camera pipeline requires
>>>>> +        to have queued in order to sustain capture operations with only minimal
>>>> The reference to "minimal frame drops" is a bit too loosely
>>>> specified ?
>>> I've changed it due to Naushir's claim that there is no practical number to
>>> gurantee no frame drops [1]
>>>
>>> [1] https://lists.libcamera.org/pipermail/libcamera-devel/2022-December/035872.html
>>>
>>>
>>>>> +        frame drops. At this quantity, there's no guarantee that manual per
>>>>> +        frame controls will apply correctly. This is also the minimum number of
>>>> The per-frame control pipeline depth does depend on other factors
>>>> such as the sensor delays, specifically for manual AE/AWB control
>>> and that is the reason it isn't or cannot be part of this property? Or
>>> what's your point?
>>>
>> My point is that the pipeline depth (which would need a more formal
>> definition as we use it quite freely without having ever set in stone
>> its definition) is a property unrelated to the minium number of
>> buffers or requests that has to be queued.
>>
>> I would leave pipeline depth and per-frame control out of the picture.
>>
>>>>> +        requests that must be queued before capture starts.
>>>> The number of buffers required to start streaming comes directly from
>>>> the min_queued_buffers variable defined by drivers (unfortunatetly not
>>>> available to users through any uAPI). One thing I would like to see
>>>> happening is drivers stop setting min_queued_buffers at all, or if not
>>>> possible maybe expose it through an api (a RO v4l2 control ?).
>>>>
>>>> Drivers should allocate internal buffers and use them if the
>>>> application doesn't keep, and handle both the runtime underruns and
>>>> start streaming conditions using scratch buffers.
>>>>
>>>> Even if this won't happen in drivers, the requirement should not be
>>>> exposed to libcamera users. In the "great scheme of things" the idea
>>>> is to decouple application's Requests from the frames pipeline, and
>>>> providing enough buffers to sustain the frame rate should be a
>>>> pipeline/IPA job.
>>>>
>>>> True, for platforms where drivers already require min_queued_buffers
>>>> applications right now have to queue enough requests before
>>>> start receiving frames back, and we goofly report it through
>>>> StreamConfiguration::bufferCount.
>>>>
>>>> Unless there's an actual use case or any angle I'm grossly
>>>> missing I don't think this property is a good idea..
>>> I understand your problem with this property. But I don't know if we can get
>>> away without providing the application a hint how many dmabufs it should
>>> allocate at least.
>>>
>> Well, the default value set by generateConfiguration() should be an
>> indication of what value the pipeline expects.

The patchset removes the bufferCount variable entirely. So the property 
tries to be (some kind of) a replacement to the info provided by 
bufferCount.

>>> To recall my problem, the rkisp1 driver seems to already use scratch buffers
>> Yes, I would love all drivers to remove min_queued_buffers as it was
>> done for rkisp1
>> https://www.spinics.net/lists/linux-media/msg264330.html
>>
>>> when it doesn't have enough buffers queued. So while queuing one buffer at a
>>> time worked, it wasn't desired due to the frame drops from the scratch
>>> buffers.
>> Keeping up with the frame rate shouldn't be a driver concern but an
>> application's one. But of course if you can't allocate enough buffers
>> to queue them back fast enough, you can't do that.
>>
>>> But the application developer cannot really know how many buffers are really
>>> required. From my perspective the current operation mode is that libcamera
>> The fact is that "really required" is an ill-formed concepts. As said
>> there are many different aspects at play: keeping up with the sensor's
>> frame rate, the pipeline depth required to guarantee per-frame control
>> and the number of buffers required to start streaming.
>>
>> We currently report some min number of buffers (most of the times, but
>> not always coming from min_queued_buffers in the driver) in
>> StreamConfiguration::bufferCount, but this is certainly is a
>> sub-optimal API.
>>
>>> allocates a sensible fixed amount of dmabufs and application developers just
>>> queue all unused buffers to libcamera [2]. So when the allocation is now put
>>> into the hands of the application developer, it may just always allocate 2
>>> buffers (to have still one queued when handling a completed buffer) and
>>> therefore only queue a maximum of 2 buffers. The driver fills the lack of
>>> buffers with scratch buffers, which cause unintended frame drops.
>> That's what should happen in the driver. The alternative would be not
>> being able to dequeue buffers at all. Simply, if an application
>> allocates two buffers only, it's calling for troubles, isn't it ?
>>
>>> One potential solution may be to pass the desired amount of buffers held in
>>> the application to the allocator. Then the pipeline could allocate a
>>> sensible amount of buffers (e.g. 1 requested for the application + 3 queued
>>> => 4 buffers) and the application would queue all unused buffers as usual.
>>>
>> I wonder why RkISP1Path::validate() reset bufferCount to 4.
>> We should allow apps to allocate more buffers if they want to.
>>
>> Kieran, Stefan, ideas ?
> That code dates back 5 years, so I can only guess that it was done to
> ensure stable operation without becoming too laggy. I completely agree
> that an application should be able to freely decide how many buffers to
> allocate. The issue with RkISP1 is that the algorithm control loop has
> the same length as the buffer count. So when you increase that hardcoded
> value to a bigger value, the regulation get's awfully slow. If I
> remember correctly this get's partially solved/worked around in this
> series. It is also addressed in the PFC topics we'll discuss this week.
That's correct. This patchset sets the number of parameter/statistic 
buffers to a fixed value (which allows proper operation), whereas the 
number of buffers the application desires is set using the allocate 
parameter (these are the "Don't rely on bufferCount" commits). Later in 
the series, I've cherry-picked another patchset that queues additional 
requests from the application, which fixes requests being canceled, when 
the application queues too many buffers (and we don't have 
parameter/statistic buffers available).
> So I think we need a bit of internal discussions to come up with a well
> defined path forward.
I'm excited for the result ^-^
>
> Best regards,
> Stefan
>
>>> Other than that I don't see how libcamera could abstract this property away,
>>> as applications control which buffers are used for a given request.
>>>
>> We certainly need a way to allow apps to allocate more than 4 buffers.
>> My main problem is with this property, which mixes in too many things
>> and is ill-defined.
>>
>>> [2]
>>> https://www.libcamera.org/guides/application-developer.html#request-queueing
>>>
>>>
>>>
>>>>> +        This property is based on the minimum number of memory buffers
>>>>> +        needed to fill the capture pipeline composed of hardware processing
>>>>> +        blocks plus as many buffers as needed to take into account propagation
>>>>> +        delays and avoid dropping frames.
>>>>> +
>>>>> +        \todo Should this be a per-stream property?
>>>>> +
>>>>> +        \todo Extend this property to expose the different minimum buffer and
>>>>> +        request counts (the minimum number of buffers to be able to capture at
>>>>> +        all, the minimum number of buffers to sustain capture without frame
>>>>> +        drop, and the minimum number of requests to ensure proper operation of
>>>>> +        per-frame controls).
>>>>> +
>>>>>    ...
>>>>> --
>>>>> 2.49.0
>>>>>

Patch
diff mbox series

diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst
index 9a15c20a..1079d998 100644
--- a/Documentation/guides/pipeline-handler.rst
+++ b/Documentation/guides/pipeline-handler.rst
@@ -663,19 +663,29 @@  associated with immutable values, which represent static characteristics that ca
 be used by applications to identify camera devices in the system. Properties can be
 registered by inspecting the values of V4L2 controls from the video devices and
 camera sensor (for example to retrieve the position and orientation of a camera)
-or to express other immutable characteristics. The example pipeline handler does
-not register any property, but examples are available in the libcamera code
-base.
+or to express other immutable characteristics.
 
-.. TODO: Add a property example to the pipeline handler. At least the model.
+A required property is ``MinimumRequests``, which indicates how many requests
+need to be queued in the pipeline for capture without frame drops to be
+possible.
+
+In our case, the vivid driver requires two buffers before it'll start streaming
+(can be seen in the ``min_reqbufs_allocation`` property for the ``vid_cap`` queue in
+vivid's driver code). Therefore we will set our ``MinimumRequests`` to two.
+Append the following line to ``init()``:
+
+.. code-block:: cpp
+
+   properties_.set(properties::MinimumRequests, 2);
 
 At this point you need to add the following includes to the top of the file for
-handling controls:
+handling controls and properties:
 
 .. code-block:: cpp
 
    #include <libcamera/controls.h>
    #include <libcamera/control_ids.h>
+   #include <libcamera/property_ids.h>
 
 Vendor-specific controls and properties
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
index ecda426a..2b8a583e 100644
--- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
+++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp
@@ -18,6 +18,7 @@ 
 #include <libcamera/camera_manager.h>
 #include <libcamera/formats.h>
 #include <libcamera/geometry.h>
+#include <libcamera/property_ids.h>
 #include <libcamera/stream.h>
 
 #include "libcamera/internal/bayer_format.h"
@@ -165,6 +166,7 @@  int ISICameraData::init()
 		return ret;
 
 	properties_ = sensor_->properties();
+	properties_.set(properties::MinimumRequests, 2);
 
 	return 0;
 }
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index e31e3879..356ca2e1 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -168,6 +168,8 @@  private:
 	MediaDevice *imguMediaDev_;
 
 	std::vector<IPABuffer> ipaBuffers_;
+
+	static constexpr unsigned int kMinimumRequests = 3;
 };
 
 IPU3CameraConfiguration::IPU3CameraConfiguration(IPU3CameraData *data)
@@ -1074,6 +1076,8 @@  int PipelineHandlerIPU3::registerCameras()
 		/* Initialize the camera properties. */
 		data->properties_ = cio2->sensor()->properties();
 
+		data->properties_.set(properties::MinimumRequests, kMinimumRequests);
+
 		ret = initControls(data.get());
 		if (ret)
 			continue;
diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
index a05e11fc..f0ab3d2e 100644
--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp
+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp
@@ -1602,6 +1602,7 @@  bool PipelineHandlerMaliC55::registerSensorCamera(MediaLink *ispLink)
 			return false;
 
 		data->properties_ = data->sensor_->properties();
+		data->properties_.set(properties::MinimumRequests, 2);
 
 		const CameraSensorProperties::SensorDelays &delays = data->sensor_->sensorDelays();
 		std::unordered_map<uint32_t, DelayedControls::ControlParams> params = {
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 194dfce7..5e3a4dba 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -1318,6 +1318,7 @@  int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 
 	/* Initialize the camera properties. */
 	data->properties_ = data->sensor_->properties();
+	data->properties_.set(properties::MinimumRequests, 3);
 
 	scalerMaxCrop_ = Rectangle(data->sensor_->resolution());
 
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
index 1f13e523..ef51d530 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
@@ -848,6 +848,8 @@  int PipelineHandlerBase::registerCamera(std::unique_ptr<RPi::CameraData> &camera
 	 */
 	data->properties_.set(properties::ScalerCropMaximum, Rectangle{});
 
+	data->properties_.set(properties::MinimumRequests, 3);
+
 	ret = platformRegister(cameraData, frontend, backend);
 	if (ret)
 		return ret;
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index efb07051..7abf0fc9 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -26,6 +26,7 @@ 
 
 #include <libcamera/camera.h>
 #include <libcamera/control_ids.h>
+#include <libcamera/property_ids.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
@@ -233,6 +234,10 @@  SimpleFrameInfo *SimpleFrames::find(uint32_t frame)
 
 struct SimplePipelineInfo {
 	const char *driver;
+	/*
+	 * Minimum number of buffers required by the driver to start streaming.
+	 */
+	unsigned int minimumBuffers;
 	/*
 	 * Each converter in the list contains the name
 	 * and the number of streams it supports.
@@ -249,14 +254,14 @@  struct SimplePipelineInfo {
 namespace {
 
 static const SimplePipelineInfo supportedDevices[] = {
-	{ "dcmipp", {}, false },
-	{ "imx7-csi", { { "pxp", 1 } }, false },
-	{ "intel-ipu6", {}, true },
-	{ "j721e-csi2rx", {}, true },
-	{ "mtk-seninf", { { "mtk-mdp", 3 } }, false },
-	{ "mxc-isi", {}, false },
-	{ "qcom-camss", {}, true },
-	{ "sun6i-csi", {}, false },
+	{ "dcmipp", 1, {}, false },
+	{ "imx7-csi", 2, { { "pxp", 1 } }, false },
+	{ "intel-ipu6", 3, {}, true }, // \todo Check if the minimumBuffers can be lowered
+	{ "j721e-csi2rx", 1, {}, true },
+	{ "mtk-seninf", 3, { { "mtk-mdp", 3 } }, false }, // \todo Check if the minimumBuffers can be lowered
+	{ "mxc-isi", 3, {}, false },
+	{ "qcom-camss", 1, {}, true },
+	{ "sun6i-csi", 3, {}, false },
 };
 
 } /* namespace */
@@ -346,6 +351,8 @@  public:
 	std::unique_ptr<SoftwareIsp> swIsp_;
 	SimpleFrames frameInfo_;
 
+	unsigned int deviceInfoMinimumBuffers;
+
 private:
 	void tryPipeline(unsigned int code, const Size &size);
 	static std::vector<const MediaPad *> routedSourcePads(MediaPad *sink);
@@ -1402,8 +1409,24 @@  int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)
 	inputCfg.bufferCount = kNumInternalBuffers;
 
 	if (data->converter_) {
+		/*
+		 * The application will interact only with the capture node of
+		 * the converter. Require two buffers for a frame drop free
+		 * conversion, plus one extra to account for requeue delays.
+		 */
+		data->properties_.set(properties::MinimumRequests, 3);
+
 		return data->converter_->configure(inputCfg, outputCfgs);
 	} else {
+		/*
+		 * The application will interact directly with the video capture
+		 * device. Require the minimum required by the driver, plus one
+		 * extra to account for requeue delays. Force at least three
+		 * buffers in order to not drop frames.
+		 */
+		data->properties_.set(properties::MinimumRequests, std::max(data->deviceInfoMinimumBuffers + 1,
+									    3U));
+
 		ipa::soft::IPAConfigInfo configInfo;
 		configInfo.sensorControls = data->sensor_->controls();
 		return data->swIsp_->configure(inputCfg, outputCfgs, configInfo);
@@ -1787,6 +1810,8 @@  bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
 	bool registered = false;
 
 	for (std::unique_ptr<SimpleCameraData> &data : pipelines) {
+		data->deviceInfoMinimumBuffers = info->minimumBuffers;
+
 		int ret = data->init();
 		if (ret < 0)
 			continue;
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 586e932d..31951a12 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -586,6 +586,8 @@  int UVCCameraData::init(MediaDevice *media)
 	properties_.set(properties::PixelArraySize, resolution);
 	properties_.set(properties::PixelArrayActiveAreas, { Rectangle(resolution) });
 
+	properties_.set(properties::MinimumRequests, 3);
+
 	/* Initialise the supported controls. */
 	ControlInfoMap::Map ctrls;
 
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 07273bd2..01685a64 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -24,6 +24,7 @@ 
 #include <libcamera/formats.h>
 #include <libcamera/framebuffer.h>
 #include <libcamera/geometry.h>
+#include <libcamera/property_ids.h>
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
@@ -592,6 +593,7 @@  int VimcCameraData::init()
 
 	/* Initialize the camera properties. */
 	properties_ = sensor_->properties();
+	properties_.set(properties::MinimumRequests, 3);
 
 	return 0;
 }
diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp
index 049ebcba..c33f1a5e 100644
--- a/src/libcamera/pipeline/virtual/virtual.cpp
+++ b/src/libcamera/pipeline/virtual/virtual.cpp
@@ -126,6 +126,7 @@  VirtualCameraData::VirtualCameraData(PipelineHandler *pipe,
 
 	properties_.set(properties::PixelArrayActiveAreas,
 			{ Rectangle(config_.maxResolutionSize) });
+	properties_.set(properties::MinimumRequests, 3);
 
 	/* \todo Support multiple streams and pass multi_stream_test */
 	streamConfigs_.resize(kMaxStream);
diff --git a/src/libcamera/property_ids_core.yaml b/src/libcamera/property_ids_core.yaml
index 834454a4..cc28d677 100644
--- a/src/libcamera/property_ids_core.yaml
+++ b/src/libcamera/property_ids_core.yaml
@@ -701,4 +701,26 @@  controls:
 
         Different cameras may report identical devices.
 
+  - MinimumRequests:
+      type: uint32_t
+      description: |
+        The minimum number of capture requests that the camera pipeline requires
+        to have queued in order to sustain capture operations with only minimal
+        frame drops. At this quantity, there's no guarantee that manual per
+        frame controls will apply correctly. This is also the minimum number of
+        requests that must be queued before capture starts.
+
+        This property is based on the minimum number of memory buffers
+        needed to fill the capture pipeline composed of hardware processing
+        blocks plus as many buffers as needed to take into account propagation
+        delays and avoid dropping frames.
+
+        \todo Should this be a per-stream property?
+
+        \todo Extend this property to expose the different minimum buffer and
+        request counts (the minimum number of buffers to be able to capture at
+        all, the minimum number of buffers to sustain capture without frame
+        drop, and the minimum number of requests to ensure proper operation of
+        per-frame controls).
+
 ...