123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200 |
- <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 opened. 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. Assigning
- minor numbers to V4L2 devices is entirely up to the system administrator,
- this is primarily intended to solve conflicts between devices.<footnote>
- <para>Access permissions are associated with character
- device special files, hence we must ensure device numbers cannot
- change with the module load order. To this end minor numbers are no
- longer automatically assigned by the "videodev" module as in V4L but
- requested by the driver. The defaults will suffice for most people
- unless two drivers compete for the same minor numbers.</para>
- </footnote> The module options to select minor numbers are named
- after the device special file with a "_nr" suffix. For example "video_nr"
- for <filename>/dev/video</filename> video capture devices. The number is
- an offset to the base minor number associated with the device type.
- <footnote>
- <para>In earlier versions of the V4L2 API the module options
- where named after the device special file with a "unit_" prefix, expressing
- the minor number itself, not an offset. Rationale for this change is unknown.
- Lastly the naming and semantics are just a convention among driver writers,
- the point to note is that minor numbers are not supposed to be hardcoded
- into drivers.</para>
- </footnote> When the driver supports multiple devices of the same
- type more than one minor number can be assigned, separated by commas:
- <informalexample>
- <screen>
- > insmod mydriver.o 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>
- alias char-major-81-0 mydriver
- alias char-major-81-1 mydriver
- alias char-major-81-64 mydriver <co id="alias" />
- options mydriver video_nr=0,1 radio_nr=0,1 <co id="options" />
- </screen>
- <calloutlist>
- <callout arearefs="alias">
- <para>When an application attempts to open a device
- special file with major number 81 and minor number 0, 1, or 64, load
- "mydriver" (and the "videodev" module it depends upon).</para>
- </callout>
- <callout arearefs="options">
- <para>Register the first two video capture devices with
- minor number 0 and 1 (base number is 0), the first two radio device
- with minor number 64 and 65 (base 64).</para>
- </callout>
- </calloutlist>
- </informalexample> When no minor number is given as module
- option the driver supplies a default. <xref linkend="devices" />
- recommends the base minor numbers to be used for the various device
- types. Obviously minor numbers must be unique. When the number is
- already in use the <emphasis>offending device</emphasis> will not be
- registered. <!-- Blessed by Linus Torvalds on
- linux-kernel@vger.kernel.org, 2002-11-20. --></para>
- <para>By convention system administrators create various
- character device special files with these major and minor numbers in
- the <filename>/dev</filename> directory. The names recommended for the
- different V4L2 device types 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>
- <para>Under the device filesystem (devfs) the minor number
- options are ignored. V4L2 drivers (or by proxy the "videodev" module)
- automatically create the required device files in the
- <filename>/dev/v4l</filename> directory using the conventional device
- names above.</para>
- </section>
- <section id="related">
- <title>Related Devices</title>
- <para>Devices can support several related functions. For example
- video capturing, video overlay and VBI capturing are related because
- these functions share, amongst other, the same video input and tuner
- frequency. V4L and earlier versions of V4L2 used the same device name
- and minor number for video capturing and overlay, but different ones
- for VBI. Experience showed this approach has several problems<footnote>
- <para>Given a device file name one cannot reliable find
- related devices. For once names are arbitrary and in a system with
- multiple devices, where only some support VBI capturing, a
- <filename>/dev/video2</filename> is not necessarily related to
- <filename>/dev/vbi2</filename>. The V4L
- <constant>VIDIOCGUNIT</constant> ioctl would require a search for a
- device file with a particular major and minor number.</para>
- </footnote>, and to make things worse the V4L videodev module
- used to prohibit multiple opens of a device.</para>
- <para>As a remedy the present version of the V4L2 API relaxed the
- concept of device types with specific names and minor numbers. For
- compatibility with old applications drivers must still register different
- minor numbers to assign a default function to the device. But if related
- functions are supported by the driver they must be available under all
- registered minor numbers. The desired function can be selected after
- opening the device as described in <xref linkend="devices" />.</para>
- <para>Imagine a driver supporting video capturing, video
- overlay, raw VBI capturing, and FM radio reception. It registers three
- devices with minor number 0, 64 and 224 (this numbering scheme is
- inherited from the V4L API). Regardless if
- <filename>/dev/video</filename> (81, 0) or
- <filename>/dev/vbi</filename> (81, 224) is opened the application can
- select any one of the video capturing, overlay or VBI capturing
- functions. Without programming (e. g. reading from the device
- with <application>dd</application> or <application>cat</application>)
- <filename>/dev/video</filename> captures video images, while
- <filename>/dev/vbi</filename> captures raw VBI data.
- <filename>/dev/radio</filename> (81, 64) is invariable a radio device,
- unrelated to the video functions. Being unrelated does not imply the
- devices can be used at the same time, however. The &func-open;
- function may very well return an &EBUSY;.</para>
- <para>Besides video input or output the hardware may also
- support audio sampling or playback. If so, these functions are
- implemented as OSS or ALSA PCM devices and eventually OSS or ALSA
- audio mixer. The V4L2 API makes no provisions yet to find these
- related devices. If you have an idea please write to the linux-media
- mailing list: &v4l-ml;.</para>
- </section>
- <section>
- <title>Multiple Opens</title>
- <para>In general, V4L2 devices can be opened more than once.
- 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 OSS or ALSA audio mixer application.
- When a device supports multiple functions like capturing and overlay
- <emphasis>simultaneously</emphasis>, multiple opens allow concurrent
- use of the device by forked processes or specialized applications.</para>
- <para>Multiple opens are optional, although drivers should
- permit at least concurrent accesses without data exchange, &ie; panel
- applications. This implies &func-open; can return an &EBUSY; when the
- device is already in use, as well as &func-ioctl; functions initiating
- data exchange (namely the &VIDIOC-S-FMT; ioctl), and the &func-read;
- and &func-write; functions.</para>
- <para>Mere 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. When the driver supports stream
- sharing anyway it must be implemented transparently. The V4L2 API does
- not specify how conflicts are solved. <!-- For example O_EXCL when the
- application does not want to be preempted, PROT_READ mmapped buffers
- which can be mapped twice, what happens when image formats do not
- match etc.--></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 an specific ioctl is
- supported, the V4L2 core now returns ENOIOCTLCMD 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
- ioctl also allows driver specific applications to reliable 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.
- An event mechanism to notify applications about asynchronous property
- changes has been proposed but not added yet.</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. Only video and VBI
- capture devices have inputs, 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; ioctl 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; ioctl. 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>
- <!--
- <figure id=io-tree>
- <title>Input and output enumeration is the root of most device properties.</title>
- <mediaobject>
- <imageobject>
- <imagedata fileref="links.pdf" format="ps" />
- </imageobject>
- <imageobject>
- <imagedata fileref="links.gif" format="gif" />
- </imageobject>
- <textobject>
- <phrase>Links between various device property structures.</phrase>
- </textobject>
- </mediaobject>
- </figure>
- -->
- <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; ioctl 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 input ioctls when the device
- has one or more inputs, all output ioctls when the device has one
- or more 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 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; ioctl, respectively. The
- &v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
- contains signal status information applicable when the tuner of the
- current video input, or a radio tuner 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. This specification does not define radio output
- devices.</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; ioctl, 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 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.<footnote>
- <para>An alternative to the current scheme is to use pointers
- to indices as arguments of <constant>VIDIOC_G_STD</constant> and
- <constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
- &v4l2-output; <structfield>std</structfield> field would be a set of
- indices like <structfield>audioset</structfield>.</para>
- <para>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
- <constant>VIDIOC_G_STD</constant>. 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.</para><para>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;.</para>
- </footnote> Drivers must implement all video standard ioctls
- when the device has one or more video inputs or outputs.</para>
- <para>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 <itemizedlist>
- <listitem>
- <para>incapable of capturing fields or frames at the nominal
- rate of the video standard, or</para>
- </listitem>
- <listitem>
- <para>where <link linkend="buffer">timestamps</link> refer
- to the instant the field or frame was received by the driver, not the
- capture time, or</para>
- </listitem>
- <listitem>
- <para>where <link linkend="buffer">sequence numbers</link>
- refer to the frames received by the driver, not the captured
- frames.</para>
- </listitem>
- </itemizedlist> Here the driver shall set the
- <structfield>std</structfield> field of &v4l2-input; and &v4l2-output;
- to zero, the <constant>VIDIOC_G_STD</constant>,
- <constant>VIDIOC_S_STD</constant>,
- <constant>VIDIOC_QUERYSTD</constant> and
- <constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
- &EINVAL;.<footnote>
- <para>See <xref linkend="buffer" /> 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.</para>
- </footnote></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 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);
- }
- </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 id="dv-timings">
- <title>Digital Video (DV) Timings</title>
- <para>
- 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: </para><itemizedlist>
- <listitem>
- <para>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.</para>
- </listitem>
- <listitem>
- <para>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.
- </para>
- </listitem>
- </itemizedlist>
- <para>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.</para>
- <para>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.</para>
- <para>Applications can make use of the <xref linkend="input-capabilities" /> and
- <xref linkend="output-capabilities"/> flags to decide what ioctls are available to set the
- video timings for the device.</para>
- </section>
- </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>
|