[libcamera-devel] [PATCH v3 7/8] libcamera: pipeline: rkisp1: Use SOF event to warn about late parameters
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat Dec 5 03:08:32 CET 2020
Hi Niklas,
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
On Fri, Nov 27, 2020 at 12:05:10PM +0100, Jacopo Mondi wrote:
> On Mon, Nov 23, 2020 at 11:12:33PM +0100, Niklas Söderlund wrote:
> > In the Timeline approach the idea was to delay queuing buffers to the
> > device until the IPA had a chance to prepare the parameters buffer. A
> > check was still added to warn if the IPA queued buffers before the
> > parameters buffer was filled in.
> >
> > This check happened much sooner then needed as the parameter buffers
> > does not have to be ready when the buffer is queued but just before its
s/its/it's/
> > consumed. As the pipeline now has true knowledge of each SOF we can move
> > the check there and remove the delaying of queuing of buffers.
> >
> > This change really speeds up the IPA reactions as the delays used in the
> > Timeline where approximated while with this change they are driven by
> > events reported by the device.
> >
> > Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> > ---
> > src/libcamera/pipeline/rkisp1/rkisp1.cpp | 78 ++++++++----------------
> > 1 file changed, 24 insertions(+), 54 deletions(-)
> >
> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > index c3c4b5a65e3d9afe..3662a53ac4a43fcd 100644
> > --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > @@ -40,7 +40,6 @@ namespace libcamera {
> > LOG_DEFINE_CATEGORY(RkISP1)
> >
> > class PipelineHandlerRkISP1;
> > -class RkISP1ActionQueueBuffers;
> > class RkISP1CameraData;
> >
> > enum RkISP1ActionType {
> > @@ -203,7 +202,6 @@ private:
> > PipelineHandler::cameraData(camera));
> > }
> >
> > - friend RkISP1ActionQueueBuffers;
> > friend RkISP1CameraData;
> > friend RkISP1Frames;
> >
> > @@ -214,6 +212,7 @@ private:
> > void bufferReady(FrameBuffer *buffer);
> > void paramReady(FrameBuffer *buffer);
> > void statReady(FrameBuffer *buffer);
> > + void frameStart(uint32_t sequence);
> >
> > int allocateBuffers(Camera *camera);
> > int freeBuffers(Camera *camera);
> > @@ -348,53 +347,6 @@ RkISP1FrameInfo *RkISP1Frames::find(Request *request)
> > return nullptr;
> > }
> >
> > -class RkISP1ActionQueueBuffers : public FrameAction
> > -{
> > -public:
> > - RkISP1ActionQueueBuffers(unsigned int frame, RkISP1CameraData *data,
> > - PipelineHandlerRkISP1 *pipe)
> > - : FrameAction(frame, QueueBuffers), data_(data), pipe_(pipe)
> > - {
> > - }
> > -
> > -protected:
> > - void run() override
> > - {
> > - RkISP1FrameInfo *info = data_->frameInfo_.find(frame());
> > - if (!info)
> > - LOG(RkISP1, Fatal) << "Frame not known";
> > -
> > - /*
> > - * \todo: If parameters are not filled a better method to handle
> > - * the situation than queuing a buffer with unknown content
> > - * should be used.
> > - *
> > - * It seems excessive to keep an internal zeroed scratch
> > - * parameters buffer around as this should not happen unless the
> > - * devices is under too much load. Perhaps failing the request
> > - * and returning it to the application with an error code is
> > - * better than queue it to hardware?
> > - */
> > - if (!info->paramFilled)
> > - LOG(RkISP1, Error)
> > - << "Parameters not ready on time for frame "
> > - << frame();
> > -
> > - pipe_->param_->queueBuffer(info->paramBuffer);
> > - pipe_->stat_->queueBuffer(info->statBuffer);
> > -
> > - if (info->mainPathBuffer)
> > - pipe_->mainPath_.queueBuffer(info->mainPathBuffer);
> > -
> > - if (info->selfPathBuffer)
> > - pipe_->selfPath_.queueBuffer(info->selfPathBuffer);
> > - }
> > -
> > -private:
> > - RkISP1CameraData *data_;
> > - PipelineHandlerRkISP1 *pipe_;
> > -};
> > -
> > int RkISP1CameraData::loadIPA()
> > {
> > ipa_ = IPAManager::createIPA(pipe_, 1, 1);
> > @@ -958,9 +910,14 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request)
> > op.controls = { request->controls() };
> > data->ipa_->processEvent(op);
> >
> > - data->timeline_.scheduleAction(std::make_unique<RkISP1ActionQueueBuffers>(data->frame_,
> > - data,
> > - this));
> > + param_->queueBuffer(info->paramBuffer);
> > + stat_->queueBuffer(info->statBuffer);
> > +
> > + if (info->mainPathBuffer)
> > + mainPath_.queueBuffer(info->mainPathBuffer);
> > +
> > + if (info->selfPathBuffer)
> > + selfPath_.queueBuffer(info->selfPathBuffer);
You're queuing the buffers to the ISP, including the ISP parameters,
before the IPA gets a change to even take into account the parameters
for this request to compute the corresponding ISP parameters. Do we
really want to do that ?
> >
> > data->frame_++;
> >
> > @@ -1098,6 +1055,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator)
> > mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady);
> > selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady);
> > stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady);
> > + isp_->frameStart.connect(this, &PipelineHandlerRkISP1::frameStart);
> > param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady);
> >
> > /*
> > @@ -1177,8 +1135,6 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
> > if (!info)
> > return;
> >
> > - data->timeline_.bufferReady(buffer);
> > -
> > if (data->frame_ <= buffer->metadata().sequence)
> > data->frame_ = buffer->metadata().sequence + 1;
> >
> > @@ -1188,6 +1144,20 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer)
> > data->ipa_->processEvent(op);
> > }
> >
> > +void PipelineHandlerRkISP1::frameStart(uint32_t sequence)
> > +{
> > + if (!activeCamera_)
> > + return;
> > +
> > + RkISP1CameraData *data = cameraData(activeCamera_);
> > +
> > + RkISP1FrameInfo *info = data->frameInfo_.find(sequence);
> > + if (!info || !info->paramFilled)
> > + LOG(RkISP1, Info)
> > + << "Parameters not ready on time for frame "
> > + << sequence;
> > +}
> > +
>
> This surely is my lack of understanding, but shouldn't we worry about
> this a param buffer queue time ?
>
> > REGISTER_PIPELINE_HANDLER(PipelineHandlerRkISP1)
> >
> > } /* namespace libcamera */
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list