libcamera: include/libcamera/internal/v4l2_videodevice.h Source File

libcamera v0.2.0 Supporting cameras in Linux since 2019

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