Re: [RFC] Video events, version 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Friday 16 October 2009 09:36:51 Sakari Ailus wrote:
> Hans Verkuil wrote:
> > On Thursday 15 October 2009 23:11:33 Laurent Pinchart wrote:
> >> Hi Sakari,
> >>
> >> On Wednesday 14 October 2009 19:48:33 Hans Verkuil wrote:
> >>> On Wednesday 14 October 2009 15:02:14 Sakari Ailus wrote:
> >>>> Here's the second version of the video events RFC. It's based on
> >>>> Laurent Pinchart's original RFC. My aim is to address the issues found
> >>>> in the old RFC during the V4L-DVB mini-summit in the Linux plumbers
> >>>> conference 2009. To get a good grasp of the problem at hand it's
> >>>> probably a good idea read the original RFC as well:
> >>>>
> >>>> <URL:http://www.spinics.net/lists/linux-media/msg10217.html>
> >>
> >> Thanks for the RFC update.
> 
> You're welcome.
> 
> >>>> Changes to version 1
> >>>> ----------------------------------
> >>>>
> >>>> struct video_event has been renamed to v4l2_event. The struct is used
> >>>> in userspace and V4L related structures appear to have v4l2 prefix so
> >>>> that should be better than video.
> >>
> >> In the end we will probably rename that to media_ or something similar
> >> in the big media controller rename (if that ever happens). For now let's
> >> keep v4l2_, that will be more consistent.
> >>
> >>>> The "entity" field has been removed from the struct v4l2_event since
> >>>> the subdevices will have their own device nodes --- the events should
> >>>> come from them instead of the media controller. Video nodes could be
> >>>> used for events, too.
> >>
> >> I would still keep the entity field. It would allow for parents to
> >> report children events and there could be use cases for that.
> >
> > We can always convert one of the reserved fields to an entity field in
> > the future. Adding support in the new API for an even newer and as yet
> > highly experimental API is not a good idea.
> 
> Then the entity field stays away for now?

As long as you add a reserved field that's marked as "don't dare touching 
this, it will be used as an entity Id later" I'm fine ;-)
 
> >>>> A few reserved fields have been added. There are new ioctls as well
> >>>> for enumeration and (un)subscribing.
> >>>>
> >>>>
> >>>> Interface description
> >>>> ---------------------
> >>>>
> >>>> Event type is either a standard event or private event. Standard
> >>>> events will be defined in videodev2.h. Private event types begin from
> >>>> V4L2_EVENT_PRIVATE. Some high order bits could be reserved for future
> >>>> use.
> >>>>
> >>>> #define V4L2_EVENT_PRIVATE_START	0x08000000
> >>>> #define V4L2_EVENT_RESERVED		0x10000000
> >>>
> >>> Suggestion: use the V4L2_EV_ prefix perhaps instead of the longer
> >>>  V4L2_EVENT?
> >>
> >> EV could be confused with electron volt, exposure value, or even escape
> >> velocity (don't underestimate the use of V4L2 in the spaceship market
> >> ;-)). On a more serious note, while I like to keep identifiers short, is
> >> the 3 characters gain worth it here ?
> 
> I'll use V4L2_EVENT_ in the next RFC, too.
> 
> >>>> VIDIOC_ENUM_EVENT is used to enumerate the available event types. It
> >>>> works a bit the same way than VIDIOC_ENUM_FMT i.e. you get the next
> >>>> event type by calling it with the last type in the type field. The
> >>>> difference is that the range is not continuous like in querying
> >>>> controls.
> >>>
> >>> Question: why do we need an ENUM_EVENT? I don't really see a use-case
> >>> for this.
> >>>
> >>> Also note that there are three methods in use for enumerating within
> >>> V4L:
> >>>
> >>> 1) there is an index field in the struct that starts at 0 and that the
> >>> application increases by 1 until the ioctl returns an error.
> >>>
> >>> 2) old-style controls where just enumerated from CID_BASE to
> >>> CID_LASTP1, which is very, very ugly.
> >>>
> >>> 3) controls new-style allow one to set bit 31 on the control ID and in
> >>> that case the ioctl will give you the first control with an ID that is
> >>> higher than the specified ID.
> >>>
> >>> 1 or 3 are both valid options IMHO.
> >>>
> >>> But again, I don't see why we need it in the first place.
> >>
> >> Applications will only subscribe to the events they can handle, so I
> >> don't think enumeration is really required. We might want to provide
> >> "subscribe to all" and "subscribe to none" options though, maybe as
> >> special events (V4L2_EVENT_NONE, V4L2_EVENT_ALL)
> >
> > Nice idea. Although we only need an EVENT_ALL. 'Subscribe to none' equals
> > 'unsubscribe all' after all :-)
> 
> Ok.
> 
> >>>> VIDIOC_G_EVENT is used to get events. sequence is the event sequence
> >>>> number and the data is specific to driver or event type.
> >>
> >> For efficiency reasons a V4L2_G_EVENTS ioctl could also be provided to
> >> retrieve multiple events.
> >>
> >> struct v4l2_events {
> >> 	__u32 count;
> >> 	struct v4l2_event __user *events;
> >> };
> >>
> >> #define VIDIOC_G_EVENTS _IOW('V', xx, struct v4l2_events)
> >
> > Hmm. Premature optimization. Perhaps as a future extension.
> 
> That *could* save one ioctl sometimes --- then you'd no there are no
> more events coming right now. But just one should be supported IMO,
> VIDIOC_G_EVENT or VIDIOC_G_EVENTS.

