summaryrefslogtreecommitdiff
path: root/src/v4l2/v4l2_camera_proxy.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/v4l2/v4l2_camera_proxy.h')
-rw-r--r--src/v4l2/v4l2_camera_proxy.h113
1 files changed, 71 insertions, 42 deletions
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index e15b230d..5aa352c3 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -1,82 +1,111 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
- * v4l2_camera_proxy.h - Proxy to V4L2 compatibility camera
+ * Proxy to V4L2 compatibility camera
*/
-#ifndef __V4L2_CAMERA_PROXY_H__
-#define __V4L2_CAMERA_PROXY_H__
+#pragma once
#include <linux/videodev2.h>
#include <map>
#include <memory>
+#include <set>
#include <sys/types.h>
#include <vector>
+#include <libcamera/base/mutex.h>
+
#include <libcamera/camera.h>
#include "v4l2_camera.h"
-using namespace libcamera;
+class V4L2CameraFile;
class V4L2CameraProxy
{
public:
- V4L2CameraProxy(unsigned int index, std::shared_ptr<Camera> camera);
+ V4L2CameraProxy(unsigned int index, std::shared_ptr<libcamera::Camera> camera);
- int open(bool nonBlocking);
- void dup();
- void close();
- void *mmap(void *addr, size_t length, int prot, int flags, off_t offset);
- int munmap(void *addr, size_t length);
+ int open(V4L2CameraFile *file) LIBCAMERA_TSA_EXCLUDES(proxyMutex_);
+ void close(V4L2CameraFile *file) LIBCAMERA_TSA_EXCLUDES(proxyMutex_);
+ void *mmap(V4L2CameraFile *file, void *addr, size_t length, int prot,
+ int flags, off64_t offset) LIBCAMERA_TSA_EXCLUDES(proxyMutex_);
+ int munmap(V4L2CameraFile *file, void *addr, size_t length)
+ LIBCAMERA_TSA_EXCLUDES(proxyMutex_);
- int ioctl(unsigned long request, void *arg);
+ int ioctl(V4L2CameraFile *file, unsigned long request, void *arg)
+ LIBCAMERA_TSA_EXCLUDES(proxyMutex_);
private:
bool validateBufferType(uint32_t type);
bool validateMemoryType(uint32_t memory);
- void setFmtFromConfig(StreamConfiguration &streamConfig);
- unsigned int calculateSizeImage(StreamConfiguration &streamConfig);
- void querycap(std::shared_ptr<Camera> camera);
- void tryFormat(struct v4l2_format *arg);
+ void setFmtFromConfig(const libcamera::StreamConfiguration &streamConfig);
+ void querycap(std::shared_ptr<libcamera::Camera> camera);
+ int tryFormat(struct v4l2_format *arg);
+ enum v4l2_priority maxPriority();
void updateBuffers();
- int freeBuffers();
-
- int vidioc_querycap(struct v4l2_capability *arg);
- int vidioc_enum_fmt(struct v4l2_fmtdesc *arg);
- int vidioc_g_fmt(struct v4l2_format *arg);
- int vidioc_s_fmt(struct v4l2_format *arg);
- int vidioc_try_fmt(struct v4l2_format *arg);
- int vidioc_reqbufs(struct v4l2_requestbuffers *arg);
- int vidioc_querybuf(struct v4l2_buffer *arg);
- int vidioc_qbuf(struct v4l2_buffer *arg);
- int vidioc_dqbuf(struct v4l2_buffer *arg);
- int vidioc_streamon(int *arg);
- int vidioc_streamoff(int *arg);
-
- static unsigned int bplMultiplier(uint32_t format);
- static unsigned int imageSize(uint32_t format, unsigned int width,
- unsigned int height);
-
- static PixelFormat v4l2ToDrm(uint32_t format);
- static uint32_t drmToV4L2(const PixelFormat &format);
+ void freeBuffers();
+
+ int vidioc_querycap(V4L2CameraFile *file, struct v4l2_capability *arg);
+ int vidioc_enum_framesizes(V4L2CameraFile *file, struct v4l2_frmsizeenum *arg);
+ int vidioc_enum_fmt(V4L2CameraFile *file, struct v4l2_fmtdesc *arg);
+ int vidioc_g_fmt(V4L2CameraFile *file, struct v4l2_format *arg);
+ int vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg);
+ int vidioc_try_fmt(V4L2CameraFile *file, struct v4l2_format *arg);
+ int vidioc_g_priority(V4L2CameraFile *file, enum v4l2_priority *arg);
+ int vidioc_s_priority(V4L2CameraFile *file, enum v4l2_priority *arg);
+ int vidioc_enuminput(V4L2CameraFile *file, struct v4l2_input *arg);
+ int vidioc_g_input(V4L2CameraFile *file, int *arg);
+ int vidioc_s_input(V4L2CameraFile *file, int *arg);
+ int vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuffers *arg);
+ int vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *arg);
+ int vidioc_prepare_buf(V4L2CameraFile *file, struct v4l2_buffer *arg);
+ int vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg);
+ int vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
+ libcamera::Mutex *lock) LIBCAMERA_TSA_REQUIRES(*lock);
+ int vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg);
+ int vidioc_streamon(V4L2CameraFile *file, int *arg);
+ int vidioc_streamoff(V4L2CameraFile *file, int *arg);
+ int vidioc_g_parm(V4L2CameraFile *file, struct v4l2_streamparm *arg);
+ int vidioc_s_parm(V4L2CameraFile *file, struct v4l2_streamparm *arg);
+
+ bool hasOwnership(V4L2CameraFile *file);
+ int acquire(V4L2CameraFile *file);
+ void release(V4L2CameraFile *file);
+
+ static const std::set<unsigned long> supportedIoctls_;
unsigned int refcount_;
unsigned int index_;
- bool nonBlocking_;
- struct v4l2_format curV4L2Format_;
- StreamConfiguration streamConfig_;
- struct v4l2_capability capabilities_;
+ libcamera::StreamConfiguration streamConfig_;
unsigned int bufferCount_;
unsigned int currentBuf_;
unsigned int sizeimage_;
+ struct v4l2_capability capabilities_;
+ struct v4l2_pix_format v4l2PixFormat_;
+ struct v4l2_fract v4l2TimePerFrame_;
+
std::vector<struct v4l2_buffer> buffers_;
std::map<void *, unsigned int> mmaps_;
+ std::set<V4L2CameraFile *> files_;
+
std::unique_ptr<V4L2Camera> vcam_;
-};
-#endif /* __V4L2_CAMERA_PROXY_H__ */
+ /*
+ * This is the exclusive owner of this V4L2CameraProxy instance.
+ * When there is no owner, anybody can call any ioctl before reqbufs.
+ * The first file to call reqbufs with count > 0 or s_fmt will become
+ * the owner, and when the owner calls reqbufs with count = 0 it will
+ * release ownership. Any buffer-related ioctl (except querybuf) or
+ * s_fmt that is called by a non-owner while there exists an owner
+ * will return -EBUSY.
+ */
+ V4L2CameraFile *owner_;
+
+ /* This mutex is to serialize access to the proxy. */
+ libcamera::Mutex proxyMutex_;
+};