What Makes the Linux Kernel Media API Documentation so Challenging?

This article is part of a series on improvements being made to Linux kernel documentation:

This article will begin to explain how we handled the conversion of the Linux Media subsystem documentation.

The Linux Media Subsystem

The Linux Media subsystem is actually a set of subsystems; each subsystem has its own particularities:

  • Video4Linux –  API and core provide functions for video stream capture and output. It also provides support for video codecs, analog TV, AM/FM radio receivers and transmitters and for software digital radio (SDR) receivers and transmitters.
  • Linux DVB – provides support for digital TV. Despite its name, it supports worldwide standards, including DVB, ATSC, ISDB, and CDDB, as well remote controllers and infra-red devices.
  • Media Controller – provides pipeline control and reconfiguration inside the hardware.
  • HDMI CEC – provides support for the HDMI Consumers Electronic Control (CEC): a system to pass remote controller commands and other commands to equipment connected via HDMI. This was added in Kernel 4.8.

The Media userspace API book documentation and its history

The Linux Media Infrastructure userspace API book (uAPI) describes the system calls and sysfs devices used by the media subsystem.

Before Kernel 4.7, the uAPI book was in the Kernel git tree in Docbook format. This book’s origin came from two different sources. The first, video4linux (V4L) DocBook, was originally written in 1998 and is maintained outside the Linux Kernel on the same CVS tree that was used to maintain the V4L drivers. It was later migrated to a Mercurial tree. Since both drivers and documentation were maintained together, the difference between documentation and implementation has always been small, if any.

The second is a LATEX book with the DVB version 1 API, which was written in 2003. It was converted to DocBook and added to the mercurial tree in 2009. At the time, DVB was using version 3 of the API, and as a result there was a huge gap between the LATEX documentation for API version 1 and the code implementation.

Please note that the V4L API uses a common set of system calls for all device types. This is the opposite of the DVB API design which uses a set of different APIs, one for each part of the device: frontend, network, conditional access, dvr, and mux. It also has a set of legacy APIs that are used for other device types such as audio, video, and overlay.

Also, in 2009 both DVB and V4L DocBook books were added to the Linux Kernel tree. Since this merge, we’ve been working to reduce the gaps on the DVB API side of the document. New parts of the document have since been added to cover remote controllers and the media controller API, both written directly into DocBook.

The Challenges of the uAPI documentation Conversion

All parts of the uAPI book were originally developed to benefit from full-featured tool sets (DocBook and LATEX). They also provide a comprehensive description of a complex set of API calls. The uAPI book uses several advanced features that are not used on other Kernel documentation books, including the following:

  • Long and wide tables with cell spans
  • Nested tables
  • Math symbols
  • Cross-reference links
  • Links between the documentation books and their corresponding uAPI header files (located at include/uapi/linux directory at the Kernel tree)
  • The book contains one part per media sub-system (V4L, DVB, remote controllers and media controller)
  • Some automation scripts, embedded inside the media documentation Makefile, that generate cross-references between uAPI header files and documentation, with support to report gaps between them

Sphinx already supports several of these features, but some required the addition of extensions and external parsers.

Converting the uAPI documentation

Due to its complexity, converting the uAPI book was not an easy task. Thankfully, Markus Haiser did a great job adding a new table parser extension into Sphinx called flat-table. He also wrote some conversion scripts that fixed most of the stuff, including the conversion of all nested tables into structures and submitted us the ReST output from his script as a patch. Yet, there were lots of things that required manual work to make it good enough to replace the DocBook version.

With that, the old Codec control IDs nested table were translated to the following ReST code snippet:

Generic Codec Controls
----------------------

.. _mpeg-control-id:

Codec Control IDs
^^^^^^^^^^^^^^^^^

``V4L2_CID_MPEG_CLASS (class)``
    The Codec class descriptor. Calling
    :ref:`VIDIOC_QUERYCTRL` for this control will
    return a description of this control class. This description can be
    used as the caption of a Tab page in a GUI, for example.

.. _v4l2-mpeg-stream-type:

``V4L2_CID_MPEG_STREAM_TYPE (enum v4l2_mpeg_stream_type)``
    The MPEG-1, -2 or -4 output stream type. One cannot assume anything
    here. Each hardware MPEG encoder tends to support different subsets
    of the available MPEG stream types. This control is specific to
    multiplexed MPEG streams. The currently defined stream types are:

.. flat-table::
    :header-rows:  0
    :stub-columns: 0
    -  .. row 1
       -  ``V4L2_MPEG_STREAM_TYPE_MPEG2_PS``
       -  MPEG-2 program stream
    -  .. row 2
       -  ``V4L2_MPEG_STREAM_TYPE_MPEG2_TS``
       -  MPEG-2 transport stream
    -  .. row 3
       -  ``V4L2_MPEG_STREAM_TYPE_MPEG1_SS``
       -  MPEG-1 system stream
    -  .. row 4
       -  ``V4L2_MPEG_STREAM_TYPE_MPEG2_DVD``
       -  MPEG-2 DVD-compatible stream
    -  .. row 5
       -  ``V4L2_MPEG_STREAM_TYPE_MPEG1_VCD``
       -  MPEG-1 VCD-compatible stream
    -  .. row 6
       -  ``V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD``
       -  MPEG-2 SVCD-compatible stream

Sphinx can then create the following html output:

1.10.5.1. Generic Codec Controls

 

1.10.5.1.1. Codec Control IDs

V4L2_CID_MPEG_CLASS (class)
The Codec class descriptor. Calling ioctls VIDIOC_QUERYCTRL, VIDIOC_QUERY_EXT_CTRL and VIDIOC_QUERYMENU for this control will return a description of this control class. This description can be used as the caption of a Tab page in a GUI, for example.
V4L2_CID_MPEG_STREAM_TYPE (enum v4l2_mpeg_stream_type)
The MPEG-1, -2 or -4 output stream type. One cannot assume anything here. Each hardware MPEG encoder tends to support different subsets of the available MPEG stream types. This control is specific to multiplexed MPEG streams. The currently defined stream types are:
V4L2_MPEG_STREAM_TYPE_MPEG2_PS MPEG-2 program stream
V4L2_MPEG_STREAM_TYPE_MPEG2_TS MPEG-2 transport stream
V4L2_MPEG_STREAM_TYPE_MPEG1_SS MPEG-1 system stream
V4L2_MPEG_STREAM_TYPE_MPEG2_DVD MPEG-2 DVD-compatible stream
V4L2_MPEG_STREAM_TYPE_MPEG1_VCD MPEG-1 VCD-compatible stream
V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD MPEG-2 SVCD-compatible stream

The scripts that were embedded into the Documentation/media/Makefile were converted into a Perl script (Documentation/sphinx/parse-headers.pl), and were made generic enough to generate cross references for any header file.

Author: Mauro Carvalho Chehab

Mauro is the maintainer of the Linux kernel media and EDAC subsystems and Tizen on Yocto. He's also a major contributor to the Reliability Availability and Serviceability (RAS) subsystems.