diff options
Diffstat (limited to 'src/v4l2/v4l2_camera_proxy.h')
-rw-r--r-- | src/v4l2/v4l2_camera_proxy.h | 113 |
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_; +}; |