[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:35:13 CEST 2022


Hi Umang,

On Fri, Apr 08, 2022 at 12:57:08PM +0530, Umang Jain wrote:
> Him
> 
> On 4/8/22 12:36, Umang Jain via libcamera-devel wrote:
> > Hi Paul,
> > 
> > On 4/8/22 12:25, paul.elder at ideasonboard.com wrote:
> > > Hi Umang,
> > > 
> > > On Wed, Apr 06, 2022 at 07:47:04PM +0530, Umang Jain via
> > > libcamera-devel wrote:
> > > > 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:
> > > >    ActionSetSensorControls => setSensorControls
> > > >    ActionParamFilled       => paramsBufferReady
> > > >    ActionMetadataReady     => metadataReady
> > > >    EventProcessControls    => queueRequest()
> > > Do you need to mention a bit on why just this one seems symmetrical? I
> > > know what's going on since you recently had a similar change, but for
> > > others perhaps not?
> > 
> > 
> > I can provide a sentence that it symmetrical to other IPA interfaces
> > now. But actually it was other way around that, other IPAs interface I
> > changed recently, were brought to symmetry with IPU3 - but they got
> > merged first!
> > 
> > No issue, I think a sentence regarding EventProcessControls =>
> > queueRequest() and what it is supposed to do might be helpful. I'll see
> > what is the best way to phrase it.
> 
> 
> I think I will go with this re-phrasing of the commit message:
> 
>     ipa: ipu3: Replace event-based ops with dedicated functions
> 
>     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 actions to signals are:
>       ActionSetSensorControls => setSensorControls
>       ActionParamFilled       => paramsBufferReady
>       ActionMetadataReady     => metadataReady
> 
>     The translated naming scheme of events to dedicated functions are:
>       EventProcessControls    => queueRequest()
>       EventStatReady          => processStatsBuffer()
>       EventFillParams         => fillParamsBuffer()
> 
>     The dedicated functions are called from pipeline-handler to the IPA
>     using IPC. These functions run asynchronously and when completed,
>     the IPA emits the respective signals as stated above in the translated
>     naming scheme.
> 
>     The EventProcessControls is translated to queueRequest() to bring
>     symmetry to the IPU3 interface with other IPA interfaces.

Looks good!


Paul

> 
> > 
> > > 
> > > >    EventStatReady          => processStatsBuffer()
> > > >    EventFillParams         => fillParamsBuffer()
> > > > 
> > > > Signed-off-by: Umang Jain <umang.jain at ideasonboard.com>
> > > > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > > Reviewed-by: Paul Elder <paul.elder 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
> > > >         ┌──────────────────┴────┴────┴────┴─────────┐    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);
> > > > +    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);
> > > > +    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