[libcamera-devel] [PATCH v5 1/6] ipa: ipu3: Replace event-based ops with dedicated functions

paul.elder at ideasonboard.com paul.elder at ideasonboard.com
Fri Apr 8 09:01:19 CEST 2022


Hi Kieran,

On Thu, Apr 07, 2022 at 11:11:34PM +0100, Kieran Bingham via libcamera-devel wrote:
> Quoting Umang Jain via libcamera-devel (2022-04-06 15:17:04)
> > The IPAIPU3 interface currently uses event-type based structures in
> > order to communicate with the pipeline-handler (and vice-versa).
> > Replace the event based structures with dedicated functions associated
> > to each operation.
> > 
> > The translated naming scheme of operations to dedicated functions:
> 
> So I think these without () are signals? If so we should state that here?
> 
> The Actions are translated to signals:
> >   ActionSetSensorControls => setSensorControls
> >   ActionParamFilled       => paramsBufferReady
> >   ActionMetadataReady     => metadataReady
> 
> And Events are translated to dedicated functions:
> 
> >   EventProcessControls    => queueRequest()
> >   EventStatReady          => processStatsBuffer()
> >   EventFillParams         => fillParamsBuffer()
> > 
> 
> Is there really a distinction between the use of signals and functions
> in either direction? or is it ultimately just signals both ways? (Or is
> it signals connected to functions of the same name? in both ways?)

Pipeline handler -> IPA calls are functions calls, from both the
perspective of the pipeline handler and the IPA. That is, the pipeline
handler can do ipa_->queueRequest() and the IPA implements a
queueRequest function. Under the hood it's either invokeMethod or IPC
send, so it's not a signal.

IPA -> pipeline handler is signal emission. The IPA emits a signal and
the pipeline handler handles it with a slot.

> Anyway - that bit doesn't really matter it's just the commit message.
> 
> It's so hard to parse this patch. We really need to make sure something
> like this is split from the start next time.

tbh yeah it is. I'm used to this pattern of patch though so it wasn't
that bad :p


Paul

