V4L2 file handles and event interface
cover V4L2 file handles and event interface
Hi,
Here's the first version of the V4L2 file handle and event interface patchset. I posted it as RFC since there are a few issues with the contents and I have no assurrances that this even is functional at the moment.
The first patch adds the V4L2 file handle support and the rest are for V4L2 events.
A few notes on the patches:
- I don't like the locking too much. Perhaps the file handle specific lock (events->lock) could be dropped in favour of the lock for v4l2_file_handle in video_device.
- Event queue depth is not controlled at the moment.
- (Un)subscribing all events is not supported.
Comments are very welcome.
Cheers,
Signature · 2 lines
Sakari Ailus [email protected]
RFC 1/4 V4L: File handles
This patch adds a list of v4l2_file_handle structures to every video_device. It allows using file handle related information in V4L2. The event interface is one example of such use.
--- drivers/media/video/Makefile | 2 +- drivers/media/video/v4l2-dev.c | 7 +++- drivers/media/video/v4l2-fh.c | 95 ++++++++++++++++++++++++++++++++++++++++ include/media/v4l2-dev.h | 4 ++ include/media/v4l2-fh.h | 45 +++++++++++++++++++ 5 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 drivers/media/video/v4l2-fh.c create mode 100644 include/media/v4l2-fh.h
drivers/media/video/Makefile +1 -1
@@ -10,7 +10,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o # V4L2 core modules
drivers/media/video/v4l2-dev.c +6 -1
@@ -283,7 +283,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)/* and increase the device refcount */ video_get (vdev);mutex_unlock (&videodev_lock); -if (vdev->fops->open) + ret =v4l2_file_handle_add (vdev, filp); +if (!ret && vdev->fops->open) ret = vdev->fops->open (filp);/* decrease the refcount in case of an error */
@@ -301,6 +302,8 @@ static int v4l2_release(struct inode *inode, struct file *filp)if (vdev->fops->release) vdev->fops->release (filp); +v4l2_file_handle_del (vdev, filp); +/* decrease the refcount unconditionally since the release() return value is ignored. */ video_put (vdev);
@@ -421,6 +424,8 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,if (!vdev->release)return -EINVAL ; +v4l2_file_handle_init (vdev); +/* Part 1: check device type */ switch (type) {case VFL_TYPE_GRABBER :
drivers/media/video/v4l2-fh.c new file +95 -0
95 lines not on this page · raw message
include/media/v4l2-dev.h +4 -0
@@ -16,6 +16,8 @@#include <linux/mutex.h> #include <linux/videodev2.h> +#include <media/v4l2-fh.h> +#define VIDEO_MAJOR 81#define VFL_TYPE_GRABBER 0
@@ -77,6 +79,8 @@ struct video_device/* attribute to differentiate multiple indices on one physical device */ int index; +spinlock_t fh_lock;/* Lock for file handle list */ +struct list_head fh;/* File handle list */ int debug;/* Activates debug level*/ /* Video standard vars */
include/media/v4l2-fh.h new file +45 -0
45 lines not on this page · raw message
Signature · 1 line
1.5.6.5
RFC 2/4 V4L: Events: Add new ioctls for events
This patch adds a set of new ioctls to the V4L2 API. The ioctls conform to V4L2 Events RFC version 2.3:
<URL:http://www.spinics.net/lists/linux-media/msg12033.html>
--- drivers/media/video/v4l2-compat-ioctl32.c | 3 +++ drivers/media/video/v4l2-ioctl.c | 3 +++ include/linux/videodev2.h | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 0 deletions(-)
drivers/media/video/v4l2-compat-ioctl32.c +3 -0
@@ -1077,6 +1077,9 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)case VIDIOC_DBG_G_REGISTER :case VIDIOC_DBG_G_CHIP_IDENT :case VIDIOC_S_HW_FREQ_SEEK : +case VIDIOC_DQEVENT : +case VIDIOC_SUBSCRIBE_EVENT : +case VIDIOC_UNSUBSCRIBE_EVENT : ret =do_video_ioctl (file, cmd, arg);break ;
drivers/media/video/v4l2-ioctl.c +3 -0
@@ -283,6 +283,9 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_DBG_G_CHIP_IDENT)] = "VIDIOC_DBG_G_CHIP_IDENT", [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", + [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", + [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", + [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", #endif };#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
include/linux/videodev2.h +24 -0
@@ -1536,6 +1536,27 @@ struct v4l2_streamparm { };/* +* E V E N T S +*/ + +struct v4l2_event { +__u32 count; +__u32 type; +__u32 sequence; +struct timespec timestamp; +__u32 reserved[8 ]; +__u8 data[64 ]; +}; + +struct v4l2_event_subscription { +__u32 type; +__u32 reserved[8 ]; +}; + +#define V4L2_EVENT_ALL 0 +#define V4L2_EVENT_PRIVATE_START 0x08000000 + +/* * A D V A N C E D D E B U G G I N G * * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
@@ -1651,6 +1672,9 @@ struct v4l2_dbg_chip_ident {#endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +#define VIDIOC_DQEVENT _IOR('V', 83, struct v4l2_event) +#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 84, struct v4l2_event_subscription) +#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 85, struct v4l2_event_subscription)/* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */
Signature · 1 line
1.5.6.5
RFC 3/4 V4L: Events: Support event handling in do_ioctl
Add support for event handling to do_ioctl.
--- drivers/media/video/v4l2-ioctl.c | 48 ++++++++++++++++++++++++++++++++++++++ include/media/v4l2-ioctl.h | 7 +++++ 2 files changed, 55 insertions(+), 0 deletions(-)
drivers/media/video/v4l2-ioctl.c +48 -0
@@ -1797,7 +1797,55 @@ static long __video_do_ioctl(struct file *file, }break ; } +case VIDIOC_DQEVENT : + { +struct v4l2_event *ev = arg; + +if (!ops->vidioc_dqevent) +break ; + + ret = ops->vidioc_dqevent (file, ev); +if (ret <0 ) { +dbgarg (cmd,"no pending events?" ); +break ; + } +dbgarg (cmd, +"count=%d, type=0x%8.8x, sequence=%d, " +"timestamp=%d.%9.9lu " , + ev->count, ev->type, ev->sequence, + (int )ev->timestamp.tv_sec, ev->timestamp.tv_nsec); +break ; + } +case VIDIOC_SUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; +if (!ops->vidioc_subscribe_event) +break ; + + ret = ops->vidioc_subscribe_event (file, sub); +if (ret <0 ) { +dbgarg (cmd,"failed, ret=%ld" , ret); +break ; + } +dbgarg (cmd,"type=0x%8.8x" , sub->type); +break ; + } +case VIDIOC_UNSUBSCRIBE_EVENT : + { +struct v4l2_event_subscription *sub = arg; + +if (!ops->vidioc_unsubscribe_event) +break ; + + ret = ops->vidioc_unsubscribe_event (file, sub); +if (ret <0 ) { +dbgarg (cmd,"failed, ret=%ld" , ret); +break ; + } +dbgarg (cmd,"type=0x%8.8x" , sub->type); +break ; + }default : {if (!ops->vidioc_default)
include/media/v4l2-ioctl.h +7 -0
@@ -239,6 +239,13 @@ struct v4l2_ioctl_ops {int (*vidioc_enum_frameintervals) (struct file *file,void *fh,struct v4l2_frmivalenum *fival); +int (*vidioc_dqevent) (struct file *file, +struct v4l2_event *ev); +int (*vidioc_subscribe_event) (struct file *file, +struct v4l2_event_subscription *sub); +int (*vidioc_unsubscribe_event) (struct file *file, +struct v4l2_event_subscription *sub); +/* For other private ioctls */ long (*vidioc_default) (struct file *file,void *fh,int cmd,void *arg);
Signature · 1 line
1.5.6.5
RFC 4/4 V4L: Events: Add backend
Add event handling backend to V4L2. The backend handles event subscription and delivery to file handles. Event subscriptions are based on file handle. Events may be delivered to all subscribed file handles on a device independent of where they originate from.
--- drivers/media/video/Makefile | 3 +- drivers/media/video/v4l2-event.c | 254 ++++++++++++++++++++++++++++++++++++++ drivers/media/video/v4l2-fh.c | 9 ++ include/media/v4l2-event.h | 73 +++++++++++ include/media/v4l2-fh.h | 3 + 5 files changed, 341 insertions(+), 1 deletions(-) create mode 100644 drivers/media/video/v4l2-event.c create mode 100644 include/media/v4l2-event.h
drivers/media/video/Makefile +2 -1
@@ -10,7 +10,8 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ + v4l2-event.o # V4L2 core modules
drivers/media/video/v4l2-event.c new file +254 -0
254 lines not on this page · raw message
drivers/media/video/v4l2-fh.c +9 -0
@@ -59,6 +59,7 @@ int v4l2_file_handle_add(struct video_device *vdev, struct file *filp) {struct v4l2_file_handle *fh;unsigned long flags; +int ret; fh =kmalloc (sizeof (*fh),GFP_KERNEL );if (!fh)
@@ -66,6 +67,12 @@ int v4l2_file_handle_add(struct video_device *vdev, struct file *filp) fh->filp = filp; + ret =v4l2_event_init (&fh->events); +if (ret) { +kfree (fh); +return ret; + } +spin_lock_irqsave (&vdev->fh_lock, flags);list_add (&fh->list, &vdev->fh);spin_unlock_irqrestore (&vdev->fh_lock, flags);
@@ -79,6 +86,8 @@ void v4l2_file_handle_del(struct video_device *vdev, struct file *filp)struct v4l2_file_handle *fh =v4l2_file_handle_get (vdev, filp);unsigned long flags; +v4l2_event_exit (&fh->events); +spin_lock_irqsave (&vdev->fh_lock, flags);list_del (&fh->list);spin_unlock_irqrestore (&vdev->fh_lock, flags);
include/media/v4l2-event.h new file +73 -0
73 lines not on this page · raw message
include/media/v4l2-fh.h +3 -0
@@ -28,9 +28,12 @@#include <linux/types.h> #include <linux/list.h> +#include <media/v4l2-event.h> +struct v4l2_file_handle {struct list_head list;struct file *filp; +struct v4l2_events events;/* events, pending and subscribed */ };struct video_device ;
Signature · 1 line
1.5.6.5