libcamera  v0.3.1+12-19bbca3c
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  * 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 
15 namespace libcamera {
16 
17 LOG_DECLARE_CATEGORY(FCQueue)
18 
19 namespace ipa {
20 
21 template<typename FrameContext>
22 class FCQueue;
23 
24 struct FrameContext {
25 private:
26  template<typename T> friend class FCQueue;
27  uint32_t frame;
28 };
29 
30 template<typename FrameContext>
31 class FCQueue
32 {
33 public:
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 
106 private:
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 */
#define LOG(category, severity)
Log a message.
Top-level libcamera namespace.
Definition: backtrace.h:17
void clear()
Clear the contexts queue.
Definition: fc_queue.h:39
A support class for managing FrameContext instances in IPA modules.
Definition: fc_queue.h:22
FCQueue(unsigned int size)
Construct a frame contexts queue of a specified size.
Definition: fc_queue.h:34
FrameContext & alloc(const uint32_t frame)
Allocate and return a FrameContext for the frame.
Definition: fc_queue.h:45
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Context for a frame.
Definition: fc_queue.h:24
Logging infrastructure.