Re: [RFC] Video events, version 2

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

 



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

Yup.

>>>>> 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'm not keen on using pointers insides structures unless there is a very
good reason to do so. In practice it complicates the driver code
substantially due to all the kernel-to-userspace copies that need to be
done that are normally handled by video_ioctl2. In addition it requires
custom code in the compat-ioctl32 part as well.

>>>>> 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;
>>>> 	__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.
>
> 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.

With 'big unions' I didn't mean the memory size. I think 64 bytes (16
longs) is a decent size. I was talking about the union definition in the
videodev2.h header.

>> 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? :-) :-)
>
>>>> 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...

Question: will we drop old events or new events? Or make this
configurable? Or driver dependent?

Regards,

         Hans

-- 
Hans Verkuil - video4linux developer - sponsored by TANDBERG Telecom

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