@@ -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_)