I forgot to mention in my last mail that we should add a flag to the 
v4l2_event structure to report if more events are pending (or even possible a 
pending event count).

> >>>> The user will get the information that there's an event through
> >>>> exception file descriptors by using select(2). When an event is
> >>>> available the poll handler sets POLLPRI which wakes up select. -EINVAL
> >>>> will be returned if there are no pending events.
> >>>>
> >>>> VIDIOC_SUBSCRIBE_EVENT and VIDIOC_UNSUBSCRIBE_EVENT are used to
> >>>> subscribe and unsubscribe from events. The argument is event type.
> >>>
> >>> Two event types can be defined already (used by ivtv):
> >>>
> >>> #define V4L2_EVENT_DECODER_STOPPED   1
> >>> #define V4L2_EVENT_OUTPUT_VSYNC      2
> >>>
> >>>> struct v4l2_eventdesc {
> >>>> 	__u32		type;
> >>>> 	__u8		description[64];
> >>>> 	__u32		reserved[4];
> >>>> };
> >>>>
> >>>> struct v4l2_event {
> >>>> 	__u32		type;
> >>>> 	__u32		sequence;
> >>>> 	struct timeval	timestamp;
> >>>> 	__u8		data[64];
> >>>
> >>> This should be a union:
> >>>
> >>>
> >>> union {
> >>> 	enum v4l2_field ev_output_vsync;

Forgot to mention this, we shouldn't use enums in kernel-userspace APIs. They 
introduce ABI issues on some platforms.

> >>> 	__u8 data[64];
> >>> };
> >>
> >> The union will grow pretty big and I'm scared it would soon become a
> >> mess.
> >
> > But otherwise apps need to unpack the data array. That's very
> > user-unfriendly. I've no problem with big unions.

But then the header file that defines v4l2_event will need to include all 
headers that define the various structure for all possible events.

> The size of the structure is now 96 bytes. I guess we could make that
> around 128 to allow a bit more space for data without really affecting
> performance.
> 
> > As an aside: I think that eventually videodev2.h should be split up.
> > Especially the control section should be moved to a separate header and
> > just be included by videodev2.h.
> >
> >>>> 	__u32		reserved[4];
> >>>> };
> >>>>
> >>>> #define VIDIOC_ENUM_EVENT	_IORW('V', 83, struct v4l2_eventdesc)
> >>>> #define VIDIOC_G_EVENT		_IOR('V', 84, struct v4l2_event)
> >>>> #define VIDIOC_SUBSCRIBE_EVENT	_IOW('V', 85, __u32)
> >>>> #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 86, __u32)
> >>>
> >>> For (un)subscribe I suggest that we also use a struct with the event
> >>> type and a few reserved fields.
> >>
> >> Agreed.
> 
> Ack.
> 
> >>>> As it was discussed in the LPC, event subscriptions should be bound to
> >>>> file handle. The implementation, however, is not visible to userspace.
> >>>> This is why I'm not specifying it in this RFC.
> >>>>
> >>>> While the number of possible standard (and probably private) events
> >>>> would be quite small and the implementation could be a bit field, I do
> >>>> see that the interface must be using types passed as numbers instead
> >>>> of bit fields.
> >>>>
> >>>> Is it necessary to buffer events of same type or will an event replace
> >>>> an older event of the same type? It probably depends on event type
> >>>> which is better. This is also a matter of implementation.
> >>>>
> >>>>
> >>>> Comments and questions are more than welcome.
> >>>
> >>> Here's a mixed bag of idea/comments:
> >>>
> >>> We need to define what to do when you unsubscribe an event and there
> >>> are still events of that type pending. Do we remove those pending
> >>> events as well? I think we should just keep them, but I'm open for
> >>> other opinions.
> >>
> >> It would be easier to keep them and I don't think that would hurt.
> 
> I'd guess so, too.
> 
> >>> I was wondering if a 'count' field in v4l2_event might be useful: e.g.
> >>> if you get multiple identical events, and that event is already
> >>> registered, then you can just increase the count rather than adding the
> >>> same event again. This might be overengineering, though. And to be
> >>> honest, I can't think of a use-case, but it's something to keep in mind
> >>> perhaps.
> >>
> >> That's called events compression in the GUI world. The main reason to
> >> implement this is efficiency when dealing with events that can occur at
> >> a high frequency. For instance, when moving a window and thus exposing
> >> previously unexposed parts that need to be redrawn, compressing all the
> >> redraw events generated while the window moves make sense. There could
> >> be use cases in the media world as well, but I think this is a case of
> >> overengineering at the moment. We can always implement it later, and I
> >> don't think a count field would be useful anyway, as events that could
> >> be repeated will probably be intermixed with other events.
> 
> Perhaps more than four reserved fields should be allocated for the event
> structure? :-) :-)

