new file mode 100644
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * frames.cpp - Intel IPU3 Frames helper
+ */
+
+#include "frames.h"
+
+#include <libcamera/buffer.h>
+#include <libcamera/request.h>
+
+#include "libcamera/internal/pipeline_handler.h"
+#include "libcamera/internal/v4l2_videodevice.h"
+
+namespace libcamera {
+
+LOG_DECLARE_CATEGORY(IPU3)
+
+IPU3Frames::IPU3Frames()
+ : nextId_(0)
+{
+}
+
+void IPU3Frames::init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers,
+ const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers)
+{
+ for (const std::unique_ptr<FrameBuffer> &buffer : paramBuffers)
+ availableParamBuffers_.push(buffer.get());
+
+ for (const std::unique_ptr<FrameBuffer> &buffer : statBuffers)
+ availableStatBuffers_.push(buffer.get());
+
+ nextId_ = 0;
+ frameInfo_.clear();
+}
+
+void IPU3Frames::clear()
+{
+ availableParamBuffers_ = {};
+ availableStatBuffers_ = {};
+}
+
+IPU3Frames::Info *IPU3Frames::create(Request *request)
+{
+ unsigned int id = nextId_++;
+
+ if (availableParamBuffers_.empty()) {
+ LOG(IPU3, Error) << "Parameters buffer underrun";
+ return nullptr;
+ }
+ FrameBuffer *paramBuffer = availableParamBuffers_.front();
+
+ if (availableStatBuffers_.empty()) {
+ LOG(IPU3, Error) << "Statisitc buffer underrun";
+ return nullptr;
+ }
+ FrameBuffer *statBuffer = availableStatBuffers_.front();
+
+ availableParamBuffers_.pop();
+ availableStatBuffers_.pop();
+
+ /* \todo Remove the dynamic allocation of Info */
+ std::unique_ptr<Info> info = std::make_unique<Info>();
+
+ info->id = id;
+ info->request = request;
+ info->rawBuffer = nullptr;
+ info->paramBuffer = paramBuffer;
+ info->statBuffer = statBuffer;
+ info->paramDequeued = false;
+ info->metadataProcessed = false;
+
+ frameInfo_[id] = std::move(info);
+
+ return frameInfo_[id].get();
+}
+
+void IPU3Frames::remove(IPU3Frames::Info *info)
+{
+ /* Return params and stat buffer for reuse. */
+ availableParamBuffers_.push(info->paramBuffer);
+ availableStatBuffers_.push(info->statBuffer);
+
+ /* Delete the extended frame information. */
+ frameInfo_.erase(info->id);
+}
+
+bool IPU3Frames::tryComplete(IPU3Frames::Info *info)
+{
+ Request *request = info->request;
+
+ if (request->hasPendingBuffers())
+ return false;
+
+ if (!info->metadataProcessed)
+ return false;
+
+ if (!info->paramDequeued)
+ return false;
+
+ remove(info);
+
+ return true;
+}
+
+IPU3Frames::Info *IPU3Frames::find(unsigned int id)
+{
+ const auto &itInfo = frameInfo_.find(id);
+
+ if (itInfo != frameInfo_.end())
+ return itInfo->second.get();
+
+ LOG(IPU3, Error) << "Can't find tracking informaton for frame " << id;
+ return nullptr;
+}
+
+IPU3Frames::Info *IPU3Frames::find(FrameBuffer *buffer)
+{
+ for (auto const &itInfo : frameInfo_) {
+ Info *info = itInfo.second.get();
+
+ for (auto const itBuffers : info->request->buffers())
+ if (itBuffers.second == buffer)
+ return info;
+
+ if (info->rawBuffer == buffer || info->paramBuffer == buffer ||
+ info->statBuffer == buffer)
+ return info;
+ }
+
+ LOG(IPU3, Error) << "Can't find tracking informaton from buffer";
+ return nullptr;
+}
+
+} /* namespace libcamera */
new file mode 100644
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2020, Google Inc.
+ *
+ * frames.h - Intel IPU3 Frames helper
+ */
+#ifndef __LIBCAMERA_PIPELINE_IPU3_FRAMES_H__
+#define __LIBCAMERA_PIPELINE_IPU3_FRAMES_H__
+
+#include <map>
+#include <memory>
+#include <queue>
+#include <vector>
+
+namespace libcamera {
+
+class FrameBuffer;
+class IPAProxy;
+class PipelineHandler;
+class Request;
+class V4L2VideoDevice;
+struct IPABuffer;
+
+class IPU3Frames
+{
+public:
+ struct Info {
+ unsigned int id;
+ Request *request;
+
+ FrameBuffer *rawBuffer;
+ FrameBuffer *paramBuffer;
+ FrameBuffer *statBuffer;
+
+ bool paramDequeued;
+ bool metadataProcessed;
+ };
+
+ IPU3Frames();
+
+ void init(const std::vector<std::unique_ptr<FrameBuffer>> ¶mBuffers,
+ const std::vector<std::unique_ptr<FrameBuffer>> &statBuffers);
+ void clear();
+
+ Info *create(Request *request);
+ void remove(Info *info);
+ bool tryComplete(Info *info);
+
+ Info *find(unsigned int id);
+ Info *find(FrameBuffer *buffer);
+
+private:
+ std::queue<FrameBuffer *> availableParamBuffers_;
+ std::queue<FrameBuffer *> availableStatBuffers_;
+
+ unsigned int nextId_;
+ std::map<unsigned int, std::unique_ptr<Info>> frameInfo_;
+};
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_PIPELINE_IPU3_FRAMES_H__ */
@@ -2,6 +2,7 @@
libcamera_sources += files([
'cio2.cpp',
+ 'frames.cpp',
'imgu.cpp',
'ipu3.cpp',
])