Video Standards

Digital Video (DV) Timings

Video devices typically support one or more different video standards or variations of standards. Each video input and output may support another set of standards. This set is reported by the std field of struct v4l2_input and struct v4l2_output returned by the VIDIOC_ENUMINPUT and VIDIOC_ENUMOUTPUT ioctl, respectively.

V4L2 defines one bit for each analog video standard currently in use worldwide, and sets aside bits for driver defined standards, e. g. hybrid standards to watch NTSC video tapes on PAL TVs and vice versa. Applications can use the predefined bits to select a particular standard, although presenting the user a menu of supported standards is preferred. To enumerate and query the attributes of the supported standards applications use the VIDIOC_ENUMSTD ioctl.

Many of the defined standards are actually just variations of a few major standards. The hardware may in fact not distinguish between them, or do so internal and switch automatically. Therefore enumerated standards also contain sets of one or more standard bits.

Assume a hypothetic tuner capable of demodulating B/PAL, G/PAL and I/PAL signals. The first enumerated standard is a set of B and G/PAL, switched automatically depending on the selected radio frequency in UHF or VHF band. Enumeration gives a "PAL-B/G" or "PAL-I" choice. Similar a Composite input may collapse standards, enumerating "PAL-B/G/H/I", "NTSC-M" and "SECAM-D/K".[6]

To query and select the standard used by the current video input or output applications call the VIDIOC_G_STD and VIDIOC_S_STD ioctl, respectively. The received standard can be sensed with the VIDIOC_QUERYSTD ioctl. Note parameter of all these ioctls is a pointer to a v4l2_std_id type (a standard set), not an index into the standard enumeration.[7] Drivers must implement all video standard ioctls when the device has one or more video inputs or outputs.

Special rules apply to USB cameras where the notion of video standards makes little sense. More generally any capture device, output devices accordingly, which is

Here the driver shall set the std field of struct v4l2_input and struct v4l2_output to zero, the VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD ioctls shall return the EINVAL error code.[8]

Example 1.5. Information about the current video standard

v4l2_std_id std_id;
struct v4l2_standard standard;

if (-1 == ioctl (fd, VIDIOC_G_STD, &std_id)) {
	/* Note when VIDIOC_ENUMSTD always returns EINVAL this
	   is no video device or it falls under the USB exception,
	   and VIDIOC_G_STD returning EINVAL is no error. */

	perror ("VIDIOC_G_STD");
	exit (EXIT_FAILURE);
}

memset (&standard, 0, sizeof (standard));
standard.index = 0;

while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) {
	if (standard.id & std_id) {
	       printf ("Current video standard: %s\n", standard.name);
	       exit (EXIT_SUCCESS);
	}

	standard.index++;
}

/* EINVAL indicates the end of the enumeration, which cannot be
   empty unless this device falls under the USB exception. */

if (errno == EINVAL || standard.index == 0) {
	perror ("VIDIOC_ENUMSTD");
	exit (EXIT_FAILURE);
}
      

Example 1.6. Listing the video standards supported by the current input

struct v4l2_input input;
struct v4l2_standard standard;

memset (&input, 0, sizeof (input));

if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) {
	perror ("VIDIOC_G_INPUT");
	exit (EXIT_FAILURE);
}

if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) {
	perror ("VIDIOC_ENUM_INPUT");
	exit (EXIT_FAILURE);
}

printf ("Current input %s supports:\n", input.name);

memset (&standard, 0, sizeof (standard));
standard.index = 0;

while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) {
	if (standard.id & input.std)
		printf ("%s\n", standard.name);

	standard.index++;
}

/* EINVAL indicates the end of the enumeration, which cannot be
   empty unless this device falls under the USB exception. */

if (errno != EINVAL || standard.index == 0) {
	perror ("VIDIOC_ENUMSTD");
	exit (EXIT_FAILURE);
}
      

Example 1.7. Selecting a new video standard

struct v4l2_input input;
v4l2_std_id std_id;

memset (&input, 0, sizeof (input));

if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) {
	perror ("VIDIOC_G_INPUT");
	exit (EXIT_FAILURE);
}

if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) {
	perror ("VIDIOC_ENUM_INPUT");
	exit (EXIT_FAILURE);
}

if (0 == (input.std & V4L2_STD_PAL_BG)) {
	fprintf (stderr, "Oops. B/G PAL is not supported.\n");
	exit (EXIT_FAILURE);
}

/* Note this is also supposed to work when only B
   or G/PAL is supported. */

std_id = V4L2_STD_PAL_BG;

if (-1 == ioctl (fd, VIDIOC_S_STD, &std_id)) {
	perror ("VIDIOC_S_STD");
	exit (EXIT_FAILURE);
}
      

Digital Video (DV) Timings

The video standards discussed so far has been dealing with Analog TV and the corresponding video timings. Today there are many more different hardware interfaces such as High Definition TV interfaces (HDMI), VGA, DVI connectors etc., that carry video signals and there is a need to extend the API to select the video timings for these interfaces. Since it is not possible to extend the v4l2_std_id due to the limited bits available, a new set of IOCTLs is added to set/get video timings at the input and output:

  • DV Presets: Digital Video (DV) presets. These are IDs representing a video timing at the input/output. Presets are pre-defined timings implemented by the hardware according to video standards. A __u32 data type is used to represent a preset unlike the bit mask that is used in v4l2_std_id allowing future extensions to support as many different presets as needed.

  • Custom DV Timings: This will allow applications to define more detailed custom video timings for the interface. This includes parameters such as width, height, polarities, frontporch, backporch etc.

To enumerate and query the attributes of DV presets supported by a device, applications use the VIDIOC_ENUM_DV_PRESETS ioctl. To get the current DV preset, applications use the VIDIOC_G_DV_PRESET ioctl and to set a preset they use the VIDIOC_S_DV_PRESET ioctl.

To set custom DV timings for the device, applications use the VIDIOC_S_DV_TIMINGS ioctl and to get current custom DV timings they use the VIDIOC_G_DV_TIMINGS ioctl.

Applications can make use of the Table A.35, “Input capabilities” and Table A.38, “Output capabilities” flags to decide what ioctls are available to set the video timings for the device.



[6] Some users are already confused by technical terms PAL, NTSC and SECAM. There is no point asking them to distinguish between B, G, D, or K when the software or hardware can do that automatically.

[7] An alternative to the current scheme is to use pointers to indices as arguments of VIDIOC_G_STD and VIDIOC_S_STD, the struct v4l2_input and struct v4l2_output std field would be a set of indices like audioset.

Indices are consistent with the rest of the API and identify the standard unambiguously. In the present scheme of things an enumerated standard is looked up by v4l2_std_id. Now the standards supported by the inputs of a device can overlap. Just assume the tuner and composite input in the example above both exist on a device. An enumeration of "PAL-B/G", "PAL-H/I" suggests a choice which does not exist. We cannot merge or omit sets, because applications would be unable to find the standards reported by VIDIOC_G_STD. That leaves separate enumerations for each input. Also selecting a standard by v4l2_std_id can be ambiguous. Advantage of this method is that applications need not identify the standard indirectly, after enumerating.

So in summary, the lookup itself is unavoidable. The difference is only whether the lookup is necessary to find an enumerated standard or to switch to a standard by v4l2_std_id.

[8] See the section called “Buffers” for a rationale. Probably even USB cameras follow some well known video standard. It might have been better to explicitly indicate elsewhere if a device cannot live up to normal expectations, instead of this exception.