libcamera  v0.0.0+3695-a2c715d8
Supporting cameras in Linux since 2019
v4l2_videodevice.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3  * Copyright (C) 2019, Google Inc.
4  *
5  * v4l2_videodevice.h - V4L2 Video Device
6  */
7 
8 #pragma once
9 
10 #include <array>
11 #include <atomic>
12 #include <memory>
13 #include <optional>
14 #include <ostream>
15 #include <stdint.h>
16 #include <string>
17 #include <vector>
18 
19 #include <linux/videodev2.h>
20 
21 #include <libcamera/base/class.h>
22 #include <libcamera/base/log.h>
23 #include <libcamera/base/signal.h>
24 #include <libcamera/base/timer.h>
26 #include <libcamera/base/utils.h>
27 
28 #include <libcamera/color_space.h>
29 #include <libcamera/framebuffer.h>
30 #include <libcamera/geometry.h>
31 #include <libcamera/pixel_format.h>
32 
36 
37 namespace libcamera {
38 
39 class EventNotifier;
40 class MediaDevice;
41 class MediaEntity;
42 
43 struct V4L2Capability final : v4l2_capability {
44  const char *driver() const
45  {
46  return reinterpret_cast<const char *>(v4l2_capability::driver);
47  }
48  const char *card() const
49  {
50  return reinterpret_cast<const char *>(v4l2_capability::card);
51  }
52  const char *bus_info() const
53  {
54  return reinterpret_cast<const char *>(v4l2_capability::bus_info);
55  }
56  unsigned int device_caps() const
57  {
58  return capabilities & V4L2_CAP_DEVICE_CAPS
59  ? v4l2_capability::device_caps
60  : v4l2_capability::capabilities;
61  }
62  bool isMultiplanar() const
63  {
64  return device_caps() & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
65  V4L2_CAP_VIDEO_OUTPUT_MPLANE |
66  V4L2_CAP_VIDEO_M2M_MPLANE);
67  }
68  bool isCapture() const
69  {
70  return device_caps() & (V4L2_CAP_VIDEO_CAPTURE |
71  V4L2_CAP_VIDEO_CAPTURE_MPLANE |
72  V4L2_CAP_META_CAPTURE);
73  }
74  bool isOutput() const
75  {
76  return device_caps() & (V4L2_CAP_VIDEO_OUTPUT |
77  V4L2_CAP_VIDEO_OUTPUT_MPLANE |
78  V4L2_CAP_META_OUTPUT);
79  }
80  bool isVideo() const
81  {
82  return device_caps() & (V4L2_CAP_VIDEO_CAPTURE |
83  V4L2_CAP_VIDEO_CAPTURE_MPLANE |
84  V4L2_CAP_VIDEO_OUTPUT |
85  V4L2_CAP_VIDEO_OUTPUT_MPLANE);
86  }
87  bool isM2M() const
88  {
89  return device_caps() & (V4L2_CAP_VIDEO_M2M |
90  V4L2_CAP_VIDEO_M2M_MPLANE);
91  }
92  bool isMeta() const
93  {
94  return device_caps() & (V4L2_CAP_META_CAPTURE |
95  V4L2_CAP_META_OUTPUT);
96  }
97  bool isVideoCapture() const
98  {
99  return isVideo() && isCapture();
100  }
101  bool isVideoOutput() const
102  {
103  return isVideo() && isOutput();
104  }
105  bool isMetaCapture() const
106  {
107  return isMeta() && isCapture();
108  }
109  bool isMetaOutput() const
110  {
111  return isMeta() && isOutput();
112  }
113  bool hasStreaming() const
114  {
115  return device_caps() & V4L2_CAP_STREAMING;
116  }
117  bool hasMediaController() const
118  {
119  return device_caps() & V4L2_CAP_IO_MC;
120  }
121 };
122 
124 {
125 public:
126  V4L2BufferCache(unsigned int numEntries);
127  V4L2BufferCache(const std::vector<std::unique_ptr<FrameBuffer>> &buffers);
128  ~V4L2BufferCache();
129 
130  bool isEmpty() const;
131  int get(const FrameBuffer &buffer);
132  void put(unsigned int index);
133 
134 private:
135  class Entry
136  {
137  public:
138  Entry();
139  Entry(bool free, uint64_t lastUsed, const FrameBuffer &buffer);
140 
141  bool operator==(const FrameBuffer &buffer) const;
142 
143  bool free_;
144  uint64_t lastUsed_;
145 
146  private:
147  struct Plane {
148  Plane(const FrameBuffer::Plane &plane)
149  : fd(plane.fd.get()), length(plane.length)
150  {
151  }
152 
153  int fd;
154  unsigned int length;
155  };
156 
157  std::vector<Plane> planes_;
158  };
159 
160  std::atomic<uint64_t> lastUsedCounter_;
161  std::vector<Entry> cache_;
162  /* \todo Expose the miss counter through an instrumentation API. */
163  unsigned int missCounter_;
164 };
165 
167 {
168 public:
169  struct Plane {
170  uint32_t size = 0;
171  uint32_t bpl = 0;
172  };
173 
176  std::optional<ColorSpace> colorSpace;
177 
178  std::array<Plane, 3> planes;
179  unsigned int planesCount = 0;
180 
181  const std::string toString() const;
182 };
183 
184 std::ostream &operator<<(std::ostream &out, const V4L2DeviceFormat &f);
185 
187 {
188 public:
189  using Formats = std::map<V4L2PixelFormat, std::vector<SizeRange>>;
190 
191  explicit V4L2VideoDevice(const std::string &deviceNode);
192  explicit V4L2VideoDevice(const MediaEntity *entity);
193  ~V4L2VideoDevice();
194 
195  int open();
196  int open(SharedFD handle, enum v4l2_buf_type type);
197  void close();
198 
199  const char *driverName() const { return caps_.driver(); }
200  const char *deviceName() const { return caps_.card(); }
201  const char *busName() const { return caps_.bus_info(); }
202 
203  const V4L2Capability &caps() const { return caps_; }
204 
205  int getFormat(V4L2DeviceFormat *format);
206  int tryFormat(V4L2DeviceFormat *format);
207  int setFormat(V4L2DeviceFormat *format);
208  Formats formats(uint32_t code = 0);
209 
210  int setSelection(unsigned int target, Rectangle *rect);
211 
212  int allocateBuffers(unsigned int count,
213  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
214  int exportBuffers(unsigned int count,
215  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
216  int importBuffers(unsigned int count);
217  int releaseBuffers();
218 
219  int queueBuffer(FrameBuffer *buffer);
221 
222  int streamOn();
223  int streamOff();
224 
225  void setDequeueTimeout(utils::Duration timeout);
227 
228  static std::unique_ptr<V4L2VideoDevice>
229  fromEntityName(const MediaDevice *media, const std::string &entity);
230 
231 protected:
232  std::string logPrefix() const override;
233 
234 private:
236 
237  enum class State {
238  Streaming,
239  Stopping,
240  Stopped,
241  };
242 
243  int getFormatMeta(V4L2DeviceFormat *format);
244  int trySetFormatMeta(V4L2DeviceFormat *format, bool set);
245 
246  int getFormatMultiplane(V4L2DeviceFormat *format);
247  int trySetFormatMultiplane(V4L2DeviceFormat *format, bool set);
248 
249  int getFormatSingleplane(V4L2DeviceFormat *format);
250  int trySetFormatSingleplane(V4L2DeviceFormat *format, bool set);
251 
252  std::vector<V4L2PixelFormat> enumPixelformats(uint32_t code);
253  std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
254 
255  int requestBuffers(unsigned int count, enum v4l2_memory memoryType);
256  int createBuffers(unsigned int count,
257  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
258  std::unique_ptr<FrameBuffer> createBuffer(unsigned int index);
259  UniqueFD exportDmabufFd(unsigned int index, unsigned int plane);
260 
261  void bufferAvailable();
262  FrameBuffer *dequeueBuffer();
263 
264  void watchdogExpired();
265 
266  V4L2Capability caps_;
267  V4L2DeviceFormat format_;
268  const PixelFormatInfo *formatInfo_;
269 
270  enum v4l2_buf_type bufferType_;
271  enum v4l2_memory memoryType_;
272 
273  V4L2BufferCache *cache_;
274  std::map<unsigned int, FrameBuffer *> queuedBuffers_;
275 
276  EventNotifier *fdBufferNotifier_;
277 
278  State state_;
279  std::optional<unsigned int> firstFrame_;
280 
281  Timer watchdog_;
282  utils::Duration watchdogDuration_;
283 };
284 
286 {
287 public:
288  V4L2M2MDevice(const std::string &deviceNode);
289  ~V4L2M2MDevice();
290 
291  int open();
292  void close();
293 
294  V4L2VideoDevice *output() { return output_; }
295  V4L2VideoDevice *capture() { return capture_; }
296 
297 private:
298  std::string deviceNode_;
299 
300  V4L2VideoDevice *output_;
301  V4L2VideoDevice *capture_;
302 };
303 
304 } /* namespace libcamera */
Frame buffer handling.
RAII-style wrapper for file descriptors.
Definition: shared_fd.h:16
bool isCapture() const
Identify if the video device captures data.
Definition: v4l2_videodevice.h:68
Utilities to help constructing class interfaces.
The MediaDevice represents a Media Controller device with its full graph of connected objects...
Definition: media_device.h:25
const V4L2Capability & caps() const
Retrieve the device V4L2 capabilities.
Definition: v4l2_videodevice.h:203
Base class for V4L2VideoDevice and V4L2Subdevice.
Definition: v4l2_device.h:29
V4L2 pixel format FourCC wrapper.
Definition: v4l2_pixelformat.h:21
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition: color_space.cpp:303
Class and enums to represent color spaces.
File descriptor wrapper that owns a file descriptor.
bool isMetaCapture() const
Identify if the video device captures image meta-data.
Definition: v4l2_videodevice.h:105
Per-plane memory size information.
Definition: v4l2_videodevice.h:169
Top-level libcamera namespace.
Definition: backtrace.h:17
V4L2VideoDevice * capture()
Retrieve the capture V4L2VideoDevice instance.
Definition: v4l2_videodevice.h:295
Size size
The image size in pixels.
Definition: v4l2_videodevice.h:175
bool isOutput() const
Identify if the video device outputs data.
Definition: v4l2_videodevice.h:74
unsigned int length
The plane length in bytes.
Definition: framebuffer.h:58
Frame buffer data and its associated dynamic metadata.
Definition: framebuffer.h:49
Describe a two-dimensional size.
Definition: geometry.h:52
Generic timer.
Miscellaneous utility functions.
std::optional< ColorSpace > colorSpace
The color space of the pixels.
Definition: v4l2_videodevice.h:176
const char * bus_info() const
Retrieve the location of the video device in the system.
Definition: v4l2_videodevice.h:52
bool isVideoOutput() const
Identify if the video device outputs images.
Definition: v4l2_videodevice.h:101
Signal dequeueTimeout
A Signal emitted when the dequeue watchdog timer expires.
Definition: v4l2_videodevice.h:226
V4L2VideoDevice object and API.
Definition: v4l2_videodevice.h:186
V4L2 Pixel Format.
The MediaEntity represents an entity in the media graph.
Definition: media_object.h:88
std::map< V4L2PixelFormat, std::vector< SizeRange > > Formats
A map of supported V4L2 pixel formats to frame sizes.
Definition: v4l2_videodevice.h:189
const char * driverName() const
Retrieve the name of the V4L2 device driver.
Definition: v4l2_videodevice.h:199
bool hasMediaController() const
Determine if the video device uses Media Controller to configure I/O.
Definition: v4l2_videodevice.h:117
#define LIBCAMERA_DISABLE_COPY(klass)
Disable copy construction and assignment of the klass.
Signal & slot implementation.
Information about pixel formats.
Definition: formats.h:21
struct v4l2_capability object wrapper and helpers
Definition: v4l2_videodevice.h:43
Describe a rectangle&#39;s position and dimensions.
Definition: geometry.h:242
V4L2VideoDevice * output()
Retrieve the output V4L2VideoDevice instance.
Definition: v4l2_videodevice.h:294
Single-shot timer interface.
Definition: timer.h:22
bool isM2M() const
Identify if the device is a Memory-to-Memory device.
Definition: v4l2_videodevice.h:87
The V4L2 video device image format and sizes.
Definition: v4l2_videodevice.h:166
unique_ptr-like wrapper for a file descriptor
Definition: unique_fd.h:17
Common base for V4L2 devices and subdevices.
bool isVideoCapture() const
Identify if the video device captures images.
Definition: v4l2_videodevice.h:97
std::array< Plane, 3 > planes
The per-plane memory size information.
Definition: v4l2_videodevice.h:178
SharedFD fd
The dmabuf file descriptor.
Definition: framebuffer.h:56
bool isMeta() const
Identify if the video device captures or outputs image meta-data.
Definition: v4l2_videodevice.h:92
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition: geometry.cpp:91
bool isMultiplanar() const
Identify if the video device implements the V4L2 multiplanar APIs.
Definition: v4l2_videodevice.h:62
Helper class from std::chrono::duration that represents a time duration in nanoseconds with double pr...
Definition: utils.h:323
int get() const
Retrieve the numerical file descriptor.
Definition: shared_fd.h:30
Generic signal and slot communication mechanism.
Definition: object.h:20
A memory region to store a single plane of a frame.
Definition: framebuffer.h:54
bool isVideo() const
Identify if the video device captures or outputs images.
Definition: v4l2_videodevice.h:80
Notify of activity on a file descriptor.
Definition: event_notifier.h:19
Signal< FrameBuffer * > bufferReady
A Signal emitted when a framebuffer completes.
Definition: v4l2_videodevice.h:220
bool hasStreaming() const
Determine if the video device can perform Streaming I/O.
Definition: v4l2_videodevice.h:113
const char * deviceName() const
Retrieve the name of the V4L2 video device.
Definition: v4l2_videodevice.h:200
Data structures related to geometric objects.
Types and helper functions to handle libcamera image formats.
V4L2PixelFormat fourcc
The fourcc code describing the pixel encoding scheme.
Definition: v4l2_videodevice.h:174
Logging infrastructure.
unsigned int device_caps() const
Retrieve the capabilities of the video device.
Definition: v4l2_videodevice.h:56
const char * card() const
Retrieve the video device card name.
Definition: v4l2_videodevice.h:48
Hot cache of associations between V4L2 buffer indexes and FrameBuffer.
Definition: v4l2_videodevice.h:123
const char * driver() const
Retrieve the driver module name.
Definition: v4l2_videodevice.h:44
Memory-to-Memory video device.
Definition: v4l2_videodevice.h:285
libcamera pixel format
const char * busName() const
Retrieve the location of the device in the system.
Definition: v4l2_videodevice.h:201
bool isMetaOutput() const
Identify if the video device outputs image meta-data.
Definition: v4l2_videodevice.h:109