To: video4linux list <video4linux-list@xxxxxxxxxx> 
Subject: v4l2 api 
From: Gerd Knorr <kraxel@xxxxxxxxxxx> 
Date: Wed, 9 Oct 2002 16:21:08 +0200 
Delivered-to: video4linux-list@xxxxxxxxxxxxxxxxxx 
User-agent: Mutt/1.3.28i 

  Hi *,

Michael Schimek currently reviews the v4l2 API documentation and due
to this we recently talked/emailed about some details of the v4l2 api.

We came to the conclusion that it there are good reasons to do some
incompatible changes before submitting v4l2 to the standard kernel:

 (1) some quirks from v4l1 still present in v4l2.
 (2) some recent changes within the kernel.


The major changes we are thinking about are:

 * open() handling.

   The recent changes in videodev.c provide a sane way for drivers to
   support multiple opens.  This allows to take a completely different
   approach for using the different functions of a video card:  Instead
   of having multiple devices (video, vbi, ...) there is only one which
   can be opened multiple times and switched to different modes.

   Example: to capture vbi data you will simply open /dev/video and
   switch the device into vbi mode using the S_FMT ioctl with
   v4l2_format->type set to V4L2_BUF_TYPE_VBI_CAPTURE.

   This approach removes the need to figure somehow which devices are
   related, because all functions of the card can be used using the same
   special file.  It also allows adding other formats without major
   pain (sliced vbi, rds, audio?, ...).

   /dev/vbi will still be there for backward compatibility, but it will
   be basically the same as /dev/video, just with vbi mode turned on by
   default.

   This change reqires v4l2_capability being updated, because devices
   can support both video and vbi capture now, thus the current type
   approach doesn't cut it.

 * new field handling, the current v4l2 spec a bit confusing about
   this.  There is now:

   enum v4l2_field {
	V4L2_FIELD_ANY        = 0, /* driver can choose from none,
				      top, bottom, interlaced
				      depending on whatever it thinks
				      is approximate ... */
	V4L2_FIELD_NONE       = 1, /* this device has no fields ... */
	V4L2_FIELD_TOP        = 2, /* top field only */
	V4L2_FIELD_BOTTOM     = 3, /* bottom field only */
	V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
	V4L2_FIELD_SEQUENTIAL = 5, /* both fields sequential into one
				      buffer */
	V4L2_FIELD_ALTERNATE  = 6, /* both fields alternating into
				      separate buffers */
   };

   Both v4l2_pix_format and v4l2_buffer have this, for v4l2_pix_format
   this field is r/w, for v4l2_buffer it is read-only (for the
   application).


Because the stuff above implies we will be source and binary
incompatible anyway I've also did a number of other cleanups as well:

 * drop open flags
   obsolete

 * drop all effect stuff
   That was planned anyway.  Nobody uses it (yet).  And I suspect nobody
   ever will.  Processors become faster, and special hardware is more
   expencive + less flexible.

   what about the video output stuff btw.  Does anybody use that?

 * drop mmap v4l1 compat flags
   obsolete

 * drop v4l2_q_* helper functions
   we have < linux/list.h>

 * drop zoom stuff
   use crop_* instead (whilch needs some review + exact specification)

 * drop struct v4l2_performance + ioctl
   Applications have to do that themself anyway to keep a/v in sync.
   And because the ioctl is optional and thus apps can't depend on it
   being present it is even more useless.

 * drop VIDIOC_*_FREQ ioctls
   There is VIDIOC_*_FREQUENCY ...

 * replace stamp_t with struct timeval, drop all time functions.
   We'll simply use gettimeofday like everybody else.

 * struct v4l2_capability
   - drop inputs, outputs, audios (use enum ioctls for these ...)
   - drop maxframerate (not really useful here, depends on tv norm).
   - replace type + flags with capabilities (see above).

 * struct v4l2_pix_format
   - drop depth, flags (field changes mentioned above.
                        depth is redundant, pixelformat implies this.)
   - add fields

 * struct v4l2_fmtdesc
   - drop depth, flags

 * struct v4l2_buffer
   - add field

 * struct v4l2_framebuffer
   - one base ptr only (nobody ever used the other two).

 * renamed preview => overlay

 * v4l2_inout/output
   - replace assoc_audio with audioset
   - drop capability

 * struct v4l2_queryctrl
   - drop category, group