As you mentioned that we have 32 bytes left if we want to pad to 128 bytes, 
I'd go for additional reserved fields.

> >>> Would we ever need a VIDIOC_S_EVENT to let the application set an
> >>> event? ('software events').
> >>
> >> Using a kernel driver to pass information from one userspace application
> >> to another doesn't seem like a very good design IMHO. Let's not do that
> >> for now.
> >>
> >>> Rather than naming the ioctl VIDIOC_G_EVENT, perhaps VIDIOC_DQEVENT
> >>> might be more appropriate.
> >>
> >> No preference there.
> 
> VIDIOC_DQEVENTS? :-)
> 
> >>> How do we prevent the event queue from overflowing? Just hardcode a
> >>> watermark? Alternatively, when subscribing an event we can also pass
> >>> the maximum number of allowed events as an argument.
> >>
> >> We can't prevent it from overflowing if the userspace application isn't
> >> fast enough. In that case events will be discarded, and the application
> >> will find out using the sequence number.
> >
> > Obviously, but my question is whether we use a fixed internal queue or
> > whether we make this something that the application can configure.
> >
> > That said, I think the initial implementation should be that the
> > subscribe ioctl gets a struct with the event type and a few reserved
> > fields so that in the future we can use one of the reserved fields as a
> > configuration parameter. So for now we just have some default watermark
> > that is set by the driver.
> 
> I'd like to think a queue size defined by the driver is fine at this
> point. It's probably depending on the driver rather than application how
> long the queue should to be. At some point old events start becoming
> uninteresting...

I agree, let's not worry about it right now.

-- 
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

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux