[libcamera-devel] [PATCH v2 2/2] libcamera: ipu3: Try queuing pending requests if a buffer is available

Hirokazu Honda hiroh at chromium.org
Tue Apr 6 10:51:53 CEST 2021


IPU3CameraData stores requests that have been failed due to a
buffer shortage. The requests should be retried once enough
buffers are available. This sets the retry function as signal to
CIO2Device and IPU3Frame, and invokes it from
CIO2Device::tryReturnBuffer() and IPU3Frame::remove().

Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
---
 src/libcamera/pipeline/ipu3/cio2.cpp   | 4 +++-
 src/libcamera/pipeline/ipu3/cio2.h     | 3 +++
 src/libcamera/pipeline/ipu3/frames.cpp | 6 ++++--
 src/libcamera/pipeline/ipu3/frames.h   | 5 +++++
 src/libcamera/pipeline/ipu3/ipu3.cpp   | 4 ++++
 5 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp
index 3cd777d1..6490fd46 100644
--- a/src/libcamera/pipeline/ipu3/cio2.cpp
+++ b/src/libcamera/pipeline/ipu3/cio2.cpp
@@ -272,7 +272,7 @@ FrameBuffer *CIO2Device::queueBuffer(Request *request, FrameBuffer *rawBuffer)
 	/* If no buffer is provided in the request, use an internal one. */
 	if (!buffer) {
 		if (availableBuffers_.empty()) {
-			LOG(IPU3, Error) << "CIO2 buffer underrun";
+			LOG(IPU3, Debug) << "CIO2 buffer underrun";
 			return nullptr;
 		}
 
@@ -302,6 +302,8 @@ void CIO2Device::tryReturnBuffer(FrameBuffer *buffer)
 			break;
 		}
 	}
+
+	bufferAvailable_.emit();
 }
 
 void CIO2Device::freeBuffers()
diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h
index 5ecc4f47..8f37ee35 100644
--- a/src/libcamera/pipeline/ipu3/cio2.h
+++ b/src/libcamera/pipeline/ipu3/cio2.h
@@ -54,6 +54,7 @@ public:
 	FrameBuffer *queueBuffer(Request *request, FrameBuffer *rawBuffer);
 	void tryReturnBuffer(FrameBuffer *buffer);
 	Signal<FrameBuffer *> &bufferReady() { return output_->bufferReady; }
+	Signal<> &bufferAvailable() { return bufferAvailable_; }
 	Signal<uint32_t> &frameStart() { return csi2_->frameStart; }
 
 private:
@@ -65,6 +66,8 @@ private:
 	std::unique_ptr<V4L2Subdevice> csi2_;
 	std::unique_ptr<V4L2VideoDevice> output_;
 
+	Signal<> bufferAvailable_;
+
 	std::vector<std::unique_ptr<FrameBuffer>> buffers_;
 	std::queue<FrameBuffer *> availableBuffers_;
 };
diff --git a/src/libcamera/pipeline/ipu3/frames.cpp b/src/libcamera/pipeline/ipu3/frames.cpp
index 03e8131c..58a47f98 100644
--- a/src/libcamera/pipeline/ipu3/frames.cpp
+++ b/src/libcamera/pipeline/ipu3/frames.cpp
@@ -44,12 +44,12 @@ IPU3Frames::Info *IPU3Frames::create(Request *request)
 	unsigned int id = request->sequence();
 
 	if (availableParamBuffers_.empty()) {
-		LOG(IPU3, Error) << "Parameters buffer underrun";
+		LOG(IPU3, Debug) << "Parameters buffer underrun";
 		return nullptr;
 	}
 
 	if (availableStatBuffers_.empty()) {
-		LOG(IPU3, Error) << "Statistics buffer underrun";
+		LOG(IPU3, Debug) << "Statistics buffer underrun";
 		return nullptr;
 	}
 
@@ -86,6 +86,8 @@ void IPU3Frames::remove(IPU3Frames::Info *info)
 
 	/* Delete the extended frame information. */
 	frameInfo_.erase(info->id);
+
+	bufferAvailable_.emit();
 }
 
 bool IPU3Frames::tryComplete(IPU3Frames::Info *info)
diff --git a/src/libcamera/pipeline/ipu3/frames.h b/src/libcamera/pipeline/ipu3/frames.h
index 4acdf48e..d2e5fbb9 100644
--- a/src/libcamera/pipeline/ipu3/frames.h
+++ b/src/libcamera/pipeline/ipu3/frames.h
@@ -12,6 +12,8 @@
 #include <queue>
 #include <vector>
 
+#include <libcamera/signal.h>
+
 namespace libcamera {
 
 class FrameBuffer;
@@ -49,10 +51,13 @@ public:
 	Info *find(unsigned int id);
 	Info *find(FrameBuffer *buffer);
 
+	Signal<> &bufferAvailable() { return bufferAvailable_; }
 private:
 	std::queue<FrameBuffer *> availableParamBuffers_;
 	std::queue<FrameBuffer *> availableStatBuffers_;
 
+	Signal<> bufferAvailable_;
+
 	std::map<unsigned int, std::unique_ptr<Info>> frameInfo_;
 };
 
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index c73e4f7c..462a0d9b 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -699,6 +699,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera)
 	data->ipa_->mapBuffers(ipaBuffers_);
 
 	data->frameInfos_.init(imgu->paramBuffers_, imgu->statBuffers_);
+	data->frameInfos_.bufferAvailable().connect(
+		data, &IPU3CameraData::queuePendingRequests);
 
 	return 0;
 }
@@ -1123,6 +1125,8 @@ int PipelineHandlerIPU3::registerCameras()
 		 */
 		data->cio2_.bufferReady().connect(data.get(),
 					&IPU3CameraData::cio2BufferReady);
+		data->cio2_.bufferAvailable().connect(
+			data.get(), &IPU3CameraData::queuePendingRequests);
 		data->imgu_->input_->bufferReady.connect(&data->cio2_,
 					&CIO2Device::tryReturnBuffer);
 		data->imgu_->output_->bufferReady.connect(data.get(),
-- 
2.31.0.208.g409f899ff0-goog



More information about the libcamera-devel mailing list