<div dir="ltr">Sorry I forgot to include the comment that explains how |stillCount| is calculated and what it does.<br>To avoid the spam, I'll put the comment here and upload it with PATCH v5:<br><span id="gmail-docs-internal-guid-8f29e168-7fff-29fc-698c-221c14f31951"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br></span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">/*</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * If the StillCapture request is the first request or isn't</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * consequential, we need to requeue the same buffers to ImgU1 to</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * mitigate the frame delay (i.e. |stillCount| being 2). Otherwise,</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * |stillCount| would be 1, which means the buffers are queued once as</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> * usual.</span></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> */</span></p></span><br class="gmail-Apple-interchange-newline"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 2, 2022 at 6:30 PM Harvey Yang <<a href="mailto:chenghaoyang@chromium.org">chenghaoyang@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Like the shipped ipu3 HAL [1], handle the frame delay with one extra input,<br>
needed for the first frame and StillCapture's non-sequential frame<br>
requests.<br>
<br>
[1]:<br>
<a href="https://source.corp.google.com/chromeos_public/src/platform/camera/hal/intel/ipu3/psl/ipu3/ImguUnit.cpp;l=773" rel="noreferrer" target="_blank">https://source.corp.google.com/chromeos_public/src/platform/camera/hal/intel/ipu3/psl/ipu3/ImguUnit.cpp;l=773</a><br>
<br>
Signed-off-by: Harvey Yang <<a href="mailto:chenghaoyang@chromium.org" target="_blank">chenghaoyang@chromium.org</a>><br>
---<br>
 src/libcamera/pipeline/ipu3/ipu3.cpp | 73 +++++++++++++++++++++++-----<br>
 1 file changed, 62 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
index f8101c6c..36ca47c2 100644<br>
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
@@ -90,6 +90,9 @@ public:<br>
<br>
        ControlInfoMap ipaControls_;<br>
<br>
+       bool firstRequest_ = true;<br>
+       int lastCaptureRequestSeq_ = -1;<br>
+<br>
 private:<br>
        void metadataReady(unsigned int id, const ControlList &metadata);<br>
        void paramsBufferReady(unsigned int id);<br>
@@ -884,6 +887,9 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis<br>
        CIO2Device *cio2 = &data->cio2_;<br>
        int ret;<br>
<br>
+       data->firstRequest_ = true;<br>
+       data->lastCaptureRequestSeq_ = -1;<br>
+<br>
        imgu0_.input_->bufferReady.connect(data,<br>
                                           &IPU3CameraData::tryReturnBuffer);<br>
        imgu0_.output_->bufferReady.connect(data,<br>
@@ -1422,6 +1428,11 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)<br>
        if (!info)<br>
                return;<br>
<br>
+       int yuvCount = firstRequest_ ? 2 : 1;<br>
+       int stillCount = firstRequest_ || (lastCaptureRequestSeq_ + 1) != static_cast<int>(info->request->sequence()) ? 2 : 1;<br>
+<br>
+       firstRequest_ = false;<br>
+<br>
        bool hasYuv = false;<br>
        bool hasCapture = false;<br>
        /* Queue all buffers from the request aimed for the ImgU. */<br>
@@ -1431,33 +1442,53 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)<br>
<br>
                if (stream == &outStream_) {<br>
                        hasYuv = true;<br>
-                       imgu0_->output_->queueBuffer(outbuffer);<br>
+<br>
+                       for (int i = 0; i < yuvCount; ++i) {<br>
+                               bufferReturnCounters[outbuffer] += 1;<br>
+                               imgu0_->output_->queueBuffer(outbuffer);<br>
+                       }<br>
                } else if (stream == &vfStream_) {<br>
                        hasYuv = true;<br>
-                       imgu0_->viewfinder_->queueBuffer(outbuffer);<br>
+<br>
+                       for (int i = 0; i < yuvCount; ++i) {<br>
+                               bufferReturnCounters[outbuffer] += 1;<br>
+                               imgu0_->viewfinder_->queueBuffer(outbuffer);<br>
+                       }<br>
                } else if (stream == &outCaptureStream_) {<br>
                        hasCapture = true;<br>
<br>
-                       imgu1_->output_->queueBuffer(outbuffer);<br>
+                       for (int i = 0; i < stillCount; ++i) {<br>
+                               bufferReturnCounters[outbuffer] += 1;<br>
+                               imgu1_->output_->queueBuffer(outbuffer);<br>
+                       }<br>
                }<br>
        }<br>
<br>
        if (hasYuv) {<br>
-               bufferReturnCounters[info->rawBuffer] += 1;<br>
-<br>
-               imgu0_->param_->queueBuffer(info->paramBuffer);<br>
-               imgu0_->stat_->queueBuffer(info->statBuffer);<br>
-               imgu0_->input_->queueBuffer(info->rawBuffer);<br>
+               for (int i = 0; i < yuvCount; ++i) {<br>
+                       bufferReturnCounters[info->paramBuffer] += 1;<br>
+                       bufferReturnCounters[info->statBuffer] += 1;<br>
+                       bufferReturnCounters[info->rawBuffer] += 1;<br>
+<br>
+                       imgu0_->param_->queueBuffer(info->paramBuffer);<br>
+                       imgu0_->stat_->queueBuffer(info->statBuffer);<br>
+                       imgu0_->input_->queueBuffer(info->rawBuffer);<br>
+               }<br>
        } else {<br>
                info->paramDequeued = true;<br>
                info->metadataProcessed = true;<br>
        }<br>
<br>
        if (hasCapture) {<br>
-               bufferReturnCounters[info->rawBuffer] += 1;<br>
+               lastCaptureRequestSeq_ = info->request->sequence();<br>
<br>
-               imgu1_->param_->queueBuffer(info->captureParamBuffer);<br>
-               imgu1_->input_->queueBuffer(info->rawBuffer);<br>
+               for (int i = 0; i < stillCount; ++i) {<br>
+                       bufferReturnCounters[info->captureParamBuffer] += 1;<br>
+                       bufferReturnCounters[info->rawBuffer] += 1;<br>
+<br>
+                       imgu1_->param_->queueBuffer(info->captureParamBuffer);<br>
+                       imgu1_->input_->queueBuffer(info->rawBuffer);<br>
+               }<br>
        } else {<br>
                info->captureParamDequeued = true;<br>
        }<br>
@@ -1498,6 +1529,11 @@ void IPU3CameraData::tryReturnBuffer(FrameBuffer *buffer)<br>
  */<br>
 void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)<br>
 {<br>
+       if (--bufferReturnCounters[buffer] > 0)<br>
+               return;<br>
+<br>
+       bufferReturnCounters.erase(buffer);<br>
+<br>
        IPU3Frames::Info *info = frameInfos_.find(buffer);<br>
        if (!info)<br>
                return;<br>
@@ -1564,6 +1600,11 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)<br>
<br>
 void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)<br>
 {<br>
+       if (--bufferReturnCounters[buffer] > 0)<br>
+               return;<br>
+<br>
+       bufferReturnCounters.erase(buffer);<br>
+<br>
        IPU3Frames::Info *info = frameInfos_.find(buffer);<br>
        if (!info)<br>
                return;<br>
@@ -1584,6 +1625,11 @@ void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)<br>
<br>
 void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)<br>
 {<br>
+       if (--bufferReturnCounters[buffer] > 0)<br>
+               return;<br>
+<br>
+       bufferReturnCounters.erase(buffer);<br>
+<br>
        IPU3Frames::Info *info = frameInfos_.find(buffer);<br>
        if (!info)<br>
                return;<br>
@@ -1604,6 +1650,11 @@ void IPU3CameraData::captureParamBufferReady(FrameBuffer *buffer)<br>
<br>
 void IPU3CameraData::statBufferReady(FrameBuffer *buffer)<br>
 {<br>
+       if (--bufferReturnCounters[buffer] > 0)<br>
+               return;<br>
+<br>
+       bufferReturnCounters.erase(buffer);<br>
+<br>
        IPU3Frames::Info *info = frameInfos_.find(buffer);<br>
        if (!info)<br>
                return;<br>
-- <br>
2.37.1.455.g008518b4e5-goog<br>
<br>
</blockquote></div>