mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-15 16:35:06 +03:00
libcamera: ipu3: Add helper for parameter and statistic buffers
Add a helper class to aid in associating a parameter and statistic buffer with each request queued to the pipeline. The helper helps with tracking the state of the extra buffers and in completing the request once all extra processing is done. This change only adds the helper more work is needed to integrate it with the pipeline and an IPA. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
82549ae253
commit
d2bc3eb7b6
3 changed files with 199 additions and 0 deletions
136
src/libcamera/pipeline/ipu3/frames.cpp
Normal file
136
src/libcamera/pipeline/ipu3/frames.cpp
Normal file
|
@ -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 */
|
62
src/libcamera/pipeline/ipu3/frames.h
Normal file
62
src/libcamera/pipeline/ipu3/frames.h
Normal file
|
@ -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([
|
libcamera_sources += files([
|
||||||
'cio2.cpp',
|
'cio2.cpp',
|
||||||
|
'frames.cpp',
|
||||||
'imgu.cpp',
|
'imgu.cpp',
|
||||||
'ipu3.cpp',
|
'ipu3.cpp',
|
||||||
])
|
])
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue