summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Zamazal <mzamazal@redhat.com>2025-03-27 19:59:39 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2025-03-28 02:09:13 +0200
commit4e343af7dfbbc0477159a134159db8a16dcadd43 (patch)
treed348a3412b8e3e17823a3850400536108da11095
parent4adf0e0b1cf9733127591c24c2a6129fda481dd9 (diff)
libcamera: software_isp: Track frames and requests
Hardware pipelines track requests and other information related to particular frames. This hasn't been needed in software ISP so far. But in order to be able to track metadata corresponding to a given frame, frame-request tracking mechanism starts being useful. This patch introduces the basic tracking structure, actual metadata handling is added in the following patch. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # Lenovo X13s Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/libcamera/pipeline/simple/simple.cpp72
1 files changed, 68 insertions, 4 deletions
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 6e039bf3..004a8d53 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -181,6 +181,54 @@ LOG_DEFINE_CATEGORY(SimplePipeline)
class SimplePipelineHandler;
+struct SimpleFrameInfo {
+ SimpleFrameInfo(uint32_t f, Request *r)
+ : frame(f), request(r)
+ {
+ }
+
+ uint32_t frame;
+ Request *request;
+};
+
+class SimpleFrames
+{
+public:
+ void create(Request *request);
+ void destroy(uint32_t frame);
+ void clear();
+
+ SimpleFrameInfo *find(uint32_t frame);
+
+private:
+ std::map<uint32_t, SimpleFrameInfo> frameInfo_;
+};
+
+void SimpleFrames::create(Request *request)
+{
+ const uint32_t frame = request->sequence();
+ auto [it, inserted] = frameInfo_.try_emplace(frame, frame, request);
+ ASSERT(inserted);
+}
+
+void SimpleFrames::destroy(uint32_t frame)
+{
+ frameInfo_.erase(frame);
+}
+
+void SimpleFrames::clear()
+{
+ frameInfo_.clear();
+}
+
+SimpleFrameInfo *SimpleFrames::find(uint32_t frame)
+{
+ auto info = frameInfo_.find(frame);
+ if (info == frameInfo_.end())
+ return nullptr;
+ return &info->second;
+}
+
struct SimplePipelineInfo {
const char *driver;
/*
@@ -293,11 +341,13 @@ public:
std::unique_ptr<Converter> converter_;
std::unique_ptr<SoftwareIsp> swIsp_;
+ SimpleFrames frameInfo_;
private:
void tryPipeline(unsigned int code, const Size &size);
static std::vector<const MediaPad *> routedSourcePads(MediaPad *sink);
+ void completeRequest(Request *request);
void conversionInputDone(FrameBuffer *buffer);
void conversionOutputDone(FrameBuffer *buffer);
@@ -785,7 +835,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
/* No conversion, just complete the request. */
Request *request = buffer->request();
pipe->completeBuffer(request, buffer);
- pipe->completeRequest(request);
+ completeRequest(request);
return;
}
@@ -803,7 +853,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
const RequestOutputs &outputs = conversionQueue_.front();
for (auto &[stream, buf] : outputs.outputs)
pipe->completeBuffer(outputs.request, buf);
- pipe->completeRequest(outputs.request);
+ completeRequest(outputs.request);
conversionQueue_.pop();
return;
@@ -861,7 +911,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
/* Otherwise simply complete the request. */
pipe->completeBuffer(request, buffer);
- pipe->completeRequest(request);
+ completeRequest(request);
}
void SimpleCameraData::clearIncompleteRequests()
@@ -872,6 +922,18 @@ void SimpleCameraData::clearIncompleteRequests()
}
}
+void SimpleCameraData::completeRequest(Request *request)
+{
+ SimpleFrameInfo *info = frameInfo_.find(request->sequence());
+ if (!info) {
+ /* Something is really wrong, let's return. */
+ return;
+ }
+
+ frameInfo_.destroy(info->frame);
+ pipe()->completeRequest(request);
+}
+
void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)
{
/* Queue the input buffer back for capture. */
@@ -885,7 +947,7 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
/* Complete the buffer and the request. */
Request *request = buffer->request();
if (pipe->completeBuffer(request, buffer))
- pipe->completeRequest(request);
+ completeRequest(request);
}
void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)
@@ -1398,6 +1460,7 @@ void SimplePipelineHandler::stopDevice(Camera *camera)
video->bufferReady.disconnect(data, &SimpleCameraData::imageBufferReady);
+ data->frameInfo_.clear();
data->clearIncompleteRequests();
data->conversionBuffers_.clear();
@@ -1426,6 +1489,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request)
}
}
+ data->frameInfo_.create(request);
if (data->useConversion_) {
data->conversionQueue_.push({ request, std::move(buffers) });
if (data->swIsp_)