There are still some items which are on my / Michaels TODO list.  Stuff
which needs some discussion and/or can be added to the API later:

 * v4l2_framebuffer
   It would be better to pass the (pci) device somehow instead of some
   physical address for pci-pci xfer overlay.  Not sure how to do that
   through, there seems to be no standard struct (yet?) to pass that
   kind of info between kernel and userland ...

 * The crop/scaling thing needs some work, Michael is busy with that.

 * more elements for v4l2_format: rds + maybe sound comes to mind.

 * The min/max sizes in v4l2_capabilities are somewhat ugly, maybe
   we should move that to another ioctl.  First problem is that they
   might depend on some device parameters (tv norm, maybe some speed vs.
   quality option on usb cams).  Second problem is that the size might
   be different for overlay and capture (some matrox guys have this
   problem IIRC).

 * exact read() behaviour needs to be specified (for video + vbi):
   - read partial frames: drivers are allowed and/or required to
     implement that?
   - should read() use a buffer queue?  Yes / no / configure via
     v4l2_captureparm?  A queue has the advantage that you can
     do full-rate capture using read() because the driver doesn't
     need to start/stop capture for every read() call.  The drawback is
     that the driver must buffer+copy the video data and can't attempt
     to do zerocopy DMA.  It may also happen that applications which
     capture frames in large intervalls receive old data.

 * kernel 2.5.x has async I/O support.  I think it would be a good
   idea to support aio for video frames in v4l2 drivers.  Applications
   can queue multiple read requests.  This is IMHO a better solution
   than configuring the read() queuing behaviour with an ioctl.  The
   ioctl is somewhat ugly, and the aio way allows zerocopy DMA.

Comments?  Anything else we should change?

  Gerd

PS: below is the current status of the updated videodev2 header file.

Code

To: video4linux-list@xxxxxxxxxx 
Subject: Re: v4l2 api 
From: Gerd Knorr <kraxel@xxxxxxxxxxx> 
Date: Thu, 10 Oct 2002 15:38:10 +0200 
Delivered-to: video4linux-list@xxxxxxxxxxxxxxxxxx 
In-reply-to: <20021009142108.GA6050@xxxxxxxxxxx> 

update:

There is a pre-alpha bttv snapshot now:
	http://bytesex.org/snapshot/bttv9-20021010.tar.gz

The tarball includes the current v4l2 stuff.  Compiles, but isn't tested
otherwise yet.  Has some stuff which didn't compile simply commented out
and labeled FIXME.  Lots of other stuff also not updated/added yet (open
handling, async I/O, ...).  v4l1 compat module not fixed yet.  No
application will be able to use that out-of-the-box due to the broken
backward compatibility.  Don't even try to use that to get your daily
work done.

Current v4l2 header file is below.  Some of the stuff mentioned on the
list is merged now.

The TV standard stuff (ntsc, pal, ...) has been redone too.  It turned
out that it is quite useless to have the exact tv standard specs in a
struct -- nobody uses them.  We are back to the model to have IDs for
the TV norms, but unlike v4l1 the TV norm ID is a bitfield now. There is
a bit for every minor tv standard out there (PAL-B, PAL-G, ...).  It is
possible to combine these bits to specify a group of standards (i.e.
PAL-BGHIDK in case you don't know or don't care about the audio carrier
differences).  The current list is still subject to change, I think it
isn't complete yet.  And it should be complete to avoid the mess we had
with v4l1 because some exotic PAL variants where missing ...

A new ioctl called VIDIOC_DETECT_STD is there to ask the driver what he
thinks the current standard is.  If the tv card hardware is able to
autodetect this info can be passed to userland here.

  Gerd

Code