<div dir="ltr">Hi folks,<div><br></div><div>Could I request a round of review? Thanks!</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 18, 2023 at 4:52 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">As ipu3 ISP requires two frames in the pipeline to generate non-delayed<br>
output, this CL fixes the problem of the first frame (preview and<br>
capture) being black by queueing the first buffer twice.<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 | 50 ++++++++++++++++++++++++----<br>
 1 file changed, 43 insertions(+), 7 deletions(-)<br>
<br>
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
index a81c817a..fa4a8a10 100644<br>
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp<br>
@@ -86,11 +86,15 @@ public:<br>
<br>
        ControlInfoMap ipaControls_;<br>
<br>
+       bool firstRequest_ = true;<br>
+<br>
 private:<br>
        void metadataReady(unsigned int id, const ControlList &metadata);<br>
        void paramsBufferReady(unsigned int id);<br>
        void setSensorControls(unsigned int id, const ControlList &sensorControls,<br>
                               const ControlList &lensControls);<br>
+<br>
+       std::map<FrameBuffer *, int> bufferReturnCounters_;<br>
 };<br>
<br>
 class IPU3CameraConfiguration : public CameraConfiguration<br>
@@ -721,6 +725,8 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis<br>
        ImgUDevice *imgu = data->imgu_;<br>
        int ret;<br>
<br>
+       data->firstRequest_ = true;<br>
+<br>
        /* Disable test pattern mode on the sensor, if any. */<br>
        ret = cio2->sensor()->setTestPatternMode(<br>
                controls::draft::TestPatternModeEnum::TestPatternModeOff);<br>
@@ -1224,22 +1230,37 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)<br>
        if (!info)<br>
                return;<br>
<br>
+       const int yuvCount = firstRequest_ ? 2 : 1;<br>
+       firstRequest_ = false;<br>
        /* Queue all buffers from the request aimed for the ImgU. */<br>
        for (auto it : info->request->buffers()) {<br>
                const Stream *stream = it.first;<br>
                FrameBuffer *outbuffer = it.second;<br>
<br>
-               if (stream == &outStream_)<br>
-                       imgu_->output_->queueBuffer(outbuffer);<br>
-               else if (stream == &vfStream_)<br>
-                       imgu_->viewfinder_->queueBuffer(outbuffer);<br>
+               if (stream == &outStream_) {<br>
+                       for (int i = 0; i < yuvCount; ++i) {<br>
+                               bufferReturnCounters_[outbuffer] += 1;<br>
+                               imgu_->output_->queueBuffer(outbuffer);<br>
+                       }<br>
+               } else if (stream == &vfStream_) {<br>
+                       for (int i = 0; i < yuvCount; ++i) {<br>
+                               bufferReturnCounters_[outbuffer] += 1;<br>
+                               imgu_->viewfinder_->queueBuffer(outbuffer);<br>
+                       }<br>
+               }<br>
        }<br>
<br>
        info->paramBuffer->_d()->metadata().planes()[0].bytesused =<br>
                sizeof(struct ipu3_uapi_params);<br>
-       imgu_->param_->queueBuffer(info->paramBuffer);<br>
-       imgu_->stat_->queueBuffer(info->statBuffer);<br>
-       imgu_->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>
+               imgu_->param_->queueBuffer(info->paramBuffer);<br>
+               imgu_->stat_->queueBuffer(info->statBuffer);<br>
+               imgu_->input_->queueBuffer(info->rawBuffer);<br>
+       }<br>
 }<br>
<br>
 void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)<br>
@@ -1268,6 +1289,11 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)<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>
@@ -1334,6 +1360,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>
@@ -1354,6 +1385,11 @@ void IPU3CameraData::paramBufferReady(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.42.0.459.ge4e396fd5e-goog<br>
<br>
</blockquote></div>