[libcamera-devel] [RFC 09/12] libcamera: v4l2_videodevice: Add a buffer cache class
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Nov 18 21:05:27 CET 2019
Hi Niklas,
Thank you for the patch.
On Mon, Oct 28, 2019 at 03:25:22AM +0100, Niklas Söderlund wrote:
> In preparation for the new buffer handling add a class which will deal
> with keeping the cache between dmafds and V4L2 video device buffer
> indexes. Previously this responsibility have been split between multiple
s/have been/was/
> classes.
>
> This initial implement ensures that no hot association is lost while its
> eviction strategy could be improved in the future.
>
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> src/libcamera/include/v4l2_videodevice.h | 19 ++++++++++
> src/libcamera/v4l2_videodevice.cpp | 47 ++++++++++++++++++++++++
> 2 files changed, 66 insertions(+)
>
> diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
> index 4b8cf9394eb9516f..5b178339d0ce7e2c 100644
> --- a/src/libcamera/include/v4l2_videodevice.h
> +++ b/src/libcamera/include/v4l2_videodevice.h
> @@ -104,6 +104,25 @@ struct V4L2Capability final : v4l2_capability {
> }
> };
>
> +class V4L2BufferCache
> +{
> +public:
> + V4L2BufferCache(unsigned int size);
> +
> + void populate(unsigned int index, const std::array<int, 3> &fds);
> +
> + int pop(const std::array<int, 3> &fds);
> + void push(unsigned int index);
I understand why there's no doc at this stage, but you then need to name
methods in a self-documenting way :-) Jokes aside, I think better names
are needed here. I also fail to see why you need both populate() and
pop(), but maybe I'll figure it out in a later patch.
> +
> +private:
> + struct CacheInfo {
> + bool free;
> + std::array<int, 3> last;
> + };
> +
> + std::map<unsigned int, CacheInfo> cache_;
As indices start at zero and are consecutive, how about using an
std::vector<CacheInfo> instead ?
> +};
> +
> class V4L2DeviceFormat
> {
> public:
> diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
> index a2a9eab2bcc0d7e8..8bc2e439e4faeb68 100644
> --- a/src/libcamera/v4l2_videodevice.cpp
> +++ b/src/libcamera/v4l2_videodevice.cpp
> @@ -132,6 +132,53 @@ LOG_DECLARE_CATEGORY(V4L2)
> * \return True if the video device provides Streaming I/O IOCTLs
> */
>
> +V4L2BufferCache::V4L2BufferCache(unsigned int size)
> +{
> + for (unsigned int i = 0; i < size; i++)
> + cache_[i] = { .free = true, .last = { -1, -1, -1 } };
If you turn cache_ into a vector, this could just become
cache_.resize(size, { .free = true, .last = { -1, -1, -1 } });
> +}
> +
> +void V4L2BufferCache::populate(unsigned int index, const std::array<int, 3> &fds)
> +{
> + ASSERT(index < cache_.size());
> + cache_[index].last = fds;
> +}
> +
> +int V4L2BufferCache::pop(const std::array<int, 3> &fds)
> +{
> + int use = -1;
> +
> + for (auto &it : cache_) {
> + int index = it.first;
> + CacheInfo &info = it.second;
> +
> + if (!info.free)
> + continue;
> +
> + if (use < 0)
> + use = index;
> +
> + if (info.last == fds) {
> + use = index;
> + break;
> + }
> + }
Or maybe cache_ should be a map from fds to { index, free } to optimize
this ?
> +
> + if (use < 0)
> + return -ENOENT;
> +
> + cache_[use].free = false;
> + cache_[use].last = fds;
> +
> + return use;
> +}
> +
> +void V4L2BufferCache::push(unsigned int index)
> +{
> + ASSERT(index < cache_.size());
> + cache_[index].free = true;
> +}
> +
> /**
> * \class V4L2DeviceFormat
> * \brief The V4L2 video device image format and sizes
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list