October 5, 2016 - Mauro Carvalho Chehab
What Makes the Linux Kernel Media API Documentation so Challenging?
This article is a part of a series that covers improvements that are being made to the 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/linuxdirectory 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
Codec Control IDs
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_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:
- .. row 1
- MPEG-2 program stream
- .. row 2
- MPEG-2 transport stream
- .. row 3
- MPEG-1 system stream
- .. row 4
- MPEG-2 DVD-compatible stream
- .. row 5
- MPEG-1 VCD-compatible stream
- .. row 6
- MPEG-2 SVCD-compatible stream
Sphinx can then create the following html output:
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.
About Mauro Carvalho Chehab
Mauro is the upstream maintainer of the Linux kernel media and EDAC subsystems, and also a major contributor for the Reliability Availability and Serviceability (RAS) subsystems. Mauro also maintains Tizen on Yocto packages upstream. He works for the Samsung Open Source Group since 2013. Has worked during 5 years at the Red Hat RHEL Kernel team, having broad experience in telecommunications due to his work at some of the Brazilian largest wired and wireless carriers.