[libcamera-devel] [PATCH v3 9/9] ipu3: Fixes frame delay
Cheng-Hao Yang
chenghaoyang at chromium.org
Tue Aug 2 12:31:26 CEST 2022
Hi Umang,
On Wed, Jul 27, 2022 at 9:25 PM Umang Jain <umang.jain at ideasonboard.com>
wrote:
> Hello,
>
> On 6/29/22 16:00, Harvey Yang via libcamera-devel wrote:
> > Like the shipped ipu3 HAL, handle the frame delay with one extra input,
>
>
> Can you point to the shipped ipu3 HAL frame delay handling code here for
> reference?
>
>
Sure. Added.
> > needed for the first frame and StillCapture's non-sequential frame
> > requests.
> >
> > Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
> > ---
> > src/libcamera/pipeline/ipu3/ipu3.cpp | 73 +++++++++++++++++++++++-----
> > 1 file changed, 62 insertions(+), 11 deletions(-)
> >
> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp
> b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > index e26c2736..8689cf8b 100644
> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > @@ -90,6 +90,9 @@ public:
> >
> > ControlInfoMap ipaControls_;
> >
> > + bool firstRequest_ = true;
> > + int lastRequestSequence_ = -1;
>
>
> this is only used under hasCapture so maybe lastCaptureRequestSeq_ is
> more appropriate?
>
>
Right, thanks!
> > +
> > private:
> > void metadataReady(unsigned int id, const ControlList &metadata);
> > void paramsBufferReady(unsigned int id);
> > @@ -565,6 +568,9 @@ int PipelineHandlerIPU3::configure(Camera *camera,
> CameraConfiguration *c)
> > CIO2Device *cio2 = &data->cio2_;
> > V4L2DeviceFormat outputFormat;
> >
> > + data->firstRequest_ = true;
> > + data->lastRequestSequence_ = -1;
> > +
>
>
> Does this needs to be reset on every start()/stop() cycles?
>
>
Ah, right. Resetting them when start() should be enough.
> > ImgUDevice::PipeConfig imguConfig1 = config->imguConfig1();
> > useImgu1_ = !imguConfig1.isNull();
> >
> > @@ -1427,6 +1433,11 @@ void IPU3CameraData::paramsBufferReady(unsigned
> int id)
> > if (!info)
> > return;
> >
> > + int yuvCount = firstRequest_ ? 2 : 1;
> > + int stillCount = firstRequest_ || (lastRequestSequence_ + 1) !=
> static_cast<int>(info->request->sequence()) ? 2 : 1;
> > +
>
>
> This is getting a bit non-trivial to follow. Can you probably include a
> brief comment here to explain some rationale?
>
> As per my understanding, if the lastRequestSequence_ was a StillCapture,
> stillCount will be 1 for current request capture, and it will 2 for all
> other cases?
>
> We need stillCount to be 2 (usually) because .... ?
>
>
If it's the first request, or the StillCapture request doesn't come
sequentially, we'll need to queue the buffers twice (i.e. |stillCount|
being 2) to mitigate the frame delay.
Added a comment in the code. Please check :)
> > + firstRequest_ = false;
> > +
> > bool hasYuv = false;
> > bool hasCapture = false;
> > /* Queue all buffers from the request aimed for the ImgU. */
> > @@ -1436,33 +1447,53 @@ void IPU3CameraData::paramsBufferReady(unsigned
> int id)
> >
> > if (stream == &outStream_) {
> > hasYuv = true;
> > - imgu0_->output_->queueBuffer(outbuffer);
> > +
> > + for (int i = 0; i < yuvCount; ++i) {
> > + bufferReturnCounters[outbuffer] += 1;
> > + imgu0_->output_->queueBuffer(outbuffer);
>
>
> Have you checked / discussed what happens if you re-queue the same
> buffer on videodevice twice (before even dequeuing it)? I am not sure,
> because the current documentation doesn't specify this case I think.
>
> I've asked around.
>
>
Yeah, I've tried it on soraka and discussed it with Han-lin & Laurent &
Tomasz. It's also the way that the shipped HAL is handling the frame delay.
Please check :)
> > + }
> > } else if (stream == &vfStream_) {
> > hasYuv = true;
> > - imgu0_->viewfinder_->queueBuffer(outbuffer);
> > +
> > + for (int i = 0; i < yuvCount; ++i) {
> > + bufferReturnCounters[outbuffer] += 1;
> > +
> imgu0_->viewfinder_->queueBuffer(outbuffer);
> > + }
> > } else if (stream == &outCaptureStream_) {
> > hasCapture = true;
> >
> > - imgu1_->output_->queueBuffer(outbuffer);
> > + for (int i = 0; i < stillCount; ++i) {
> > + bufferReturnCounters[outbuffer] += 1;
> > + imgu1_->output_->queueBuffer(outbuffer);
> > + }
> > }
> > }
> >
> > if (hasYuv) {
> > - bufferReturnCounters[info->rawBuffer] += 1;
> > -
> > - imgu0_->param_->queueBuffer(info->paramBuffer);
> > - imgu0_->stat_->queueBuffer(info->statBuffer);
> > - imgu0_->input_->queueBuffer(info->rawBuffer);
> > + for (int i = 0; i < yuvCount; ++i) {
> > + bufferReturnCounters[info->paramBuffer] += 1;
> > + bufferReturnCounters[info->statBuffer] += 1;
> > + bufferReturnCounters[info->rawBuffer] += 1;
> > +
> > + imgu0_->param_->queueBuffer(info->paramBuffer);
> > + imgu0_->stat_->queueBuffer(info->statBuffer);
> > + imgu0_->input_->queueBuffer(info->rawBuffer);
> > + }
> > } else {
> > info->paramDequeued = true;
> > info->metadataProcessed = true;
> > }
> >
> > if (hasCapture) {
> > - bufferReturnCounters[info->rawBuffer] += 1;
> > + lastRequestSequence_ = info->request->sequence();
> >
> > - imgu1_->param_->queueBuffer(info->captureParamBuffer);
> > - imgu1_->input_->queueBuffer(info->rawBuffer);
> > + for (int i = 0; i < stillCount; ++i) {
> > + bufferReturnCounters[info->captureParamBuffer] +=
> 1;
> > + bufferReturnCounters[info->rawBuffer] += 1;
> > +
> > +
> imgu1_->param_->queueBuffer(info->captureParamBuffer);
> > + imgu1_->input_->queueBuffer(info->rawBuffer);
> > + }
> > } else {
> > info->captureParamDequeued = true;
> > }
> > @@ -1503,6 +1534,11 @@ void IPU3CameraData::tryReturnBuffer(FrameBuffer
> *buffer)
> > */
> > void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)
> > {
> > + if (--bufferReturnCounters[buffer] > 0)
> > + return;
> > +
> > + bufferReturnCounters.erase(buffer);
> > +
> > IPU3Frames::Info *info = frameInfos_.find(buffer);
> > if (!info)
> > return;
> > @@ -1569,6 +1605,11 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer
> *buffer)
> >
> > void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)
> > {
> > + if (--bufferReturnCounters[buffer] > 0)
> > + return;
> > +
> > + bufferReturnCounters.erase(buffer);
> > +
> > IPU3Frames::Info *info = frameInfos_.find(buffer);
> > if (!info)
> > return;
> > @@ -1589,6 +1630,11 @@ void IPU3CameraData::paramBufferReady(FrameBuffer
> *buffer)
> >
> > void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)
> > {
> > + if (--bufferReturnCounters[buffer] > 0)
> > + return;
> > +
> > + bufferReturnCounters.erase(buffer);
> > +
> > IPU3Frames::Info *info = frameInfos_.find(buffer);
> > if (!info)
> > return;
> > @@ -1609,6 +1655,11 @@ void
> IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)
> >
> > void IPU3CameraData::statBufferReady(FrameBuffer *buffer)
> > {
> > + if (--bufferReturnCounters[buffer] > 0)
> > + return;
> > +
> > + bufferReturnCounters.erase(buffer);
> > +
> > IPU3Frames::Info *info = frameInfos_.find(buffer);
> > if (!info)
> > return;
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20220802/e811148d/attachment.htm>
More information about the libcamera-devel
mailing list