[0/8] libcamera: Support partial metadata completion
mbox series

Message ID 20241206160747.97176-1-jacopo.mondi@ideasonboard.com
Headers show
Series
  • libcamera: Support partial metadata completion
Related show

Message

Jacopo Mondi Dec. 6, 2024, 4:07 p.m. UTC
There has been quite some back and forth on how this should be done,
specifically how to have pipeline handlers behave uniformly and how to
have them use the same mechanism to signal metadata availability and store
the metadata in Request::metadata() for existing applications to access it.

I took the shortest paths: all pipeline handlers now use early metadata
completion, but the feature is totally opt-in for applications.

The basic idea is to restrict access to Request::metadata() to get a const
reference. This way pipeline handlers and applications cannot modify the
metadata list directly.

Then two new helpers have been added to PipelineHandler base for pipeline
handlers to add metadata results to Request::metadata(). These new
functions trigger the Camera::metadataAvailable signal from the core.

So now all pipeline handlers:
1) To store metadata have to use PipelineHandler::metadataAvailable() function
2) The core triggers Camera::metadataAvailable on behalf of pipelines

Performances:

- Controls are copied, this is bad as they can transport large quantity of data

  To avoid sending large quantity of data over a signal, and have the same
  data stored in Request::metadata, the new signal transports pointers to the
  ControlId that have been updated. Application can access the actual values
  from Request::metadata() using the ids.

- Avoid intermediate copies when calling PipelineHandler::metadataAvailable()

  Currently pipeline handlers either

  - Merge ControlList in Request::metadata()
  - Set single controls in Request::metadata()

  Merging ControlList was already non-efficient, as control values have been
  first copied to a list, then merged (copied) into Request::metadata. The
  new PipelineHandler::metadataAvailable(Request *, const ControlList &)
  doesn't introduce any additional copy.

  When it comes to setting single controls, the easier way would have been to
  use a ControlValue as in

  PipelineHandler::metadataAvailable(Request *, ControlId *, ControlValue &)

  However creating a ControlValue would first copy the control content in the
  temporary object, and the copy it again when setting it in
  Request::metadata(). To avoid double copies two templated functions have been
  prepared and the function arguments are copied directly into
  Request::metadata(). If I got this right the new

   metadataAvailable(request, controls::SomeControl, { .... });

  is not less efficient than

   request->metadata().set(controls::SomeControl, { ..... });

Last patch as DNI to show how the new signal can be used by applications.

Thanks
  j

Jacopo Mondi (8):
  libcamera: camera: Introduce metadataAvailable signal
  guides: application: Document Camera::metadataAvailable
  libcamera: pipeline_handler: Add metadataAvailable() function
  guides: pipeline_handler: Document PipelineHandler::metadataAvailable
  libcamera: request: Add function to reset metadata
  libcamera: pipelines: Use the metadataAvailable() function
  libcamera: request: Make access to metadata() const
  [DNI] apps: cam: Use Camera::metadataAvailable signal

 .../guides/application-developer.rst          |  8 ++
 Documentation/guides/pipeline-handler.rst     | 26 +++++--
 include/libcamera/camera.h                    |  2 +
 include/libcamera/internal/pipeline_handler.h | 41 ++++++++++
 include/libcamera/internal/request.h          |  8 ++
 include/libcamera/request.h                   |  4 +-
 src/apps/cam/camera_session.cpp               | 17 +++++
 src/apps/cam/camera_session.h                 |  2 +
 src/libcamera/camera.cpp                      | 42 +++++++++++
 src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  6 +-
 src/libcamera/pipeline/ipu3/ipu3.cpp          | 14 ++--
 src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  8 +-
 .../pipeline/rpi/common/pipeline_base.cpp     | 12 +--
 src/libcamera/pipeline/rpi/vc4/vc4.cpp        |  2 +-
 src/libcamera/pipeline/simple/simple.cpp      |  4 +-
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  4 +-
 src/libcamera/pipeline/vimc/vimc.cpp          |  4 +-
 src/libcamera/pipeline/virtual/virtual.cpp    |  3 +-
 src/libcamera/pipeline_handler.cpp            | 74 +++++++++++++++++++
 19 files changed, 243 insertions(+), 38 deletions(-)

--
2.47.1