libcamera  v0.0.0
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 #ifndef __LIBCAMERA_INTERNAL_V4L2_VIDEODEVICE_H__
8 #define __LIBCAMERA_INTERNAL_V4L2_VIDEODEVICE_H__
9 
10 #include <atomic>
11 #include <memory>
12 #include <stdint.h>
13 #include <string>
14 #include <vector>
15 
16 #include <linux/videodev2.h>
17 
18 #include <libcamera/buffer.h>
19 #include <libcamera/geometry.h>
20 #include <libcamera/pixel_format.h>
21 #include <libcamera/signal.h>
22 
24 #include "libcamera/internal/log.h"
27 
28 namespace libcamera {
29 
30 class EventNotifier;
31 class FileDescriptor;
32 class MediaDevice;
33 class MediaEntity;
34 
35 struct V4L2Capability final : v4l2_capability {
36  const char *driver() const
37  {
38  return reinterpret_cast<const char *>(v4l2_capability::driver);
39  }
40  const char *card() const
41  {
42  return reinterpret_cast<const char *>(v4l2_capability::card);
43  }
44  const char *bus_info() const
45  {
46  return reinterpret_cast<const char *>(v4l2_capability::bus_info);
47  }
48  unsigned int device_caps() const
49  {
50  return capabilities & V4L2_CAP_DEVICE_CAPS
51  ? v4l2_capability::device_caps
52  : v4l2_capability::capabilities;
53  }
54  bool isMultiplanar() const
55  {
56  return device_caps() & (V4L2_CAP_VIDEO_CAPTURE_MPLANE |
57  V4L2_CAP_VIDEO_OUTPUT_MPLANE |
58  V4L2_CAP_VIDEO_M2M_MPLANE);
59  }
60  bool isCapture() const
61  {
62  return device_caps() & (V4L2_CAP_VIDEO_CAPTURE |
63  V4L2_CAP_VIDEO_CAPTURE_MPLANE |
64  V4L2_CAP_META_CAPTURE);
65  }
66  bool isOutput() const
67  {
68  return device_caps() & (V4L2_CAP_VIDEO_OUTPUT |
69  V4L2_CAP_VIDEO_OUTPUT_MPLANE |
70  V4L2_CAP_META_OUTPUT);
71  }
72  bool isVideo() const
73  {
74  return device_caps() & (V4L2_CAP_VIDEO_CAPTURE |
75  V4L2_CAP_VIDEO_CAPTURE_MPLANE |
76  V4L2_CAP_VIDEO_OUTPUT |
77  V4L2_CAP_VIDEO_OUTPUT_MPLANE);
78  }
79  bool isM2M() const
80  {
81  return device_caps() & (V4L2_CAP_VIDEO_M2M |
82  V4L2_CAP_VIDEO_M2M_MPLANE);
83  }
84  bool isMeta() const
85  {
86  return device_caps() & (V4L2_CAP_META_CAPTURE |
87  V4L2_CAP_META_OUTPUT);
88  }
89  bool isVideoCapture() const
90  {
91  return isVideo() && isCapture();
92  }
93  bool isVideoOutput() const
94  {
95  return isVideo() && isOutput();
96  }
97  bool isMetaCapture() const
98  {
99  return isMeta() && isCapture();
100  }
101  bool isMetaOutput() const
102  {
103  return isMeta() && isOutput();
104  }
105  bool hasStreaming() const
106  {
107  return device_caps() & V4L2_CAP_STREAMING;
108  }
109 };
110 
112 {
113 public:
114  V4L2BufferCache(unsigned int numEntries);
115  V4L2BufferCache(const std::vector<std::unique_ptr<FrameBuffer>> &buffers);
116  ~V4L2BufferCache();
117 
118  int get(const FrameBuffer &buffer);
119  void put(unsigned int index);
120 
121 private:
122  class Entry
123  {
124  public:
125  Entry();
126  Entry(bool free, uint64_t lastUsed, const FrameBuffer &buffer);
127 
128  bool operator==(const FrameBuffer &buffer) const;
129 
130  bool free;
131  uint64_t lastUsed;
132 
133  private:
134  struct Plane {
135  Plane(const FrameBuffer::Plane &plane)
136  : fd(plane.fd.fd()), length(plane.length)
137  {
138  }
139 
140  int fd;
141  unsigned int length;
142  };
143 
144  std::vector<Plane> planes_;
145  };
146 
147  std::atomic<uint64_t> lastUsedCounter_;
148  std::vector<Entry> cache_;
149  /* \todo Expose the miss counter through an instrumentation API. */
150  unsigned int missCounter_;
151 };
152 
154 {
155 public:
158 
159  struct {
160  uint32_t size;
161  uint32_t bpl;
162  } planes[3];
163  unsigned int planesCount;
164 
165  const std::string toString() const;
166 };
167 
169 {
170 public:
171  explicit V4L2VideoDevice(const std::string &deviceNode);
172  explicit V4L2VideoDevice(const MediaEntity *entity);
173  V4L2VideoDevice(const V4L2VideoDevice &) = delete;
174  ~V4L2VideoDevice();
175 
176  V4L2VideoDevice &operator=(const V4L2VideoDevice &) = delete;
177 
178  int open();
179  int open(int handle, enum v4l2_buf_type type);
180  void close();
181 
182  const char *driverName() const { return caps_.driver(); }
183  const char *deviceName() const { return caps_.card(); }
184  const char *busName() const { return caps_.bus_info(); }
185 
186  const V4L2Capability &caps() const { return caps_; }
187 
188  int getFormat(V4L2DeviceFormat *format);
189  int setFormat(V4L2DeviceFormat *format);
190  std::map<V4L2PixelFormat, std::vector<SizeRange>> formats(uint32_t code = 0);
191 
192  int setSelection(unsigned int target, Rectangle *rect);
193 
194  int allocateBuffers(unsigned int count,
195  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
196  int exportBuffers(unsigned int count,
197  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
198  int importBuffers(unsigned int count);
199  int releaseBuffers();
200 
201  int queueBuffer(FrameBuffer *buffer);
203 
204  int setFrameStartEnabled(bool enable);
206 
207  int streamOn();
208  int streamOff();
209 
210  static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
211  const std::string &entity);
212 
213  V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat);
214 
215 protected:
216  std::string logPrefix() const override;
217 
218 private:
219  int getFormatMeta(V4L2DeviceFormat *format);
220  int setFormatMeta(V4L2DeviceFormat *format);
221 
222  int getFormatMultiplane(V4L2DeviceFormat *format);
223  int setFormatMultiplane(V4L2DeviceFormat *format);
224 
225  int getFormatSingleplane(V4L2DeviceFormat *format);
226  int setFormatSingleplane(V4L2DeviceFormat *format);
227 
228  std::vector<V4L2PixelFormat> enumPixelformats(uint32_t code);
229  std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
230 
231  int requestBuffers(unsigned int count, enum v4l2_memory memoryType);
232  int createBuffers(unsigned int count,
233  std::vector<std::unique_ptr<FrameBuffer>> *buffers);
234  std::unique_ptr<FrameBuffer> createBuffer(unsigned int index);
235  FileDescriptor exportDmabufFd(unsigned int index, unsigned int plane);
236 
237  void bufferAvailable(EventNotifier *notifier);
238  FrameBuffer *dequeueBuffer();
239 
240  void eventAvailable(EventNotifier *notifier);
241 
242  V4L2Capability caps_;
243 
244  enum v4l2_buf_type bufferType_;
245  enum v4l2_memory memoryType_;
246 
247  V4L2BufferCache *cache_;
248  std::map<unsigned int, FrameBuffer *> queuedBuffers_;
249 
250  EventNotifier *fdBufferNotifier_;
251  EventNotifier *fdEventNotifier_;
252 
253  bool frameStartEnabled_;
254 };
255 
257 {
258 public:
259  V4L2M2MDevice(const std::string &deviceNode);
260  ~V4L2M2MDevice();
261 
262  int open();
263  void close();
264 
265  V4L2VideoDevice *output() { return output_; }
266  V4L2VideoDevice *capture() { return capture_; }
267 
268 private:
269  std::string deviceNode_;
270 
271  V4L2VideoDevice *output_;
272  V4L2VideoDevice *capture_;
273 };
274 
275 } /* namespace libcamera */
276 
277 #endif /* __LIBCAMERA_INTERNAL_V4L2_VIDEODEVICE_H__ */
Buffer handling.
Notify of activity on a file descriptor.
Definition: event_notifier.h:18
RAII-style wrapper for file descriptors.
Definition: file_descriptor.h:15
int fd() const
Retrieve the numerical file descriptor.
Definition: file_descriptor.h:27
Frame buffer data and its associated dynamic metadata.
Definition: buffer.h:37
The MediaDevice represents a Media Controller device with its full graph of connected objects.
Definition: media_device.h:25
The MediaEntity represents an entity in the media graph.
Definition: media_object.h:86
libcamera image pixel format
Definition: pixel_format.h:17
Generic signal and slot communication mechanism.
Definition: signal.h:39
Hot cache of associations between V4L2 buffer indexes and FrameBuffer.
Definition: v4l2_videodevice.h:112
V4L2BufferCache(unsigned int numEntries)
Create an empty cache with numEntries entries.
Definition: v4l2_videodevice.cpp:164
int get(const FrameBuffer &buffer)
Find the best V4L2 buffer for a FrameBuffer.
Definition: v4l2_videodevice.cpp:206
void put(unsigned int index)
Mark buffer index as free in the cache.
Definition: v4l2_videodevice.cpp:248
The V4L2 video device image format and sizes.
Definition: v4l2_videodevice.h:154
V4L2PixelFormat fourcc
The fourcc code describing the pixel encoding scheme.
Definition: v4l2_videodevice.h:156
const std::string toString() const
Assemble and return a string describing the format.
Definition: v4l2_videodevice.cpp:385
Size size
The image size in pixels.
Definition: v4l2_videodevice.h:157
struct libcamera::V4L2DeviceFormat::@2 planes[3]
The per-plane memory size information.
unsigned int planesCount
The number of valid data planes.
Definition: v4l2_videodevice.h:163
Base class for V4L2VideoDevice and V4L2Subdevice.
Definition: v4l2_device.h:22
const std::string & deviceNode() const
Retrieve the device node path.
Definition: v4l2_device.h:32
Memory-to-Memory video device.
Definition: v4l2_videodevice.h:257
V4L2VideoDevice * capture()
Retrieve the capture V4L2VideoDevice instance.
Definition: v4l2_videodevice.h:266
void close()
Close the memory-to-memory device, releasing any resources acquired by open()
Definition: v4l2_videodevice.cpp:1758
int open()
Open a V4L2 Memory to Memory device.
Definition: v4l2_videodevice.cpp:1715
V4L2VideoDevice * output()
Retrieve the output V4L2VideoDevice instance.
Definition: v4l2_videodevice.h:265
V4L2M2MDevice(const std::string &deviceNode)
Create a new V4L2M2MDevice from the deviceNode.
Definition: v4l2_videodevice.cpp:1694
V4L2 pixel format FourCC wrapper.
Definition: v4l2_pixelformat.h:21
V4L2VideoDevice object and API.
Definition: v4l2_videodevice.h:169
std::map< V4L2PixelFormat, std::vector< SizeRange > > formats(uint32_t code=0)
Enumerate all pixel formats and frame sizes.
Definition: v4l2_videodevice.cpp:928
const char * driverName() const
Retrieve the name of the V4L2 device driver.
Definition: v4l2_videodevice.h:182
V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat)
Convert PixelFormat to its corresponding V4L2 FourCC.
Definition: v4l2_videodevice.cpp:1657
int importBuffers(unsigned int count)
Prepare the device to import count buffers.
Definition: v4l2_videodevice.cpp:1302
int releaseBuffers()
Release resources allocated by allocateBuffers() or importBuffers()
Definition: v4l2_videodevice.cpp:1330
const char * deviceName() const
Retrieve the name of the V4L2 video device.
Definition: v4l2_videodevice.h:183
std::string logPrefix() const override
Retrieve a string to be prefixed to the log message.
Definition: v4l2_videodevice.cpp:706
int allocateBuffers(unsigned int count, std::vector< std::unique_ptr< FrameBuffer >> *buffers)
Allocate and export buffers from the video device.
Definition: v4l2_videodevice.cpp:1132
int open()
Open the V4L2 video device node and query its capabilities.
Definition: v4l2_videodevice.cpp:501
int streamOn()
Start the video stream.
Definition: v4l2_videodevice.cpp:1576
int queueBuffer(FrameBuffer *buffer)
Queue a buffer to the video device.
Definition: v4l2_videodevice.cpp:1354
Signal< uint32_t > frameStart
A Signal emitted when capture of a frame has started.
Definition: v4l2_videodevice.h:205
V4L2VideoDevice(const std::string &deviceNode)
Construct a V4L2VideoDevice.
Definition: v4l2_videodevice.cpp:468
int streamOff()
Stop the video stream.
Definition: v4l2_videodevice.cpp:1600
int setFrameStartEnabled(bool enable)
Enable or disable frame start event notification.
Definition: v4l2_videodevice.cpp:1547
int getFormat(V4L2DeviceFormat *format)
Retrieve the image format set on the V4L2 video device.
Definition: v4l2_videodevice.cpp:716
void close()
Close the video device, releasing any resources acquired by open()
Definition: v4l2_videodevice.cpp:670
const char * busName() const
Retrieve the location of the device in the system.
Definition: v4l2_videodevice.h:184
int setSelection(unsigned int target, Rectangle *rect)
Set a selection rectangle rect for target.
Definition: v4l2_videodevice.cpp:1051
const V4L2Capability & caps() const
Retrieve the device V4L2 capabilities.
Definition: v4l2_videodevice.h:186
Signal< FrameBuffer * > bufferReady
A Signal emitted when a framebuffer completes.
Definition: v4l2_videodevice.h:202
static V4L2VideoDevice * fromEntityName(const MediaDevice *media, const std::string &entity)
Create a new video device instance from entity in media device media.
Definition: v4l2_videodevice.cpp:1636
int setFormat(V4L2DeviceFormat *format)
Configure an image format on the V4L2 video device.
Definition: v4l2_videodevice.cpp:735
int exportBuffers(unsigned int count, std::vector< std::unique_ptr< FrameBuffer >> *buffers)
Export buffers from the video device.
Definition: v4l2_videodevice.cpp:1176
Data structures related to geometric objects.
bool operator==(const Rectangle &lhs, const Rectangle &rhs)
Compare rectangles for equality.
Definition: geometry.cpp:69
Types and helper methods to handle libcamera image formats.
Logging infrastructure.
libcamera pixel format
Signal & slot implementation.
A memory region to store a single plane of a frame.
Definition: buffer.h:39
unsigned int length
The plane length in bytes.
Definition: buffer.h:41
FileDescriptor fd
The dmabuf file descriptor.
Definition: buffer.h:40
Describe a rectangle's position and dimensions.
Definition: geometry.h:15
Describe a two-dimensional size.
Definition: geometry.h:30
struct v4l2_capability object wrapper and helpers
Definition: v4l2_videodevice.h:35
bool hasStreaming() const
Determine if the video device can perform Streaming I/O.
Definition: v4l2_videodevice.h:105
unsigned int device_caps() const
Retrieve the capabilities of the video device.
Definition: v4l2_videodevice.h:48
bool isVideoOutput() const
Identify if the video device outputs images.
Definition: v4l2_videodevice.h:93
bool isM2M() const
Identify if the device is a Memory-to-Memory device.
Definition: v4l2_videodevice.h:79
bool isMetaCapture() const
Identify if the video device captures image meta-data.
Definition: v4l2_videodevice.h:97
bool isOutput() const
Identify if the video device outputs data.
Definition: v4l2_videodevice.h:66
bool isVideoCapture() const
Identify if the video device captures images.
Definition: v4l2_videodevice.h:89
bool isMultiplanar() const
Identify if the video device implements the V4L2 multiplanar APIs.
Definition: v4l2_videodevice.h:54
bool isMeta() const
Identify if the video device captures or outputs image meta-data.
Definition: v4l2_videodevice.h:84
bool isCapture() const
Identify if the video device captures data.
Definition: v4l2_videodevice.h:60
bool isMetaOutput() const
Identify if the video device outputs image meta-data.
Definition: v4l2_videodevice.h:101
const char * bus_info() const
Retrieve the location of the video device in the system.
Definition: v4l2_videodevice.h:44
const char * card() const
Retrieve the video device card name.
Definition: v4l2_videodevice.h:40
bool isVideo() const
Identify if the video device captures or outputs images.
Definition: v4l2_videodevice.h:72
const char * driver() const
Retrieve the driver module name.
Definition: v4l2_videodevice.h:36
Common base for V4L2 devices and subdevices.
V4L2 Pixel Format.