1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102 |
- <title>Common API Elements</title>
- <para>Programming a V4L2 device consists of these
- steps:</para>
- <itemizedlist>
- <listitem>
- <para>Opening the device</para>
- </listitem>
- <listitem>
- <para>Changing device properties, selecting a video and audio
- input, video standard, picture brightness a. o.</para>
- </listitem>
- <listitem>
- <para>Negotiating a data format</para>
- </listitem>
- <listitem>
- <para>Negotiating an input/output method</para>
- </listitem>
- <listitem>
- <para>The actual input/output loop</para>
- </listitem>
- <listitem>
- <para>Closing the device</para>
- </listitem>
- </itemizedlist>
- <para>In practice most steps are optional and can be executed out of
- order. It depends on the V4L2 device type, you can read about the
- details in <xref linkend="devices" />. In this chapter we will discuss
- the basic concepts applicable to all devices.</para>
- <section id="open">
- <title>Opening and Closing Devices</title>
- <section>
- <title>Device Naming</title>
- <para>V4L2 drivers are implemented as kernel modules, loaded
- manually by the system administrator or automatically when a device is
- first discovered. The driver modules plug into the "videodev" kernel
- module. It provides helper functions and a common application
- interface specified in this document.</para>
- <para>Each driver thus loaded registers one or more device nodes
- with major number 81 and a minor number between 0 and 255. Minor numbers
- are allocated dynamically unless the kernel is compiled with the kernel
- option CONFIG_VIDEO_FIXED_MINOR_RANGES. In that case minor numbers are
- allocated in ranges depending on the device node type (video, radio, etc.).</para>
- <para>Many drivers support "video_nr", "radio_nr" or "vbi_nr"
- module options to select specific video/radio/vbi node numbers. This allows
- the user to request that the device node is named e.g. /dev/video5 instead
- of leaving it to chance. When the driver supports multiple devices of the same
- type more than one device node number can be assigned, separated by commas:
- <informalexample>
- <screen>
- > modprobe mydriver video_nr=0,1 radio_nr=0,1</screen>
- </informalexample></para>
- <para>In <filename>/etc/modules.conf</filename> this may be
- written as: <informalexample>
- <screen>
- options mydriver video_nr=0,1 radio_nr=0,1
- </screen>
- </informalexample> When no device node number is given as module
- option the driver supplies a default.</para>
- <para>Normally udev will create the device nodes in /dev automatically
- for you. If udev is not installed, then you need to enable the
- CONFIG_VIDEO_FIXED_MINOR_RANGES kernel option in order to be able to correctly
- relate a minor number to a device node number. I.e., you need to be certain
- that minor number 5 maps to device node name video5. With this kernel option
- different device types have different minor number ranges. These ranges are
- listed in <xref linkend="devices" />.
- </para>
- <para>The creation of character special files (with
- <application>mknod</application>) is a privileged operation and
- devices cannot be opened by major and minor number. That means
- applications cannot <emphasis>reliable</emphasis> scan for loaded or
- installed drivers. The user must enter a device name, or the
- application can try the conventional device names.</para>
- </section>
- <section id="related">
- <title>Related Devices</title>
- <para>Devices can support several functions. For example
- video capturing, VBI capturing and radio support.</para>
- <para>The V4L2 API creates different nodes for each of these functions.</para>
- <para>The V4L2 API was designed with the idea that one device node could support
- all functions. However, in practice this never worked: this 'feature'
- was never used by applications and many drivers did not support it and if
- they did it was certainly never tested. In addition, switching a device
- node between different functions only works when using the streaming I/O
- API, not with the read()/write() API.</para>
- <para>Today each device node supports just one function.</para>
- <para>Besides video input or output the hardware may also
- support audio sampling or playback. If so, these functions are
- implemented as ALSA PCM devices with optional ALSA audio mixer
- devices.</para>
- <para>One problem with all these devices is that the V4L2 API
- makes no provisions to find these related devices. Some really
- complex devices use the Media Controller (see <xref linkend="media_controller" />)
- which can be used for this purpose. But most drivers do not use it,
- and while some code exists that uses sysfs to discover related devices
- (see libmedia_dev in the <ulink url="http://git.linuxtv.org/cgit.cgi/v4l-utils.git/">v4l-utils</ulink>
- git repository), there is no library yet that can provide a single API towards
- both Media Controller-based devices and devices that do not use the Media Controller.
- If you want to work on this please write to the linux-media mailing list: &v4l-ml;.</para>
- </section>
- <section>
- <title>Multiple Opens</title>
- <para>V4L2 devices can be opened more than once.<footnote><para>
- There are still some old and obscure drivers that have not been updated to
- allow for multiple opens. This implies that for such drivers &func-open; can
- return an &EBUSY; when the device is already in use.</para></footnote>
- When this is supported by the driver, users can for example start a
- "panel" application to change controls like brightness or audio
- volume, while another application captures video and audio. In other words, panel
- applications are comparable to an ALSA audio mixer application.
- Just opening a V4L2 device should not change the state of the device.<footnote>
- <para>Unfortunately, opening a radio device often switches the state of the
- device to radio mode in many drivers. This behavior should be fixed eventually
- as it violates the V4L2 specification.</para></footnote></para>
- <para>Once an application has allocated the memory buffers needed for
- streaming data (by calling the &VIDIOC-REQBUFS; or &VIDIOC-CREATE-BUFS; ioctls,
- or implicitly by calling the &func-read; or &func-write; functions) that
- application (filehandle) becomes the owner of the device. It is no longer
- allowed to make changes that would affect the buffer sizes (e.g. by calling
- the &VIDIOC-S-FMT; ioctl) and other applications are no longer allowed to allocate
- buffers or start or stop streaming. The &EBUSY; will be returned instead.</para>
- <para>Merely opening a V4L2 device does not grant exclusive
- access.<footnote>
- <para>Drivers could recognize the
- <constant>O_EXCL</constant> open flag. Presently this is not required,
- so applications cannot know if it really works.</para>
- </footnote> Initiating data exchange however assigns the right
- to read or write the requested type of data, and to change related
- properties, to this file descriptor. Applications can request
- additional access privileges using the priority mechanism described in
- <xref linkend="app-pri" />.</para>
- </section>
- <section>
- <title>Shared Data Streams</title>
- <para>V4L2 drivers should not support multiple applications
- reading or writing the same data stream on a device by copying
- buffers, time multiplexing or similar means. This is better handled by
- a proxy application in user space.</para>
- </section>
- <section>
- <title>Functions</title>
- <para>To open and close V4L2 devices applications use the
- &func-open; and &func-close; function, respectively. Devices are
- programmed using the &func-ioctl; function as explained in the
- following sections.</para>
- </section>
- </section>
- <section id="querycap">
- <title>Querying Capabilities</title>
- <para>Because V4L2 covers a wide variety of devices not all
- aspects of the API are equally applicable to all types of devices.
- Furthermore devices of the same type have different capabilities and
- this specification permits the omission of a few complicated and less
- important parts of the API.</para>
- <para>The &VIDIOC-QUERYCAP; ioctl is available to check if the kernel
- device is compatible with this specification, and to query the <link
- linkend="devices">functions</link> and <link linkend="io">I/O
- methods</link> supported by the device.</para>
- <para>Starting with kernel version 3.1, VIDIOC-QUERYCAP will return the
- V4L2 API version used by the driver, with generally matches the Kernel version.
- There's no need of using &VIDIOC-QUERYCAP; to check if a specific ioctl is
- supported, the V4L2 core now returns ENOTTY if a driver doesn't provide
- support for an ioctl.</para>
- <para>Other features can be queried
- by calling the respective ioctl, for example &VIDIOC-ENUMINPUT;
- to learn about the number, types and names of video connectors on the
- device. Although abstraction is a major objective of this API, the
- &VIDIOC-QUERYCAP; ioctl also allows driver specific applications to reliably identify
- the driver.</para>
- <para>All V4L2 drivers must support
- <constant>VIDIOC_QUERYCAP</constant>. Applications should always call
- this ioctl after opening the device.</para>
- </section>
- <section id="app-pri">
- <title>Application Priority</title>
- <para>When multiple applications share a device it may be
- desirable to assign them different priorities. Contrary to the
- traditional "rm -rf /" school of thought a video recording application
- could for example block other applications from changing video
- controls or switching the current TV channel. Another objective is to
- permit low priority applications working in background, which can be
- preempted by user controlled applications and automatically regain
- control of the device at a later time.</para>
- <para>Since these features cannot be implemented entirely in user
- space V4L2 defines the &VIDIOC-G-PRIORITY; and &VIDIOC-S-PRIORITY;
- ioctls to request and query the access priority associate with a file
- descriptor. Opening a device assigns a medium priority, compatible
- with earlier versions of V4L2 and drivers not supporting these ioctls.
- Applications requiring a different priority will usually call
- <constant>VIDIOC_S_PRIORITY</constant> after verifying the device with
- the &VIDIOC-QUERYCAP; ioctl.</para>
- <para>Ioctls changing driver properties, such as &VIDIOC-S-INPUT;,
- return an &EBUSY; after another application obtained higher priority.</para>
- </section>
- <section id="video">
- <title>Video Inputs and Outputs</title>
- <para>Video inputs and outputs are physical connectors of a
- device. These can be for example RF connectors (antenna/cable), CVBS
- a.k.a. Composite Video, S-Video or RGB connectors. Video and VBI
- capture devices have inputs. Video and VBI output devices have outputs,
- at least one each. Radio devices have no video inputs or outputs.</para>
- <para>To learn about the number and attributes of the
- available inputs and outputs applications can enumerate them with the
- &VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; ioctl, respectively. The
- &v4l2-input; returned by the <constant>VIDIOC_ENUMINPUT</constant>
- ioctl also contains signal status information applicable when the
- current video input is queried.</para>
- <para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctls return the
- index of the current video input or output. To select a different
- input or output applications call the &VIDIOC-S-INPUT; and
- &VIDIOC-S-OUTPUT; ioctls. Drivers must implement all the input ioctls
- when the device has one or more inputs, all the output ioctls when the
- device has one or more outputs.</para>
- <example>
- <title>Information about the current video input</title>
- <programlisting>
- &v4l2-input; input;
- int index;
- if (-1 == ioctl(fd, &VIDIOC-G-INPUT;, &index)) {
- perror("VIDIOC_G_INPUT");
- exit(EXIT_FAILURE);
- }
- memset(&input, 0, sizeof(input));
- input.index = index;
- if (-1 == ioctl(fd, &VIDIOC-ENUMINPUT;, &input)) {
- perror("VIDIOC_ENUMINPUT");
- exit(EXIT_FAILURE);
- }
- printf("Current input: %s\n", input.name);
- </programlisting>
- </example>
- <example>
- <title>Switching to the first video input</title>
- <programlisting>
- int index;
- index = 0;
- if (-1 == ioctl(fd, &VIDIOC-S-INPUT;, &index)) {
- perror("VIDIOC_S_INPUT");
- exit(EXIT_FAILURE);
- }
- </programlisting>
- </example>
- </section>
- <section id="audio">
- <title>Audio Inputs and Outputs</title>
- <para>Audio inputs and outputs are physical connectors of a
- device. Video capture devices have inputs, output devices have
- outputs, zero or more each. Radio devices have no audio inputs or
- outputs. They have exactly one tuner which in fact
- <emphasis>is</emphasis> an audio source, but this API associates
- tuners with video inputs or outputs only, and radio devices have
- none of these.<footnote>
- <para>Actually &v4l2-audio; ought to have a
- <structfield>tuner</structfield> field like &v4l2-input;, not only
- making the API more consistent but also permitting radio devices with
- multiple tuners.</para>
- </footnote> A connector on a TV card to loop back the received
- audio signal to a sound card is not considered an audio output.</para>
- <para>Audio and video inputs and outputs are associated. Selecting
- a video source also selects an audio source. This is most evident when
- the video and audio source is a tuner. Further audio connectors can
- combine with more than one video input or output. Assumed two
- composite video inputs and two audio inputs exist, there may be up to
- four valid combinations. The relation of video and audio connectors
- is defined in the <structfield>audioset</structfield> field of the
- respective &v4l2-input; or &v4l2-output;, where each bit represents
- the index number, starting at zero, of one audio input or output.</para>
- <para>To learn about the number and attributes of the
- available inputs and outputs applications can enumerate them with the
- &VIDIOC-ENUMAUDIO; and &VIDIOC-ENUMAUDOUT; ioctl, respectively. The
- &v4l2-audio; returned by the <constant>VIDIOC_ENUMAUDIO</constant> ioctl
- also contains signal status information applicable when the current
- audio input is queried.</para>
- <para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctls report
- the current audio input and output, respectively. Note that, unlike
- &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; these ioctls return a structure
- as <constant>VIDIOC_ENUMAUDIO</constant> and
- <constant>VIDIOC_ENUMAUDOUT</constant> do, not just an index.</para>
- <para>To select an audio input and change its properties
- applications call the &VIDIOC-S-AUDIO; ioctl. To select an audio
- output (which presently has no changeable properties) applications
- call the &VIDIOC-S-AUDOUT; ioctl.</para>
- <para>Drivers must implement all audio input ioctls when the device
- has multiple selectable audio inputs, all audio output ioctls when the
- device has multiple selectable audio outputs. When the device has any
- audio inputs or outputs the driver must set the <constant>V4L2_CAP_AUDIO</constant>
- flag in the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
- <example>
- <title>Information about the current audio input</title>
- <programlisting>
- &v4l2-audio; audio;
- memset(&audio, 0, sizeof(audio));
- if (-1 == ioctl(fd, &VIDIOC-G-AUDIO;, &audio)) {
- perror("VIDIOC_G_AUDIO");
- exit(EXIT_FAILURE);
- }
- printf("Current input: %s\n", audio.name);
- </programlisting>
- </example>
- <example>
- <title>Switching to the first audio input</title>
- <programlisting>
- &v4l2-audio; audio;
- memset(&audio, 0, sizeof(audio)); /* clear audio.mode, audio.reserved */
- audio.index = 0;
- if (-1 == ioctl(fd, &VIDIOC-S-AUDIO;, &audio)) {
- perror("VIDIOC_S_AUDIO");
- exit(EXIT_FAILURE);
- }
- </programlisting>
- </example>
- </section>
- <section id="tuner">
- <title>Tuners and Modulators</title>
- <section>
- <title>Tuners</title>
- <para>Video input devices can have one or more tuners
- demodulating a RF signal. Each tuner is associated with one or more
- video inputs, depending on the number of RF connectors on the tuner.
- The <structfield>type</structfield> field of the respective
- &v4l2-input; returned by the &VIDIOC-ENUMINPUT; ioctl is set to
- <constant>V4L2_INPUT_TYPE_TUNER</constant> and its
- <structfield>tuner</structfield> field contains the index number of
- the tuner.</para>
- <para>Radio input devices have exactly one tuner with index zero, no
- video inputs.</para>
- <para>To query and change tuner properties applications use the
- &VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctls, respectively. The
- &v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
- contains signal status information applicable when the tuner of the
- current video or radio input is queried. Note that
- <constant>VIDIOC_S_TUNER</constant> does not switch the current tuner,
- when there is more than one at all. The tuner is solely determined by
- the current video input. Drivers must support both ioctls and set the
- <constant>V4L2_CAP_TUNER</constant> flag in the &v4l2-capability;
- returned by the &VIDIOC-QUERYCAP; ioctl when the device has one or
- more tuners.</para>
- </section>
- <section>
- <title>Modulators</title>
- <para>Video output devices can have one or more modulators, uh,
- modulating a video signal for radiation or connection to the antenna
- input of a TV set or video recorder. Each modulator is associated with
- one or more video outputs, depending on the number of RF connectors on
- the modulator. The <structfield>type</structfield> field of the
- respective &v4l2-output; returned by the &VIDIOC-ENUMOUTPUT; ioctl is
- set to <constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> and its
- <structfield>modulator</structfield> field contains the index number
- of the modulator.</para>
- <para>Radio output devices have exactly one modulator with index
- zero, no video outputs.</para>
- <para>A video or radio device cannot support both a tuner and a
- modulator. Two separate device nodes will have to be used for such
- hardware, one that supports the tuner functionality and one that supports
- the modulator functionality. The reason is a limitation with the
- &VIDIOC-S-FREQUENCY; ioctl where you cannot specify whether the frequency
- is for a tuner or a modulator.</para>
- <para>To query and change modulator properties applications use
- the &VIDIOC-G-MODULATOR; and &VIDIOC-S-MODULATOR; ioctl. Note that
- <constant>VIDIOC_S_MODULATOR</constant> does not switch the current
- modulator, when there is more than one at all. The modulator is solely
- determined by the current video output. Drivers must support both
- ioctls and set the <constant>V4L2_CAP_MODULATOR</constant> flag in
- the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl when the
- device has one or more modulators.</para>
- </section>
- <section>
- <title>Radio Frequency</title>
- <para>To get and set the tuner or modulator radio frequency
- applications use the &VIDIOC-G-FREQUENCY; and &VIDIOC-S-FREQUENCY;
- ioctl which both take a pointer to a &v4l2-frequency;. These ioctls
- are used for TV and radio devices alike. Drivers must support both
- ioctls when the tuner or modulator ioctls are supported, or
- when the device is a radio device.</para>
- </section>
- </section>
- <section id="standard">
- <title>Video Standards</title>
- <para>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
- <structfield>std</structfield> field of &v4l2-input; and
- &v4l2-output; returned by the &VIDIOC-ENUMINPUT; and
- &VIDIOC-ENUMOUTPUT; ioctls, respectively.</para>
- <para>V4L2 defines one bit for each analog video standard
- currently in use worldwide, and sets aside bits for driver defined
- standards, ⪚ 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.</para>
- <para>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.</para>
- <para>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".<footnote>
- <para>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.</para>
- </footnote></para>
- <para>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 <emphasis>received</emphasis>
- standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note that the
- parameter of all these ioctls is a pointer to a &v4l2-std-id; type
- (a standard set), <emphasis>not</emphasis> an index into the standard
- enumeration. Drivers must implement all video standard ioctls
- when the device has one or more video inputs or outputs.</para>
- <para>Special rules apply to devices such as USB cameras where the notion of video
- standards makes little sense. More generally for any capture or output device
- which is: <itemizedlist>
- <listitem>
- <para>incapable of capturing fields or frames at the nominal
- rate of the video standard, or</para>
- </listitem>
- <listitem>
- <para>that does not support the video standard formats at all.</para>
- </listitem>
- </itemizedlist> Here the driver shall set the
- <structfield>std</structfield> field of &v4l2-input; and &v4l2-output;
- to zero and the <constant>VIDIOC_G_STD</constant>,
- <constant>VIDIOC_S_STD</constant>,
- <constant>VIDIOC_QUERYSTD</constant> and
- <constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
- &ENOTTY; or the &EINVAL;.</para>
- <para>Applications can make use of the <xref linkend="input-capabilities" /> and
- <xref linkend="output-capabilities"/> flags to determine whether the video standard ioctls
- can be used with the given input or output.</para>
- <example>
- <title>Information about the current video standard</title>
- <programlisting>
- &v4l2-std-id; std_id;
- &v4l2-standard; standard;
- if (-1 == ioctl(fd, &VIDIOC-G-STD;, &std_id)) {
- /* Note when VIDIOC_ENUMSTD always returns ENOTTY this
- is no video device or it falls under the USB exception,
- and VIDIOC_G_STD returning ENOTTY 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);
- }
- </programlisting>
- </example>
- <example>
- <title>Listing the video standards supported by the current
- input</title>
- <programlisting>
- &v4l2-input; input;
- &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);
- }
- </programlisting>
- </example>
- <example>
- <title>Selecting a new video standard</title>
- <programlisting>
- &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
- <emphasis>or</emphasis> 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);
- }
- </programlisting>
- </example>
- </section>
- <section id="dv-timings">
- <title>Digital Video (DV) Timings</title>
- <para>
- The video standards discussed so far have 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 was added to set/get video timings at
- the input and output.</para>
- <para>These ioctls deal with the detailed digital video timings that define
- each video format. This includes parameters such as the active video width and height,
- signal polarities, frontporches, backporches, sync widths etc. The <filename>linux/v4l2-dv-timings.h</filename>
- header can be used to get the timings of the formats in the <xref linkend="cea861" /> and
- <xref linkend="vesadmt" /> standards.
- </para>
- <para>To enumerate and query the attributes of the DV timings supported by a device
- applications use the &VIDIOC-ENUM-DV-TIMINGS; and &VIDIOC-DV-TIMINGS-CAP; ioctls.
- To set DV timings for the device applications use the
- &VIDIOC-S-DV-TIMINGS; ioctl and to get current DV timings they use the
- &VIDIOC-G-DV-TIMINGS; ioctl. To detect the DV timings as seen by the video receiver applications
- use the &VIDIOC-QUERY-DV-TIMINGS; ioctl.</para>
- <para>Applications can make use of the <xref linkend="input-capabilities" /> and
- <xref linkend="output-capabilities"/> flags to determine whether the digital video ioctls
- can be used with the given input or output.</para>
- </section>
- &sub-controls;
- <section id="format">
- <title>Data Formats</title>
- <section>
- <title>Data Format Negotiation</title>
- <para>Different devices exchange different kinds of data with
- applications, for example video images, raw or sliced VBI data, RDS
- datagrams. Even within one kind many different formats are possible,
- in particular an abundance of image formats. Although drivers must
- provide a default and the selection persists across closing and
- reopening a device, applications should always negotiate a data format
- before engaging in data exchange. Negotiation means the application
- asks for a particular format and the driver selects and reports the
- best the hardware can do to satisfy the request. Of course
- applications can also just query the current selection.</para>
- <para>A single mechanism exists to negotiate all data formats
- using the aggregate &v4l2-format; and the &VIDIOC-G-FMT; and
- &VIDIOC-S-FMT; ioctls. Additionally the &VIDIOC-TRY-FMT; ioctl can be
- used to examine what the hardware <emphasis>could</emphasis> do,
- without actually selecting a new data format. The data formats
- supported by the V4L2 API are covered in the respective device section
- in <xref linkend="devices" />. For a closer look at image formats see
- <xref linkend="pixfmt" />.</para>
- <para>The <constant>VIDIOC_S_FMT</constant> ioctl is a major
- turning-point in the initialization sequence. Prior to this point
- multiple panel applications can access the same device concurrently to
- select the current input, change controls or modify other properties.
- The first <constant>VIDIOC_S_FMT</constant> assigns a logical stream
- (video data, VBI data etc.) exclusively to one file descriptor.</para>
- <para>Exclusive means no other application, more precisely no
- other file descriptor, can grab this stream or change device
- properties inconsistent with the negotiated parameters. A video
- standard change for example, when the new standard uses a different
- number of scan lines, can invalidate the selected image format.
- Therefore only the file descriptor owning the stream can make
- invalidating changes. Accordingly multiple file descriptors which
- grabbed different logical streams prevent each other from interfering
- with their settings. When for example video overlay is about to start
- or already in progress, simultaneous video capturing may be restricted
- to the same cropping and image size.</para>
- <para>When applications omit the
- <constant>VIDIOC_S_FMT</constant> ioctl its locking side effects are
- implied by the next step, the selection of an I/O method with the
- &VIDIOC-REQBUFS; ioctl or implicit with the first &func-read; or
- &func-write; call.</para>
- <para>Generally only one logical stream can be assigned to a
- file descriptor, the exception being drivers permitting simultaneous
- video capturing and overlay using the same file descriptor for
- compatibility with V4L and earlier versions of V4L2. Switching the
- logical stream or returning into "panel mode" is possible by closing
- and reopening the device. Drivers <emphasis>may</emphasis> support a
- switch using <constant>VIDIOC_S_FMT</constant>.</para>
- <para>All drivers exchanging data with
- applications must support the <constant>VIDIOC_G_FMT</constant> and
- <constant>VIDIOC_S_FMT</constant> ioctl. Implementation of the
- <constant>VIDIOC_TRY_FMT</constant> is highly recommended but
- optional.</para>
- </section>
- <section>
- <title>Image Format Enumeration</title>
- <para>Apart of the generic format negotiation functions
- a special ioctl to enumerate all image formats supported by video
- capture, overlay or output devices is available.<footnote>
- <para>Enumerating formats an application has no a-priori
- knowledge of (otherwise it could explicitly ask for them and need not
- enumerate) seems useless, but there are applications serving as proxy
- between drivers and the actual video applications for which this is
- useful.</para>
- </footnote></para>
- <para>The &VIDIOC-ENUM-FMT; ioctl must be supported
- by all drivers exchanging image data with applications.</para>
- <important>
- <para>Drivers are not supposed to convert image formats in
- kernel space. They must enumerate only formats directly supported by
- the hardware. If necessary driver writers should publish an example
- conversion routine or library for integration into applications.</para>
- </important>
- </section>
- </section>
- &sub-planar-apis;
- <section id="crop">
- <title>Image Cropping, Insertion and Scaling</title>
- <para>Some video capture devices can sample a subsection of the
- picture and shrink or enlarge it to an image of arbitrary size. We
- call these abilities cropping and scaling. Some video output devices
- can scale an image up or down and insert it at an arbitrary scan line
- and horizontal offset into a video signal.</para>
- <para>Applications can use the following API to select an area in
- the video signal, query the default area and the hardware limits.
- <emphasis>Despite their name, the &VIDIOC-CROPCAP;, &VIDIOC-G-CROP;
- and &VIDIOC-S-CROP; ioctls apply to input as well as output
- devices.</emphasis></para>
- <para>Scaling requires a source and a target. On a video capture
- or overlay device the source is the video signal, and the cropping
- ioctls determine the area actually sampled. The target are images
- read by the application or overlaid onto the graphics screen. Their
- size (and position for an overlay) is negotiated with the
- &VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls.</para>
- <para>On a video output device the source are the images passed in
- by the application, and their size is again negotiated with the
- <constant>VIDIOC_G/S_FMT</constant> ioctls, or may be encoded in a
- compressed video stream. The target is the video signal, and the
- cropping ioctls determine the area where the images are
- inserted.</para>
- <para>Source and target rectangles are defined even if the device
- does not support scaling or the <constant>VIDIOC_G/S_CROP</constant>
- ioctls. Their size (and position where applicable) will be fixed in
- this case. <emphasis>All capture and output device must support the
- <constant>VIDIOC_CROPCAP</constant> ioctl such that applications can
- determine if scaling takes place.</emphasis></para>
- <section>
- <title>Cropping Structures</title>
- <figure id="crop-scale">
- <title>Image Cropping, Insertion and Scaling</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="crop.pdf" format="PS" />
- </imageobject>
- <imageobject>
- <imagedata fileref="crop.gif" format="GIF" />
- </imageobject>
- <textobject>
- <phrase>The cropping, insertion and scaling process</phrase>
- </textobject>
- </mediaobject>
- </figure>
- <para>For capture devices the coordinates of the top left
- corner, width and height of the area which can be sampled is given by
- the <structfield>bounds</structfield> substructure of the
- &v4l2-cropcap; returned by the <constant>VIDIOC_CROPCAP</constant>
- ioctl. To support a wide range of hardware this specification does not
- define an origin or units. However by convention drivers should
- horizontally count unscaled samples relative to 0H (the leading edge
- of the horizontal sync pulse, see <xref linkend="vbi-hsync" />).
- Vertically ITU-R line
- numbers of the first field (<xref linkend="vbi-525" />, <xref
- linkend="vbi-625" />), multiplied by two if the driver can capture both
- fields.</para>
- <para>The top left corner, width and height of the source
- rectangle, that is the area actually sampled, is given by &v4l2-crop;
- using the same coordinate system as &v4l2-cropcap;. Applications can
- use the <constant>VIDIOC_G_CROP</constant> and
- <constant>VIDIOC_S_CROP</constant> ioctls to get and set this
- rectangle. It must lie completely within the capture boundaries and
- the driver may further adjust the requested size and/or position
- according to hardware limitations.</para>
- <para>Each capture device has a default source rectangle, given
- by the <structfield>defrect</structfield> substructure of
- &v4l2-cropcap;. The center of this rectangle shall align with the
- center of the active picture area of the video signal, and cover what
- the driver writer considers the complete picture. Drivers shall reset
- the source rectangle to the default when the driver is first loaded,
- but not later.</para>
- <para>For output devices these structures and ioctls are used
- accordingly, defining the <emphasis>target</emphasis> rectangle where
- the images will be inserted into the video signal.</para>
- </section>
- <section>
- <title>Scaling Adjustments</title>
- <para>Video hardware can have various cropping, insertion and
- scaling limitations. It may only scale up or down, support only
- discrete scaling factors, or have different scaling abilities in
- horizontal and vertical direction. Also it may not support scaling at
- all. At the same time the &v4l2-crop; rectangle may have to be
- aligned, and both the source and target rectangles may have arbitrary
- upper and lower size limits. In particular the maximum
- <structfield>width</structfield> and <structfield>height</structfield>
- in &v4l2-crop; may be smaller than the
- &v4l2-cropcap;.<structfield>bounds</structfield> area. Therefore, as
- usual, drivers are expected to adjust the requested parameters and
- return the actual values selected.</para>
- <para>Applications can change the source or the target rectangle
- first, as they may prefer a particular image size or a certain area in
- the video signal. If the driver has to adjust both to satisfy hardware
- limitations, the last requested rectangle shall take priority, and the
- driver should preferably adjust the opposite one. The &VIDIOC-TRY-FMT;
- ioctl however shall not change the driver state and therefore only
- adjust the requested rectangle.</para>
- <para>Suppose scaling on a video capture device is restricted to
- a factor 1:1 or 2:1 in either direction and the target image size must
- be a multiple of 16 × 16 pixels. The source cropping
- rectangle is set to defaults, which are also the upper limit in this
- example, of 640 × 400 pixels at offset 0, 0. An
- application requests an image size of 300 × 225
- pixels, assuming video will be scaled down from the "full picture"
- accordingly. The driver sets the image size to the closest possible
- values 304 × 224, then chooses the cropping rectangle
- closest to the requested size, that is 608 × 224
- (224 × 2:1 would exceed the limit 400). The offset
- 0, 0 is still valid, thus unmodified. Given the default cropping
- rectangle reported by <constant>VIDIOC_CROPCAP</constant> the
- application can easily propose another offset to center the cropping
- rectangle.</para>
- <para>Now the application may insist on covering an area using a
- picture aspect ratio closer to the original request, so it asks for a
- cropping rectangle of 608 × 456 pixels. The present
- scaling factors limit cropping to 640 × 384, so the
- driver returns the cropping size 608 × 384 and adjusts
- the image size to closest possible 304 × 192.</para>
- </section>
- <section>
- <title>Examples</title>
- <para>Source and target rectangles shall remain unchanged across
- closing and reopening a device, such that piping data into or out of a
- device will work without special preparations. More advanced
- applications should ensure the parameters are suitable before starting
- I/O.</para>
- <example>
- <title>Resetting the cropping parameters</title>
- <para>(A video capture device is assumed; change
- <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> for other
- devices.)</para>
- <programlisting>
- &v4l2-cropcap; cropcap;
- &v4l2-crop; crop;
- memset (&cropcap, 0, sizeof (cropcap));
- cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &cropcap)) {
- perror ("VIDIOC_CROPCAP");
- exit (EXIT_FAILURE);
- }
- memset (&crop, 0, sizeof (crop));
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- crop.c = cropcap.defrect;
- /* Ignore if cropping is not supported (EINVAL). */
- if (-1 == ioctl (fd, &VIDIOC-S-CROP;, &crop)
- && errno != EINVAL) {
- perror ("VIDIOC_S_CROP");
- exit (EXIT_FAILURE);
- }
- </programlisting>
- </example>
- <example>
- <title>Simple downscaling</title>
- <para>(A video capture device is assumed.)</para>
- <programlisting>
- &v4l2-cropcap; cropcap;
- &v4l2-format; format;
- reset_cropping_parameters ();
- /* Scale down to 1/4 size of full picture. */
- memset (&format, 0, sizeof (format)); /* defaults */
- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- format.fmt.pix.width = cropcap.defrect.width >> 1;
- format.fmt.pix.height = cropcap.defrect.height >> 1;
- format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- if (-1 == ioctl (fd, &VIDIOC-S-FMT;, &format)) {
- perror ("VIDIOC_S_FORMAT");
- exit (EXIT_FAILURE);
- }
- /* We could check the actual image size now, the actual scaling factor
- or if the driver can scale at all. */
- </programlisting>
- </example>
- <example>
- <title>Selecting an output area</title>
- <programlisting>
- &v4l2-cropcap; cropcap;
- &v4l2-crop; crop;
- memset (&cropcap, 0, sizeof (cropcap));
- cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
- perror ("VIDIOC_CROPCAP");
- exit (EXIT_FAILURE);
- }
- memset (&crop, 0, sizeof (crop));
- crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- crop.c = cropcap.defrect;
- /* Scale the width and height to 50 % of their original size
- and center the output. */
- crop.c.width /= 2;
- crop.c.height /= 2;
- crop.c.left += crop.c.width / 2;
- crop.c.top += crop.c.height / 2;
- /* Ignore if cropping is not supported (EINVAL). */
- if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
- && errno != EINVAL) {
- perror ("VIDIOC_S_CROP");
- exit (EXIT_FAILURE);
- }
- </programlisting>
- </example>
- <example>
- <title>Current scaling factor and pixel aspect</title>
- <para>(A video capture device is assumed.)</para>
- <programlisting>
- &v4l2-cropcap; cropcap;
- &v4l2-crop; crop;
- &v4l2-format; format;
- double hscale, vscale;
- double aspect;
- int dwidth, dheight;
- memset (&cropcap, 0, sizeof (cropcap));
- cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &cropcap)) {
- perror ("VIDIOC_CROPCAP");
- exit (EXIT_FAILURE);
- }
- memset (&crop, 0, sizeof (crop));
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl (fd, &VIDIOC-G-CROP;, &crop)) {
- if (errno != EINVAL) {
- perror ("VIDIOC_G_CROP");
- exit (EXIT_FAILURE);
- }
- /* Cropping not supported. */
- crop.c = cropcap.defrect;
- }
- memset (&format, 0, sizeof (format));
- format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (-1 == ioctl (fd, &VIDIOC-G-FMT;, &format)) {
- perror ("VIDIOC_G_FMT");
- exit (EXIT_FAILURE);
- }
- /* The scaling applied by the driver. */
- hscale = format.fmt.pix.width / (double) crop.c.width;
- vscale = format.fmt.pix.height / (double) crop.c.height;
- aspect = cropcap.pixelaspect.numerator /
- (double) cropcap.pixelaspect.denominator;
- aspect = aspect * hscale / vscale;
- /* Devices following ITU-R BT.601 do not capture
- square pixels. For playback on a computer monitor
- we should scale the images to this size. */
- dwidth = format.fmt.pix.width / aspect;
- dheight = format.fmt.pix.height;
- </programlisting>
- </example>
- </section>
- </section>
- &sub-selection-api;
- <section id="streaming-par">
- <title>Streaming Parameters</title>
- <para>Streaming parameters are intended to optimize the video
- capture process as well as I/O. Presently applications can request a
- high quality capture mode with the &VIDIOC-S-PARM; ioctl.</para>
- <para>The current video standard determines a nominal number of
- frames per second. If less than this number of frames is to be
- captured or output, applications can request frame skipping or
- duplicating on the driver side. This is especially useful when using
- the &func-read; or &func-write;, which are not augmented by timestamps
- or sequence counters, and to avoid unnecessary data copying.</para>
- <para>Finally these ioctls can be used to determine the number of
- buffers used internally by a driver in read/write mode. For
- implications see the section discussing the &func-read;
- function.</para>
- <para>To get and set the streaming parameters applications call
- the &VIDIOC-G-PARM; and &VIDIOC-S-PARM; ioctl, respectively. They take
- a pointer to a &v4l2-streamparm;, which contains a union holding
- separate parameters for input and output devices.</para>
- <para>These ioctls are optional, drivers need not implement
- them. If so, they return the &EINVAL;.</para>
- </section>
|