libcamera v0.1.0+127-8e215127-dirty (2023-12-02T01:06:12+00:00)
Supporting cameras in Linux since 2019
fc_queue.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2022, Google Inc.
4 *
5 * fc_queue.h - IPA Frame context queue
6 */
7
8#pragma once
9
10#include <stdint.h>
11#include <vector>
12
13#include <libcamera/base/log.h>
14
15namespace libcamera {
16
18
19namespace ipa {
20
21template<typename FrameContext>
22class FCQueue;
23
25private:
26 template<typename T> friend class FCQueue;
27 uint32_t frame;
28};
29
30template<typename FrameContext>
32{
33public:
34 FCQueue(unsigned int size)
35 : contexts_(size)
36 {
37 }
38
39 void clear()
40 {
41 for (FrameContext &ctx : contexts_)
42 ctx.frame = 0;
43 }
44
45 FrameContext &alloc(const uint32_t frame)
46 {
47 FrameContext &frameContext = contexts_[frame % contexts_.size()];
48
49 /*
50 * Do not re-initialise if a get() call has already fetched this
51 * frame context to preseve the context.
52 *
53 * \todo If the the sequence number of the context to initialise
54 * is smaller than the sequence number of the queue slot to use,
55 * it means that we had a serious request underrun and more
56 * frames than the queue size has been produced since the last
57 * time the application has queued a request. Does this deserve
58 * an error condition ?
59 */
60 if (frame != 0 && frame <= frameContext.frame)
61 LOG(FCQueue, Warning)
62 << "Frame " << frame << " already initialised";
63 else
64 init(frameContext, frame);
65
66 return frameContext;
67 }
68
69 FrameContext &get(uint32_t frame)
70 {
71 FrameContext &frameContext = contexts_[frame % contexts_.size()];
72
73 /*
74 * If the IPA algorithms try to access a frame context slot which
75 * has been already overwritten by a newer context, it means the
76 * frame context queue has overflowed and the desired context
77 * has been forever lost. The pipeline handler shall avoid
78 * queueing more requests to the IPA than the frame context
79 * queue size.
80 */
81 if (frame < frameContext.frame)
82 LOG(FCQueue, Fatal) << "Frame context for " << frame
83 << " has been overwritten by "
84 << frameContext.frame;
85
86 if (frame == frameContext.frame)
87 return frameContext;
88
89 /*
90 * The frame context has been retrieved before it was
91 * initialised through the initialise() call. This indicates an
92 * algorithm attempted to access a Frame context before it was
93 * queued to the IPA. Controls applied for this request may be
94 * left unhandled.
95 *
96 * \todo Set an error flag for per-frame control errors.
97 */
98 LOG(FCQueue, Warning)
99 << "Obtained an uninitialised FrameContext for " << frame;
100
101 init(frameContext, frame);
102
103 return frameContext;
104 }
105
106private:
107 void init(FrameContext &frameContext, const uint32_t frame)
108 {
109 frameContext = {};
110 frameContext.frame = frame;
111 }
112
113 std::vector<FrameContext> contexts_;
114};
115
116} /* namespace ipa */
117
118} /* namespace libcamera */
A support class for managing FrameContext instances in IPA modules.
Definition: fc_queue.h:32
FCQueue(unsigned int size)
Construct a frame contexts queue of a specified size.
Definition: fc_queue.h:34
FrameContext & get(uint32_t frame)
Obtain the FrameContext for the frame.
Definition: fc_queue.h:69
FrameContext & alloc(const uint32_t frame)
Allocate and return a FrameContext for the frame.
Definition: fc_queue.h:45
void clear()
Clear the contexts queue.
Definition: fc_queue.h:39
Logging infrastructure.
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
#define LOG(category, severity)
Log a message.
Top-level libcamera namespace.
Definition: backtrace.h:17
Context for a frame.
Definition: fc_queue.h:24