This article is a continuation of the irregular lwn series on writing videodrivers for Linux.
Introductory article describes theseries and contains pointers to the previous articles. In
The last episode, we looked at how the video4linux2 API describes video formats: image sizes andthe representation of pixels within them. This article will complete thediscussion by describing the process coming
To an agreement with anapplication on an actual video format supported by the hardware.
As we saw in the previous article, there are always ways of representingimage data in memory. there is probably no video device on the marketwhich can handle all of the formats understood by the video4linuxinterface. drivers are not expected to support formats
Not understood bythe underlying hardware; in fact, using Ming format conversions within Thekernel is explicitly frowned upon. So the driver must make it possible forthe application to select a format which works with the hardware.
The first step is to simply allow the application to query the supportedformats.
Vidioc_enum_fmt IOCTL ()Is provided for thepurpose; Within the driver this command turns into a call to this callback (if a video capture device is being queried ):
int (*vidioc_enum_fmt_cap)(struct file *file, void *private_data, struct v4l2_fmtdesc *f);
This callback will ask a video capture device to describe one of itsformats. The application will pass in
V4l2_fmtdescStructure:
struct v4l2_fmtdesc {__u32 index;enum v4l2_buf_type type;__u32 flags;__u8 description[32];__u32 pixelformat;__u32 reserved[4]; };
The application will setIndexAndTypeFields.IndexIs a simple integer used to identify a format; like theother indexes used by v4l2, this one starts at zero and increases to themaximum number of formats supported. An application
Can enumerate all ofthe supported formats by incrementing the index value until the driverreturns
Einval.TypeField describes the data streamtype; it will be
V4l2_buf_type_video_captureFor a video capture (camera or tuner) device.
IfIndexCorresponds to a supported format, the driver shouldfill in the rest of the structure.
PixelformatField shouldbe the fourcc code describing the video representation andDescriptionA short textual description of the format. The onlydefined value for
FlagsField isV4l2_fmt_flag_compressed, Which indicates a compressed videoformat.
The above callback is for Video Capture Devices; it will only be calledwhen
TypeIsV4l2_buf_type_video_capture.Vidioc_enum_fmtCall will be split out into different callbacksdepending on the Type field:
/* V4L2_BUF_TYPE_VIDEO_OUTPUT */ int (*vidioc_enum_fmt_video_output)(file, private_date, f); /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ int (*vidioc_enum_fmt_overlay)(file, private_date, f); /* V4L2_BUF_TYPE_VBI_CAPTURE */ int (*vidioc_enum_fmt_vbi)(file, private_date, f); /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ */ int (*vidioc_enum_fmt_vbi_capture)(file, private_date, f); /* V4L2_BUF_TYPE_VBI_OUTPUT */ /* V4L2_BUF_TYPE_SLICED_VBI_OUTPUT */ int (*vidioc_enum_fmt_vbi_output)(file, private_date, f); /* V4L2_BUF_TYPE_VIDEO_PRIVATE */ int (*vidioc_enum_fmt_type_private)(file, private_date, f);
The argument types are the same for all of these cals. It's worth noting that drivers can support special buffer types with codesstarting
V4l2_buf_type_private, But that wowould clearlyrequire a special understanding on the application side. for the purposes of this article, we will focus on video capture and outputdevices; the other types of video devices will be examined in futureinstallments.
The application can find out how the hardware is currently configured withthe
Vidioc_g_fmtCall. The argument passed in this case isV4l2_formatStructure:
struct v4l2_format {enum v4l2_buf_type type;union{struct v4l2_pix_formatpix;struct v4l2_windowwin;struct v4l2_vbi_formatvbi;struct v4l2_sliced_vbi_formatsliced;__u8raw_data[200];} fmt; };
Once again,TypeDescribes the buffer type; the v4l2 layer willsplit this call into one of several driver callbacks depending on thattype. For Video Capture Devices, the callback is:
int (*vidioc_g_fmt_cap)(struct file *file, void *private_data, struct v4l2_format *f);
For video capture (and output) devices,PIXField of the unionis of interest. This is
V4l2_pix_formatStructure seen in theprevious installment; the driver shoshould fill in that structure with thecurrent hardware settings and return. This call shoshould not normally failunless something is seriously wrong with the hardware.
The other Callbacks are:
int (*vidioc_s_fmt_overlay)(file, private_data, f); int (*vidioc_s_fmt_video_output)(file, private_data, f); int (*vidioc_s_fmt_vbi)(file, private_data, f); int (*vidioc_s_fmt_vbi_output)(file, private_data, f); int (*vidioc_s_fmt_vbi_capture)(file, private_data, f); int (*vidioc_s_fmt_type_private)(file, private_data, f);
TheVidioc_s_fmt_video_output ()Callback uses the samePIXField in the same way as capture interfaces do.
Most applications will eventually want to configure the hardware to providea format which works for their purpose. There are two interfaces providedfor changing video formats. The first of these isVidioc_try_fmtCall, which, within a v4l2 driver,
Turns into oneof these callbacks:
int (*vidioc_try_fmt_cap)(struct file *file, void *private_data, struct v4l2_format *f); int (*vidioc_try_fmt_video_output)(struct file *file, void *private_data, struct v4l2_format *f); /* And so on for the other buffer types */
To handle this call, the driver shocould look at the requested video format and decide whetherthat format can be supported by the hardware or not. If the applicationhas requested something impossible, the driver shocould return-Einval. So, for example,
A fourcc code describing an unsupportedformat or a request for interlaced video on a progressive-only device wouldfail. on the other hand, the driver can adjust size fields to match animage size supported by the hardware; normal practice is to adjust sizesdownward
If need be. So a driver for a device which only handlesvga-resolution images wocould change
WidthAndHeightParameters accordingly and return success.
V4l2_formatStructure will be copied back to user space after the call; The drivershoshould update the structure to reflect any changed parameters so theapplication can see what it is really getting.
TheVidioc_try_fmtHandlers are optional for drivers, but omittingthis functionality is not recommended. If provided, this function iscallable at any time, even if the device is currently operating. It shoshouldNotMake any changes to
Actual hardware operating parameters; Itis just a way for the application to find out what is possible.
When the application wants to change the hardware's format for real, itdoes
Vidioc_s_fmtCall, which arrives at the driver in thisform:
int (*vidioc_s_fmt_cap)(struct file *file, void *private_data, struct v4l2_format *f); int (*vidioc_s_fmt_video_output)(struct file *file, void *private_data, struct v4l2_format *f);
UnlikeVidioc_try_fmt, This call cannot be made at arbitrarytimes. if the hardware is currently operating, or if it has streamingbuffers allocated (a topic for yet another future installment), changingthe format cocould lead to no end of mayhem. consider
What happens, forexample, if the new format is larger than the buffers which are currentlyin use. So the driver shoshould always ensure that the hardware is idle andfail the request (
-Ebusy) If not.
A format change shocould be atomic-It shocould change all of the parametersto match the request or none of them. once again, image size parameterscan be adjusted by the driver if need be. the usual form of thesecallbacks is something like this:
int my_s_fmt_cap(struct file *file, void *private, struct v4l2_format *f) {struct mydev *dev = (struct mydev *) private;int ret;if (hardware_busy(mydev)) return -EBUSY;ret = my_try_fmt_cap(file, private, f);if (ret != 0) return ret;return tweak_hardware(mydev, &f->fmt.pix); }
UsingVidioc_try_fmtHandler avoids duplication of code andgets rid of any excuse for not implementing that handler in the firstplace. If the "try" function succeeds, the resulting format is known towork and can be programmed directly into
Hardware.
There are a number of other CILS which influence how video I/O is done. future articles will look at some of them. support for setting formats isenough to enable applications to start transferring images, however, andthat is what the purpose of all this
Structure is in the end. So the nextarticle, hopefully to come after a shorter delay than happened this timearound, will get into support for reading and writing video data.