> 
> I have one question about paramsBufferReady below - but I can't see
> anything else standing out so with that resolved or otherwise:
> 
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> 
> > Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> >  include/libcamera/ipa/ipu3.mojom       |  36 ++-----
> >  src/ipa/ipu3/ipu3-ipa-design-guide.rst |  27 +++---
> >  src/ipa/ipu3/ipu3.cpp                  | 129 +++++++++++--------------
> >  src/libcamera/pipeline/ipu3/ipu3.cpp   | 122 ++++++++++-------------
> >  4 files changed, 130 insertions(+), 184 deletions(-)
> > 
> > diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
> > index 18cdc744..d1b1c6b8 100644
> > --- a/include/libcamera/ipa/ipu3.mojom
> > +++ b/include/libcamera/ipa/ipu3.mojom
> > @@ -8,32 +8,6 @@ module ipa.ipu3;
> >  
> >  import "include/libcamera/ipa/core.mojom";
> >  
> > -enum IPU3Operations {
> > -       ActionSetSensorControls = 1,
> > -       ActionParamFilled = 2,
> > -       ActionMetadataReady = 3,
> > -       EventProcessControls = 4,
> > -       EventStatReady = 5,
> > -       EventFillParams = 6,
> > -};
> > -
> > -struct IPU3Event {
> > -       IPU3Operations op;
> > -       uint32 frame;
> > -       int64 frameTimestamp;
> > -       uint32 bufferId;
> > -       libcamera.ControlList controls;
> > -       libcamera.ControlList sensorControls;
> > -       libcamera.ControlList lensControls;
> > -};
> > -
> > -struct IPU3Action {
> > -       IPU3Operations op;
> > -       libcamera.ControlList controls;
> > -       libcamera.ControlList sensorControls;
> > -       libcamera.ControlList lensControls;
> > -};
> > -
> >  struct IPAConfigInfo {
> >         libcamera.IPACameraSensorInfo sensorInfo;
> >         libcamera.ControlInfoMap sensorControls;
> > @@ -56,9 +30,15 @@ interface IPAIPU3Interface {
> >         mapBuffers(array<libcamera.IPABuffer> buffers);
> >         unmapBuffers(array<uint32> ids);
> >  
> > -       [async] processEvent(IPU3Event ev);
> > +       [async] queueRequest(uint32 frame, libcamera.ControlList controls);
> > +       [async] fillParamsBuffer(uint32 frame, uint32 bufferId);
> > +       [async] processStatsBuffer(uint32 frame, int64 frameTimestamp,
> > +                                  uint32 bufferId, libcamera.ControlList sensorControls);
> >  };
> >  
> >  interface IPAIPU3EventInterface {
> > -       queueFrameAction(uint32 frame, IPU3Action action);
> > +       setSensorControls(uint32 frame, libcamera.ControlList sensorControls,
> > +                         libcamera.ControlList lensControls);
> > +       paramsBufferReady(uint32 frame);
> > +       metadataReady(uint32 frame, libcamera.ControlList metadata);
> >  };
> > diff --git a/src/ipa/ipu3/ipu3-ipa-design-guide.rst b/src/ipa/ipu3/ipu3-ipa-design-guide.rst
> > index 89c71108..e724fdda 100644
> > --- a/src/ipa/ipu3/ipu3-ipa-design-guide.rst
> > +++ b/src/ipa/ipu3/ipu3-ipa-design-guide.rst
> > @@ -25,7 +25,8 @@ from applications, and managing events from the pipeline handler.
> >        └─┬───┬───┬──────┬────┬────┬────┬─┴────▼─┬──┘    1: init()
> >          │   │   │      │ ▲  │ ▲  │ ▲  │ ▲      │       2: configure()
> >          │1  │2  │3     │4│  │4│  │4│  │4│      │5      3: mapBuffers(), start()
> > -        ▼   ▼   ▼      ▼ │  ▼ │  ▼ │  ▼ │      ▼       4: processEvent()
> > +        │   │   │      │ │  │ │  │ │  │ │      │       4: (▼) queueRequest(), fillParamsBuffer(), processStatsBuffer()
> > +        ▼   ▼   ▼      ▼ │  ▼ │  ▼ │  ▼ │      ▼          (▲) setSensorControls, paramsBufferReady, metadataReady Signals
> 
> I like that this is more descriptive about the direction and operations
> that occur in 4.
> 
> >        ┌──────────────────┴────┴────┴────┴─────────┐    5: stop(), unmapBuffers()
> >        │ IPU3 IPA                                  │
> >        │                 ┌───────────────────────┐ │
> > @@ -100,8 +101,9 @@ There are three main interactions with the algorithms for the IPU3 IPA
> >  to operate when running:
> >  
> >  -  configure()
> > --  processEvent(``EventFillParams``)
> > --  processEvent(``EventStatReady``)
> > +-  queueRequest()
> > +-  fillParamsBuffer()
> > +-  processStatsBuffer()
> >  
> >  The configuration phase allows the pipeline-handler to inform the IPA of
> >  the current stream configurations, which is then passed into each
> > @@ -114,8 +116,8 @@ Pre-frame preparation
> >  When configured, the IPA is notified by the pipeline handler of the
> >  Camera ``start()`` event, after which incoming requests will be queued
> >  for processing, requiring a parameter buffer (``ipu3_uapi_params``) to
> > -be populated for the ImgU. This is given to the IPA through the
> > -``EventFillParams`` event, and then passed directly to each algorithm
> > +be populated for the ImgU. This is given to the IPA through
> > +``fillParamsBuffer()``, and then passed directly to each algorithm
> >  through the ``prepare()`` call allowing the ISP configuration to be
> >  updated for the needs of each component that the algorithm is
> >  responsible for.
> > @@ -125,7 +127,7 @@ structure that it modifies, and it should take care to ensure that any
> >  structure set by a use flag is fully initialised to suitable values.
> >  
> >  The parameter buffer is returned to the pipeline handler through the
> > -``ActionParamFilled`` event, and from there queued to the ImgU along
> > +``paramsBufferReady`` signal, and from there queued to the ImgU along
> >  with a raw frame captured with the CIO2.
> >  
> >  Post-frame completion
> > @@ -133,8 +135,8 @@ Post-frame completion
> >  
> >  When the capture of an image is completed, and successfully processed
> >  through the ImgU, the generated statistics buffer
> > -(``ipu3_uapi_stats_3a``) is given to the IPA through the
> > -``EventStatReady`` event. This provides the IPA with an opportunity to
> > +(``ipu3_uapi_stats_3a``) is given to the IPA through
> > +``processStatsBuffer()``. This provides the IPA with an opportunity to
> >  examine the results of the ISP and run the calculations required by each
> >  algorithm on the new data. The algorithms may require context from the
> >  operations of other algorithms, for example, the AWB might choose to use
> > @@ -145,11 +147,14 @@ before they are needed.
> >  The ordering of the algorithm processing is determined by their
> >  placement in the ``IPU3::algorithms_`` ordered list.
> >  
> > +Finally, the IPA metadata for the completed frame is returned back via
> > +the ``metadataReady`` signal.
> > +
> >  Sensor Controls
> >  ~~~~~~~~~~~~~~~
> >  
> >  The AutoExposure and AutoGain (AGC) algorithm differs slightly from the
> >  others as it requires operating directly on the sensor, as opposed to
> > -through the ImgU ISP. To support this, there is a dedicated action
> > -`ActionSetSensorControls` to allow the IPA to request controls to be set
> > -on the camera sensor through the pipeline handler.
> > +through the ImgU ISP. To support this, there is a ``setSensorControls``
> > +signal to allow the IPA to request controls to be set on the camera
> > +sensor through the pipeline handler.
> > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> > index 50b52d8b..9a59f80f 100644
> > --- a/src/ipa/ipu3/ipu3.cpp
> > +++ b/src/ipa/ipu3/ipu3.cpp
> > @@ -65,8 +65,9 @@ namespace ipa::ipu3 {
> >   * The IPU3 Pipeline defines an IPU3-specific interface for communication
> >   * between the PipelineHandler and the IPA module.
> >   *
> > - * We extend the IPAIPU3Interface to implement our algorithms and handle events
> > - * from the IPU3 PipelineHandler to satisfy requests from the application.
> > + * We extend the IPAIPU3Interface to implement our algorithms and handle
> > + * calls from the IPU3 PipelineHandler to satisfy requests from the
> > + * application.
> >   *
> >   * At initialisation time, a CameraSensorHelper is instantiated to support
> >   * camera-specific calculations, while the default controls are computed, and
> > @@ -81,14 +82,14 @@ namespace ipa::ipu3 {
> >   * parameter buffer, and adapting the settings of the sensor attached to the
> >   * IPU3 CIO2 through sensor-specific V4L2 controls.
> >   *
> > - * When the event \a EventFillParams occurs we populate the ImgU parameter
> > - * buffer with settings to configure the device in preparation for handling the
> > - * frame queued in the Request.
> > + * In fillParamsBuffer(), we populate the ImgU parameter buffer with
> > + * settings to configure the device in preparation for handling the frame
> > + * queued in the Request.
> >   *
> >   * When the frame has completed processing, the ImgU will generate a statistics
> > - * buffer which is given to the IPA as part of the \a EventStatReady event. At
> > - * this event we run the algorithms to parse the statistics and cache any
> > - * results for the next \a EventFillParams event.
> > + * buffer which is given to the IPA with processStatsBuffer(). In this we run the
> > + * algorithms to parse the statistics and cache any results for the next
> > + * fillParamsBuffer() call.
> >   *
> >   * The individual algorithms are split into modular components that are called
> >   * iteratively to allow them to process statistics from the ImgU in a defined
> > @@ -143,14 +144,18 @@ public:
> >  
> >         void mapBuffers(const std::vector<IPABuffer> &buffers) override;
> >         void unmapBuffers(const std::vector<unsigned int> &ids) override;
> > -       void processEvent(const IPU3Event &event) override;
> >  
> > +       void queueRequest(const uint32_t frame, const ControlList &controls) override;
> > +       void fillParamsBuffer(const uint32_t frame, const uint32_t bufferId) override;
> > +       void processStatsBuffer(const uint32_t frame, const int64_t frameTimestamp,
> > +                               const uint32_t bufferId,
> > +                               const ControlList &sensorControls) override;
> >  private:
> >         void updateControls(const IPACameraSensorInfo &sensorInfo,
> >                             const ControlInfoMap &sensorControls,
> >                             ControlInfoMap *ipaControls);
> >         void updateSessionConfiguration(const ControlInfoMap &sensorControls);
> > -       void processControls(unsigned int frame, const ControlList &controls);
> > +
> >         void fillParams(unsigned int frame, ipu3_uapi_params *params);
> >         void parseStatistics(unsigned int frame,
> >                              int64_t frameTimestamp,
> > @@ -505,73 +510,61 @@ void IPAIPU3::unmapBuffers(const std::vector<unsigned int> &ids)
> >  }
> >  
> >  /**
> > - * \brief Process an event generated by the pipeline handler
> > - * \param[in] event The event sent from pipeline handler
> > - *
> > - * The expected event handling over the lifetime of a Request has
> > - * the following sequence:
> > - *
> > - *   - EventProcessControls : Handle controls from a new Request
> > - *   - EventFillParams : Prepare the ISP to process the Request
> > - *   - EventStatReady : Process statistics after ISP completion
> > + * \brief Fill and return a buffer with ISP processing parameters for a frame
> > + * \param[in] frame The frame number
> > + * \param[in] bufferId ID of the parameter buffer to fill
> >   */
> > -void IPAIPU3::processEvent(const IPU3Event &event)
> > +void IPAIPU3::fillParamsBuffer(const uint32_t frame, const uint32_t bufferId)
> >  {
> > -       switch (event.op) {
> > -       case EventProcessControls: {
> > -               processControls(event.frame, event.controls);
> > -               break;
> > +       auto it = buffers_.find(bufferId);
> > +       if (it == buffers_.end()) {
> > +               LOG(IPAIPU3, Error) << "Could not find param buffer!";
> > +               return;
> >         }
> > -       case EventFillParams: {
> > -               auto it = buffers_.find(event.bufferId);
> > -               if (it == buffers_.end()) {
> > -                       LOG(IPAIPU3, Error) << "Could not find param buffer!";
> > -                       return;
> > -               }
> >  
> > -               Span<uint8_t> mem = it->second.planes()[0];
> > -               ipu3_uapi_params *params =
> > -                       reinterpret_cast<ipu3_uapi_params *>(mem.data());
> > +       Span<uint8_t> mem = it->second.planes()[0];
> > +       ipu3_uapi_params *params =
> > +               reinterpret_cast<ipu3_uapi_params *>(mem.data());
> >  
> > -               fillParams(event.frame, params);
> > -               break;
> > -       }
> > -       case EventStatReady: {
> > -               auto it = buffers_.find(event.bufferId);
> > -               if (it == buffers_.end()) {
> > -                       LOG(IPAIPU3, Error) << "Could not find stats buffer!";
> > -                       return;
> > -               }
> > +       fillParams(frame, params);
> > +}
> >  
> > -               Span<uint8_t> mem = it->second.planes()[0];
> > -               const ipu3_uapi_stats_3a *stats =
> > -                       reinterpret_cast<ipu3_uapi_stats_3a *>(mem.data());
> > +/**
> > + * \brief Process statistics after ISP completion
> > + * \param[in] frame The frame number
> > + * \param[in] frameTimestamp Timestamp of the frame
> > + * \param[in] bufferId ID of the statistics buffer
> > + * \param[in] sensorControls Sensor controls
> > + */
> > +void IPAIPU3::processStatsBuffer(const uint32_t frame, const int64_t frameTimestamp,
> > +                                const uint32_t bufferId, const ControlList &sensorControls)
> > +{
> > +       auto it = buffers_.find(bufferId);
> > +       if (it == buffers_.end()) {
> > +               LOG(IPAIPU3, Error) << "Could not find stats buffer!";
> > +               return;
> > +       }
> >  
> > -               int32_t exposure = event.sensorControls.get(V4L2_CID_EXPOSURE).get<int32_t>();
> > -               int32_t gain = event.sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>();
> > +       Span<uint8_t> mem = it->second.planes()[0];
> > +       const ipu3_uapi_stats_3a *stats =
> > +               reinterpret_cast<ipu3_uapi_stats_3a *>(mem.data());
> >  
> > -               context_.frameContext.sensor.exposure = exposure;
> > -               context_.frameContext.sensor.gain = camHelper_->gain(gain);
> > +       context_.frameContext.sensor.exposure = sensorControls.get(V4L2_CID_EXPOSURE).get<int32_t>();
> > +       context_.frameContext.sensor.gain = camHelper_->gain(sensorControls.get(V4L2_CID_ANALOGUE_GAIN).get<int32_t>());
> >  
> > -               parseStatistics(event.frame, event.frameTimestamp, stats);
> > -               break;
> > -       }
> > -       default:
> > -               LOG(IPAIPU3, Error) << "Unknown event " << event.op;
> > -               break;
> > -       }
> > +       parseStatistics(frame, frameTimestamp, stats);
> >  }
> >  
> >  /**
> > - * \brief Process a control list for a request from the application
> > + * \brief Queue a request and process the control list from the application
> >   * \param[in] frame The number of the frame which will be processed next
> >   * \param[in] controls The controls for the \a frame
> >   *
> >   * Parse the request to handle any IPA-managed controls that were set from the
> >   * application such as manual sensor settings.
> >   */
> > -void IPAIPU3::processControls([[maybe_unused]] unsigned int frame,
> > -                             [[maybe_unused]] const ControlList &controls)
> > +void IPAIPU3::queueRequest(const uint32_t frame,
> > +                          [[maybe_unused]] const ControlList &controls)
> >  {
> >         /* \todo Start processing for 'frame' based on 'controls'. */
> >  }
> > @@ -600,10 +593,7 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params)
> >         for (auto const &algo : algorithms_)
> >                 algo->prepare(context_, params);
> >  
> > -       IPU3Action op;
> > -       op.op = ActionParamFilled;
> > -
> > -       queueFrameAction.emit(frame, op);
> > +       paramsBufferReady.emit(frame);
> >  }
> >  
> >  /**
> > @@ -647,11 +637,7 @@ void IPAIPU3::parseStatistics(unsigned int frame,
> >          * likely want to avoid putting platform specific metadata in.
> >          */
> >  
> > -       IPU3Action op;
> > -       op.op = ActionMetadataReady;
> > -       op.controls = ctrls;
> > -
> > -       queueFrameAction.emit(frame, op);
> > +       metadataReady.emit(frame, ctrls);
> >  }
> >  
> >  /**
> > @@ -663,23 +649,18 @@ void IPAIPU3::parseStatistics(unsigned int frame,
> >   */
> >  void IPAIPU3::setControls(unsigned int frame)
> >  {
> > -       IPU3Action op;
> > -       op.op = ActionSetSensorControls;
> > -
> >         int32_t exposure = context_.frameContext.agc.exposure;
> >         int32_t gain = camHelper_->gainCode(context_.frameContext.agc.gain);
> >  
> >         ControlList ctrls(sensorCtrls_);
> >         ctrls.set(V4L2_CID_EXPOSURE, exposure);
> >         ctrls.set(V4L2_CID_ANALOGUE_GAIN, gain);
> > -       op.sensorControls = ctrls;
> >  
> >         ControlList lensCtrls(lensCtrls_);
> >         lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE,
> >                       static_cast<int32_t>(context_.frameContext.af.focus));
> > -       op.lensControls = lensCtrls;
> >  
> > -       queueFrameAction.emit(frame, op);
> > +       setSensorControls.emit(frame, ctrls, lensCtrls);
> >  }
> >  
> >  } /* namespace ipa::ipu3 */
> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > index 60e01917..59d7e9c0 100644
> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > @@ -86,8 +86,10 @@ public:
> >         ControlInfoMap ipaControls_;
> >  
> >  private:
> > -       void queueFrameAction(unsigned int id,
> > -                             const ipa::ipu3::IPU3Action &action);
> > +       void metadataReady(unsigned int id, const ControlList &metadata);
> > +       void paramsFilled(unsigned int id);
> 
> This is confusing. ActionParamFilled becomes paramsBufferReady in the
> commit message. Is this function used?
> 
> > +       void setSensorControls(unsigned int id, const ControlList &sensorControls,
> > +                              const ControlList &lensControls);
> >  };
> >  
> >  class IPU3CameraConfiguration : public CameraConfiguration
> > @@ -871,11 +873,7 @@ void IPU3CameraData::queuePendingRequests()
> >  
> >                 info->rawBuffer = rawBuffer;
> >  
> > -               ipa::ipu3::IPU3Event ev;
> > -               ev.op = ipa::ipu3::EventProcessControls;
> > -               ev.frame = info->id;
> > -               ev.controls = request->controls();
> > -               ipa_->processEvent(ev);
> > +               ipa_->queueRequest(info->id, request->controls());
> >  
> >                 pendingRequests_.pop();
> >                 processingRequests_.push(request);
> > @@ -1218,7 +1216,9 @@ int IPU3CameraData::loadIPA()
> >         if (!ipa_)
> >                 return -ENOENT;
> >  
> > -       ipa_->queueFrameAction.connect(this, &IPU3CameraData::queueFrameAction);
> > +       ipa_->setSensorControls.connect(this, &IPU3CameraData::setSensorControls);
> > +       ipa_->paramsBufferReady.connect(this, &IPU3CameraData::paramsFilled);
> 
> Oh - I see - the signals are connected to functions of the same name
> within the IPU3CameraData.
> 
> Is there a reason why 
>   queueFrameAction => queueFrameAction,
>   setSensorControls => setSensorControls,
>   metadataReady => metadataReady,
> but
>   paramsBufferReady => paramsFilled?
> 
> 
> 
> > +       ipa_->metadataReady.connect(this, &IPU3CameraData::metadataReady);
> >  
> >         /*
> >          * Pass the sensor info to the IPA to initialize controls.
> > @@ -1253,69 +1253,58 @@ int IPU3CameraData::loadIPA()
> >         return 0;
> >  }
> >  
> > -void IPU3CameraData::queueFrameAction(unsigned int id,
> > -                                     const ipa::ipu3::IPU3Action &action)
> > +void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id,
> > +                                      const ControlList &sensorControls,
> > +                                      const ControlList &lensControls)
> >  {
> > -       switch (action.op) {
> > -       case ipa::ipu3::ActionSetSensorControls: {
> > -               const ControlList &sensorControls = action.sensorControls;
> > -               delayedCtrls_->push(sensorControls);
> > +       delayedCtrls_->push(sensorControls);
> >  
> > -               CameraLens *focusLens = cio2_.sensor()->focusLens();
> > -               if (!focusLens)
> > -                       break;
> > -
> > -               const ControlList lensControls = action.lensControls;
> > -               if (!lensControls.contains(V4L2_CID_FOCUS_ABSOLUTE))
> > -                       break;
> > +       CameraLens *focusLens = cio2_.sensor()->focusLens();
> > +       if (!focusLens)
> > +               return;
> >  
> > -               const ControlValue &focusValue =
> > -                       lensControls.get(V4L2_CID_FOCUS_ABSOLUTE);
> > +       if (!lensControls.contains(V4L2_CID_FOCUS_ABSOLUTE))
> > +               return;
> >  
> > -               focusLens->setFocusPosition(focusValue.get<int32_t>());
> > +       const ControlValue &focusValue = lensControls.get(V4L2_CID_FOCUS_ABSOLUTE);
> >  
> > -               break;
> > -       }
> > -       case ipa::ipu3::ActionParamFilled: {
> > -               IPU3Frames::Info *info = frameInfos_.find(id);
> > -               if (!info)
> > -                       break;
> > -
> > -               /* Queue all buffers from the request aimed for the ImgU. */
> > -               for (auto it : info->request->buffers()) {
> > -                       const Stream *stream = it.first;
> > -                       FrameBuffer *outbuffer = it.second;
> > +       focusLens->setFocusPosition(focusValue.get<int32_t>());
> > +}
> >  
> > -                       if (stream == &outStream_)
> > -                               imgu_->output_->queueBuffer(outbuffer);
> > -                       else if (stream == &vfStream_)
> > -                               imgu_->viewfinder_->queueBuffer(outbuffer);
> > -               }
> > +void IPU3CameraData::paramsFilled(unsigned int id)
> > +{
> > +       IPU3Frames::Info *info = frameInfos_.find(id);
> > +       if (!info)
> > +               return;
> >  
> > -               imgu_->param_->queueBuffer(info->paramBuffer);
> > -               imgu_->stat_->queueBuffer(info->statBuffer);
> > -               imgu_->input_->queueBuffer(info->rawBuffer);
> > +       /* Queue all buffers from the request aimed for the ImgU. */
> > +       for (auto it : info->request->buffers()) {
> > +               const Stream *stream = it.first;
> > +               FrameBuffer *outbuffer = it.second;
> >  
> > -               break;
> > +               if (stream == &outStream_)
> > +                       imgu_->output_->queueBuffer(outbuffer);
> > +               else if (stream == &vfStream_)
> > +                       imgu_->viewfinder_->queueBuffer(outbuffer);
> >         }
> > -       case ipa::ipu3::ActionMetadataReady: {
> > -               IPU3Frames::Info *info = frameInfos_.find(id);
> > -               if (!info)
> > -                       break;
> >  
> > -               Request *request = info->request;
> > -               request->metadata().merge(action.controls);
> > +       imgu_->param_->queueBuffer(info->paramBuffer);
> > +       imgu_->stat_->queueBuffer(info->statBuffer);
> > +       imgu_->input_->queueBuffer(info->rawBuffer);
> > +}
> >  
> > -               info->metadataProcessed = true;
> > -               if (frameInfos_.tryComplete(info))
> > -                       pipe()->completeRequest(request);
> > +void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)
> > +{
> > +       IPU3Frames::Info *info = frameInfos_.find(id);
> > +       if (!info)
> > +               return;
> >  
> > -               break;
> > -       }
> > -       default:
> > -               LOG(IPU3, Error) << "Unknown action " << action.op;
> > -               break;
> > -       }
> > +       Request *request = info->request;
> > +       request->metadata().merge(metadata);
> > +
> > +       info->metadataProcessed = true;
> > +       if (frameInfos_.tryComplete(info))
> > +               pipe()->completeRequest(request);
> >  }
> >  
> >  /* -----------------------------------------------------------------------------
> > @@ -1390,11 +1379,7 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
> >         if (request->findBuffer(&rawStream_))
> >                 pipe()->completeBuffer(request, buffer);
> >  
> > -       ipa::ipu3::IPU3Event ev;
> > -       ev.op = ipa::ipu3::EventFillParams;
> > -       ev.frame = info->id;
> > -       ev.bufferId = info->paramBuffer->cookie();
> > -       ipa_->processEvent(ev);
> > +       ipa_->fillParamsBuffer(info->id, info->paramBuffer->cookie());
> >  }
> >  
> >  void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)
> > @@ -1438,13 +1423,8 @@ void IPU3CameraData::statBufferReady(FrameBuffer *buffer)
> >                 return;
> >         }
> >  
> > -       ipa::ipu3::IPU3Event ev;
> > -       ev.op = ipa::ipu3::EventStatReady;
> > -       ev.frame = info->id;
> > -       ev.bufferId = info->statBuffer->cookie();
> > -       ev.frameTimestamp = request->metadata().get(controls::SensorTimestamp);
> > -       ev.sensorControls = info->effectiveSensorControls;
> > -       ipa_->processEvent(ev);
> > +       ipa_->processStatsBuffer(info->id, request->metadata().get(controls::SensorTimestamp),
> > +                                info->statBuffer->cookie(), info->effectiveSensorControls);
> >  }
> >  
> >  /*
> > -- 
> > 2.31.0
> >


More information about the libcamera-devel mailing list