[RFC] Video events
Hi everybody,
yet another RFC, probably the last one before the Linux Plumbers Conference.
This RFC describes a way to pass generic events from video drivers to
userspace applications. Even though I've developed the first prototype for a
V4L2 driver, it should be applicable to DVB devices as well with minor
modifications if any. If someone familiar with DVB notices any serious
problem, please let me know.
Purpose
=======
Many video devices need to notify userspace applications of various events.
This includes, but is not limited to,
- button press events
- control change events, when the device changes the value of a control
automatically and wants to notify the user
- motor-related events, when the device reaches the end stop (this could be
handled using control change notifications on the motor controls)
- signal detection/loss on inputs
- image-related events, such as vertical sync, frame size or frame rate
change, ...
- stream-related events, such as stream start/end, when a Linux system acting
as a video device to some host (for instance a USB video gadget) receives
control requests from the host
Some of those events can be easily handled by the input subsystem, such as the
button events. Other events could hack their way into some kind of input
device, but that would be abusing the input device API and would probably
confuse some userspace applications.
A dedicated event interface is thus needed for video devices.
Current implementations
=======================
DVB video events
----------------
The ivtv and av7110 drivers use an existing event notification API implemented
for DVB devices. include/linux/dvb/video.h defines the following structure and
ioctl.
struct video_event {
__s32 type;
#define VIDEO_EVENT_SIZE_CHANGED 1
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
#define VIDEO_EVENT_DECODER_STOPPED 3
#define VIDEO_EVENT_VSYNC 4
__kernel_time_t timestamp;
union {
video_size_t size;
unsigned int frame_rate;
unsigned char vsync_field;
} u;
};
#define VIDEO_GET_EVENT _IOR('o', 28, struct video_event)
An application waits for events using the select() function by setting the
file descriptor in the exception file descriptors set. When an event is
available the poll handler sets POLLPRI which wakes up select().
The userspace application then calls ioctl(VIDIO_GET_EVENT) which fills the
struct video_event with an event type, a timestamp and event type specific
data.
UVC gadget events
-----------------
The UVC gadget driver (posted today on the linux-media and linux-usb mailing
lists) uses an independently developed but very similar method.
enum uvc_event_type
{
UVC_EVENT_CONNECT,
UVC_EVENT_DISCONNECT,
UVC_EVENT_STREAMON,
UVC_EVENT_STREAMOFF,
UVC_EVENT_SETUP,
UVC_EVENT_DATA,
};
struct uvc_event_data
{
int length;
__u8 data[64];
};
struct uvc_event
{
enum uvc_event_type type;
union {
enum usb_device_speed speed;
struct usb_ctrlrequest req;
struct uvc_event_data data;
};
};
#define UVCIOC_EVENT_READ _IOR('U', 1, struct uvc_event)
The user is notified through select() and the exception file descriptors set
exactly the same way as for the DVB video events.
ACPI events
-----------
ACPI reports button events through the input subsystem, and generic events
through netlink. For those not familiar with netlink, it's basically a kernel
<-> userspace message passing interface using sockets.
There are probably other event notification APIs in the Linux kernel, feel
free to mention the ones you know about.
Implementation proposal
=======================
My proposal is to unify the DVB video and UVC gadget event APIs into a single
video event API.
The following structure lists fields common to all event types. Some of them
(such as the sequence number) might not be required, but I've listed all the
ones I thought of.
struct video_event {
__u32 type;
__u32 sequence;
__u32 entity;
struct timeval timestamp;
__u8 data[64];
};
#define VIDEO_GET_EVENT _IOR('o', 28, struct video_event)
Applications wait for events using the select() function by setting the file
descriptor in the exception file descriptors set. When an event is available
the poll handler sets POLLPRI which wakes up select().
The userspace application then calls ioctl(VIDIO_GET_EVENT) which fills the
struct video_event. Note that the ioctl definition comes from the DVB video.h
header and can be changed to a V4L2 or media controller ioctl.
type: Similarly to V4L2 controls, event types should be defined in the
V4L2/DVB specification. Drivers could also implement private events.
sequence: Event sequence number. This field is incremented by the driver for
every event. It can be used by the application to detect lost events, caused
by buffer overruns for instance.
entity: The entity ID, when the ioctl is used with media controller nodes.
This allows a single media controller to deliver events for multiple sub-
devices and video nodes. When used directly on a video node, the entity field
is not used.
timestamp: Time at which the event was generated by the hardware. If that
information isn't available, use the time at which the event was received by
the driver. When events are related to video frames, the timestamp should be
equal (or at least as close as possible to) the related v4l2_buffer timestamp.
data: Event type-specific data. 64 bytes is completely arbitrary. A "good"
size could be chosen to have the whole structure size a multiple of cache
lines on common architectures.
As usual, comments are welcome. This will probably be discussed during the LPC
(if we can make the topic fit into the schedule).
--
Regards,
Laurent Pinchart
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Linux Input]
[Video for Linux]
[Mplayer Users]
[Linux USB Devel]
[Linux Audio Users]
[Photos]
[Yosemite Photos]
[Linux Kernel]
[Linux SCSI]
[XFree86]
[Devices]
[Yosemite Backpacking]
[Linux Input]