Proposal for channel coordination between multiple v4l2 users

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



Hello all.

Summary:  I'm proposing an extension for the v4l2 API which would allow
device users (i) to "play nice" with each other in regard to channel
changes and (ii) to efficiently detect channel or norm changes by
other users.  I've made patches against bttv and saa7134 and small
test programs as proof of concept which I'd like to put the up for
discussion.

HTML version of this text and download of patches are available at:
http://nxtvepg.sourceforge.net/v4l2


A few months ago I already mailed to the list asking for an extension
of the v4l2 API to compensate for some of the side-effects of allowing
multiple opens of the video devices, in particular for data services.
My impression of the discussion was that there was an agreement that
something should be done, but driver extensions should be as minimal
as possible.  Unfortunately no solution was found at that time that
enthralled anyone.

In the meantime we've discussed the matter some more on the libzvbi
mailing list and came up with a solution which would provide the
necessary means for data service apps.  Please keep in mind all
following relates only to *channel* switching; capturing is not
affected.


(i) Avoiding disruptive channel changes

Background data harvesting applications often require to switch to a
certain channel to load data from.  Preferrably such channel changes
should be restricted to times when no TV display or other interactive
application is running, to avoid annoying the user and forcing him/her
to manually kill the background process.  With v4l1 such apps could
achieve that simply by switching the channel through /dev/video.

To allow v4l2 clients to "play nice" too, I'd like to propose a concept
which is based on a numeric "priority" level: by default all device
users are assigned a middle priority when opening the device. By means
of a new ioctl VIDIOC_S_CHNPRIO users can freely manipulate their level.
Channel, frequency or norm changes would only succeed if there is no
user with a higher priority, else the change is rejected and error EBUSY
is returned (coordination of users at the same level is outside of the
scope of this proposal, as it is dealt with differently between levels.)

Normal TV display and other interactive apps would not need to be
changed at all.  Background apps would only have to call the above ioctl
once to lower their priority to the minimum and be prepared to get EBUSY
upon channel changes afterwards.

This ioctl could also allow to raise ones default above the default,
which can be used by SoftVCRs to assist the user in avoiding to
accidentially destroy the recording, e.g. by starting a TV display app
which switches to channel #1 by default.  I don't know yet if this
possibility will be used, but it's a straight-forward extension and
comes at close to zero extra effort, so I don't see a reason not to
include it.  We could also create an "exclusive" level which is only
granted to one file handle for those apps which need to make absolutely
sure noone interferes with their channel setup.

I've proposed such a simple priority scheme in the past, but it was
rejected by Gerd Knorr AFAIR because of implementational issues, e.g.
absence of a list of device users.  I've managed to work around this by
maintaining global counters for the number of clients at each priority
level (see the patch). Each file handle also remembers it's own level
in it's private data.  To the driver checking channel change permission
simply means checking for a count greater zero in the priorities above
the respective file handle's own priority level.

I'd propose to offer the following 4 priority levels:

  3= exclusive (non-interruptable TV recording)
  2= recording (secondary, non-exclusive recording)
  1= interactive (default: TV viewer, Radio, teletext reader)
  0= background (background data harvesting)

For informational purposes the max. priority level among all device
users can be queried with ioctl VIDIOC_G_PRIO.

Still open is the handling of radio: bttv doesn't keep private data
hence radio app's channel priority level is fixed at the default.
Also the saa7134 driver immediately puts the device in radio mode
when the device is opened, thereby destroying the channel setup of any
other applications regardless of channel priorities.

(ii) Channel event notifications

Even with the above instruments it'll still happen frequently that one
app switches the channel while others are capturing.  Most types of
applications should react to such changes in one way or another: TV
displays will at least update the channel name in their window's title
bar, teletext apps will flush their page cache etc.

I'm proposing to add a mechanism that can provide at least a trigger
to affected applications when a change of global parameters occurs.
They can then use the appropriate ioctls to query for new parameter
values.  Again, this mechanism is designed to allow applications to
play nice which are otherwise not aware of each other. It's specifically
not designed to support communication between video control panels and
TV displays, which probably needs more elaborate event processing and
should be dealt with in user space.

To provide such triggers I propose to add two ioctl commands: one to
put a file handle into an "event reporting" mode (S_CHNEVENT), and a
second one to query for ocurred events (G_CHNEVENT).  The latter ioctl
can either block until an event occurs, or poll() and select() can be
used to wait for an event.

The crux here is to use a separate file handle exclusively for event
reporting.  This keeps implementation in the driver simple, as users
need not be woken up while blocked in a video buffer queue etc. Still
no new minor device is required, as any v4l2 file handle can be put
into event reporting mode simply by use of S_CHNEVENT.

Currently G_CHNEVENT returns an event mask which narrows down which type
of event has occured, i.e. channel/tuner/freq., video norm, channel user
priority.  The intention is to limit the number of ioctl queries
the user has to do; but I'm not sure yet if we really need that or can
drop it to keep the driver patch simpler.

In the driver the implementation is based on a set of counters in the
global device struct.  Counters are incremented whenever the respective
event type occurs.  Each file handle has a copy of the counter array
in it's private data.  Clients waiting for events in G_CHNEVENT, or
poll()s on file handles in event reporting mode are woken up whenever
their private counter set differs from the global one.

I should note though that usually a channel change consists of several
subsequent ioctls, but this solution will wake up the user already upon
the first. So the user should probably not respond to the notification
immediately, but instead use a timer, or only set a flag and deal with
it when the next video/vbi frame arrives.  VBI apps will usually skip
one or two frames after channel changes anyways, so it's not a problem,
since a subsequent notification would only reset the skip counter.

Also note the mask bits given to S_CHNEVENT are currently ignored; the
parameter is only checked against 0 to en- or disable event report mode.
G_CHNEVENT will hence wake up for any event, not only the ones specified
in the mask.  I intend to clean this up after the discussion.


If you need more details or background, please refer to the patches
at the URL above or mail to the list or to me personally. Any comments
or suggestions are welcome.

bye,
-tom




[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux