[libcamera-devel] [PATCH v1 1/1] libcamera: Fix ipu3's issue of first black frame

Harvey Yang chenghaoyang at chromium.org
Mon Sep 18 10:49:21 CEST 2023


As ipu3 ISP requires two frames in the pipeline to generate non-delayed
output, this CL fixes the problem of the first frame (preview and
capture) being black by queueing the first buffer twice.

Signed-off-by: Harvey Yang <chenghaoyang at chromium.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp | 50 ++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index a81c817a..fa4a8a10 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -86,11 +86,15 @@ public:
 
 	ControlInfoMap ipaControls_;
 
+	bool firstRequest_ = true;
+
 private:
 	void metadataReady(unsigned int id, const ControlList &metadata);
 	void paramsBufferReady(unsigned int id);
 	void setSensorControls(unsigned int id, const ControlList &sensorControls,
 			       const ControlList &lensControls);
+
+	std::map<FrameBuffer *, int> bufferReturnCounters_;
 };
 
 class IPU3CameraConfiguration : public CameraConfiguration
@@ -721,6 +725,8 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis
 	ImgUDevice *imgu = data->imgu_;
 	int ret;
 
+	data->firstRequest_ = true;
+
 	/* Disable test pattern mode on the sensor, if any. */
 	ret = cio2->sensor()->setTestPatternMode(
 		controls::draft::TestPatternModeEnum::TestPatternModeOff);
@@ -1224,22 +1230,37 @@ void IPU3CameraData::paramsBufferReady(unsigned int id)
 	if (!info)
 		return;
 
+	const int yuvCount = firstRequest_ ? 2 : 1;
+	firstRequest_ = false;
 	/* 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;
 
-		if (stream == &outStream_)
-			imgu_->output_->queueBuffer(outbuffer);
-		else if (stream == &vfStream_)
-			imgu_->viewfinder_->queueBuffer(outbuffer);
+		if (stream == &outStream_) {
+			for (int i = 0; i < yuvCount; ++i) {
+				bufferReturnCounters_[outbuffer] += 1;
+				imgu_->output_->queueBuffer(outbuffer);
+			}
+		} else if (stream == &vfStream_) {
+			for (int i = 0; i < yuvCount; ++i) {
+				bufferReturnCounters_[outbuffer] += 1;
+				imgu_->viewfinder_->queueBuffer(outbuffer);
+			}
+		}
 	}
 
 	info->paramBuffer->_d()->metadata().planes()[0].bytesused =
 		sizeof(struct ipu3_uapi_params);
-	imgu_->param_->queueBuffer(info->paramBuffer);
-	imgu_->stat_->queueBuffer(info->statBuffer);
-	imgu_->input_->queueBuffer(info->rawBuffer);
+	for (int i = 0; i < yuvCount; ++i) {
+		bufferReturnCounters_[info->paramBuffer] += 1;
+		bufferReturnCounters_[info->statBuffer] += 1;
+		bufferReturnCounters_[info->rawBuffer] += 1;
+
+		imgu_->param_->queueBuffer(info->paramBuffer);
+		imgu_->stat_->queueBuffer(info->statBuffer);
+		imgu_->input_->queueBuffer(info->rawBuffer);
+	}
 }
 
 void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)
@@ -1268,6 +1289,11 @@ void IPU3CameraData::metadataReady(unsigned int id, const ControlList &metadata)
  */
 void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)
 {
+	if (--bufferReturnCounters_[buffer] > 0)
+		return;
+
+	bufferReturnCounters_.erase(buffer);
+
 	IPU3Frames::Info *info = frameInfos_.find(buffer);
 	if (!info)
 		return;
@@ -1334,6 +1360,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;
@@ -1354,6 +1385,11 @@ void IPU3CameraData::paramBufferReady(FrameBuffer *buffer)
 
 void IPU3CameraData::statBufferReady(FrameBuffer *buffer)
 {
+	if (--bufferReturnCounters_[buffer] > 0)
+		return;
+
+	bufferReturnCounters_.erase(buffer);
+
 	IPU3Frames::Info *info = frameInfos_.find(buffer);
 	if (!info)
 		return;
-- 
2.42.0.459.ge4e396fd5e-goog



More information about the libcamera-devel mailing list