mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
6.8 KiB
233 lines
6.8 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* generic helper functions for handling video4linux capture buffers |
|
* |
|
* (c) 2007 Mauro Carvalho Chehab, <[email protected]> |
|
* |
|
* Highly based on video-buf written originally by: |
|
* (c) 2001,02 Gerd Knorr <[email protected]> |
|
* (c) 2006 Mauro Carvalho Chehab, <[email protected]> |
|
* (c) 2006 Ted Walther and John Sokol |
|
*/ |
|
|
|
#ifndef _VIDEOBUF_CORE_H |
|
#define _VIDEOBUF_CORE_H |
|
|
|
#include <linux/poll.h> |
|
#include <linux/videodev2.h> |
|
|
|
#define UNSET (-1U) |
|
|
|
|
|
struct videobuf_buffer; |
|
struct videobuf_queue; |
|
|
|
/* --------------------------------------------------------------------- */ |
|
|
|
/* |
|
* A small set of helper functions to manage video4linux buffers. |
|
* |
|
* struct videobuf_buffer holds the data structures used by the helper |
|
* functions, additionally some commonly used fields for v4l buffers |
|
* (width, height, lists, waitqueue) are in there. That struct should |
|
* be used as first element in the drivers buffer struct. |
|
* |
|
* about the mmap helpers (videobuf_mmap_*): |
|
* |
|
* The mmaper function allows to map any subset of contiguous buffers. |
|
* This includes one mmap() call for all buffers (which the original |
|
* video4linux API uses) as well as one mmap() for every single buffer |
|
* (which v4l2 uses). |
|
* |
|
* If there is a valid mapping for a buffer, buffer->baddr/bsize holds |
|
* userspace address + size which can be fed into the |
|
* videobuf_dma_init_user function listed above. |
|
* |
|
*/ |
|
|
|
struct videobuf_mapping { |
|
unsigned int count; |
|
struct videobuf_queue *q; |
|
}; |
|
|
|
enum videobuf_state { |
|
VIDEOBUF_NEEDS_INIT = 0, |
|
VIDEOBUF_PREPARED = 1, |
|
VIDEOBUF_QUEUED = 2, |
|
VIDEOBUF_ACTIVE = 3, |
|
VIDEOBUF_DONE = 4, |
|
VIDEOBUF_ERROR = 5, |
|
VIDEOBUF_IDLE = 6, |
|
}; |
|
|
|
struct videobuf_buffer { |
|
unsigned int i; |
|
u32 magic; |
|
|
|
/* info about the buffer */ |
|
unsigned int width; |
|
unsigned int height; |
|
unsigned int bytesperline; /* use only if != 0 */ |
|
unsigned long size; |
|
enum v4l2_field field; |
|
enum videobuf_state state; |
|
struct list_head stream; /* QBUF/DQBUF list */ |
|
|
|
/* touched by irq handler */ |
|
struct list_head queue; |
|
wait_queue_head_t done; |
|
unsigned int field_count; |
|
u64 ts; |
|
|
|
/* Memory type */ |
|
enum v4l2_memory memory; |
|
|
|
/* buffer size */ |
|
size_t bsize; |
|
|
|
/* buffer offset (mmap + overlay) */ |
|
size_t boff; |
|
|
|
/* buffer addr (userland ptr!) */ |
|
unsigned long baddr; |
|
|
|
/* for mmap'ed buffers */ |
|
struct videobuf_mapping *map; |
|
|
|
/* Private pointer to allow specific methods to store their data */ |
|
int privsize; |
|
void *priv; |
|
}; |
|
|
|
struct videobuf_queue_ops { |
|
int (*buf_setup)(struct videobuf_queue *q, |
|
unsigned int *count, unsigned int *size); |
|
int (*buf_prepare)(struct videobuf_queue *q, |
|
struct videobuf_buffer *vb, |
|
enum v4l2_field field); |
|
void (*buf_queue)(struct videobuf_queue *q, |
|
struct videobuf_buffer *vb); |
|
void (*buf_release)(struct videobuf_queue *q, |
|
struct videobuf_buffer *vb); |
|
}; |
|
|
|
#define MAGIC_QTYPE_OPS 0x12261003 |
|
|
|
/* Helper operations - device type dependent */ |
|
struct videobuf_qtype_ops { |
|
u32 magic; |
|
|
|
struct videobuf_buffer *(*alloc_vb)(size_t size); |
|
void *(*vaddr) (struct videobuf_buffer *buf); |
|
int (*iolock) (struct videobuf_queue *q, |
|
struct videobuf_buffer *vb, |
|
struct v4l2_framebuffer *fbuf); |
|
int (*sync) (struct videobuf_queue *q, |
|
struct videobuf_buffer *buf); |
|
int (*mmap_mapper) (struct videobuf_queue *q, |
|
struct videobuf_buffer *buf, |
|
struct vm_area_struct *vma); |
|
}; |
|
|
|
struct videobuf_queue { |
|
struct mutex vb_lock; |
|
struct mutex *ext_lock; |
|
spinlock_t *irqlock; |
|
struct device *dev; |
|
|
|
wait_queue_head_t wait; /* wait if queue is empty */ |
|
|
|
enum v4l2_buf_type type; |
|
unsigned int msize; |
|
enum v4l2_field field; |
|
enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */ |
|
struct videobuf_buffer *bufs[VIDEO_MAX_FRAME]; |
|
const struct videobuf_queue_ops *ops; |
|
struct videobuf_qtype_ops *int_ops; |
|
|
|
unsigned int streaming:1; |
|
unsigned int reading:1; |
|
|
|
/* capture via mmap() + ioctl(QBUF/DQBUF) */ |
|
struct list_head stream; |
|
|
|
/* capture via read() */ |
|
unsigned int read_off; |
|
struct videobuf_buffer *read_buf; |
|
|
|
/* driver private data */ |
|
void *priv_data; |
|
}; |
|
|
|
static inline void videobuf_queue_lock(struct videobuf_queue *q) |
|
{ |
|
if (!q->ext_lock) |
|
mutex_lock(&q->vb_lock); |
|
} |
|
|
|
static inline void videobuf_queue_unlock(struct videobuf_queue *q) |
|
{ |
|
if (!q->ext_lock) |
|
mutex_unlock(&q->vb_lock); |
|
} |
|
|
|
int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb, |
|
int non_blocking, int intr); |
|
int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, |
|
struct v4l2_framebuffer *fbuf); |
|
|
|
struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q); |
|
|
|
/* Used on videobuf-dvb */ |
|
void *videobuf_queue_to_vaddr(struct videobuf_queue *q, |
|
struct videobuf_buffer *buf); |
|
|
|
void videobuf_queue_core_init(struct videobuf_queue *q, |
|
const struct videobuf_queue_ops *ops, |
|
struct device *dev, |
|
spinlock_t *irqlock, |
|
enum v4l2_buf_type type, |
|
enum v4l2_field field, |
|
unsigned int msize, |
|
void *priv, |
|
struct videobuf_qtype_ops *int_ops, |
|
struct mutex *ext_lock); |
|
int videobuf_queue_is_busy(struct videobuf_queue *q); |
|
void videobuf_queue_cancel(struct videobuf_queue *q); |
|
|
|
enum v4l2_field videobuf_next_field(struct videobuf_queue *q); |
|
int videobuf_reqbufs(struct videobuf_queue *q, |
|
struct v4l2_requestbuffers *req); |
|
int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b); |
|
int videobuf_qbuf(struct videobuf_queue *q, |
|
struct v4l2_buffer *b); |
|
int videobuf_dqbuf(struct videobuf_queue *q, |
|
struct v4l2_buffer *b, int nonblocking); |
|
int videobuf_streamon(struct videobuf_queue *q); |
|
int videobuf_streamoff(struct videobuf_queue *q); |
|
|
|
void videobuf_stop(struct videobuf_queue *q); |
|
|
|
int videobuf_read_start(struct videobuf_queue *q); |
|
void videobuf_read_stop(struct videobuf_queue *q); |
|
ssize_t videobuf_read_stream(struct videobuf_queue *q, |
|
char __user *data, size_t count, loff_t *ppos, |
|
int vbihack, int nonblocking); |
|
ssize_t videobuf_read_one(struct videobuf_queue *q, |
|
char __user *data, size_t count, loff_t *ppos, |
|
int nonblocking); |
|
__poll_t videobuf_poll_stream(struct file *file, |
|
struct videobuf_queue *q, |
|
poll_table *wait); |
|
|
|
int videobuf_mmap_setup(struct videobuf_queue *q, |
|
unsigned int bcount, unsigned int bsize, |
|
enum v4l2_memory memory); |
|
int __videobuf_mmap_setup(struct videobuf_queue *q, |
|
unsigned int bcount, unsigned int bsize, |
|
enum v4l2_memory memory); |
|
int videobuf_mmap_free(struct videobuf_queue *q); |
|
int videobuf_mmap_mapper(struct videobuf_queue *q, |
|
struct vm_area_struct *vma); |
|
|
|
#endif
|
|
|