blob: 090f6a00043f75f10dba4be7457d0c2fb5e8215a [file] [log] [blame] [view] [edit]
V4L2 media-ctl toolkit
======================
The V4L2 media-ctl toolkit, or simply `mctk`, is a collection of routines to
capture, manipulate, and restore the state of a Video4Linux2 "media controller"
and all of its related devices, within the framework/API of V4L2.
In-memory models of media-ctl devices and sub-devices
-----------------------------------------------------
By design, the tool works primarily on an in-memory representation of a
tree of a media-ctl device and its subnodes, hereforth called a "model".
Secondarily, it may also send any changes to this model back to real
devices, accessible via /dev/*.
There is always only one "active" media-ctl tree/model being updated/worked on.
Whether updates are sent to the kernel depends on the origin of the active
model:
1) If the model was loaded from a real /dev/mediaX device, then the tool
will keep all its file descriptors to the associated devices open, and
changes to the model will be propagated to the kernel.
NOTE: The tool does not refresh its model with new kernel values after
setting a value in the kernel. That is, an `*_S_*` ioctl() is NOT
followed by one or more `*_G_*` ioctl()s. It is up to the user to
know about any intricacies of the V4L2 device being manipulated.
2) If the model was loaded from a dump file, then any changes will be
reflected only in memory.
In both cases, the final state of the memory model can be dumped to a new file.
Processing order
----------------
The parameters to this toolkit are processed sequentially, in the order they
are given on the command line. In effect, they form a "script" to be executed.
The idea is that
# ./mctk --action1 paramX --action2 --action3 paramY
will first do action 1 with parameter X, then action 2 which does not take
a parameter, and finally action 3, which takes parameter Y.
Load
----
A load action is always the first.
It opens either a kernel device or a dump file, and creates an in-memory
model of a media-ctl device. All further operations will be executed on
this in-memory model.
If the model has been loaded from a kernel device, then actions will ALSO
be fed back to the kernel, via appropriate ioctl()s.
If the model has been loaded from a file, then that file will not be modified.
Please use the dump action to write the modified state to a new file.
If a new load action follows a previous one, then the tool will abort.
### Usage
The following command opens a real media-ctl device for processing,
and then quits without performing any action on it:
# ./mctk --load-device /dev/media0
The following command does the same, but takes a bus_info string instead.
The tool will iterate over all /dev/media* devices until it finds one
with the given bus_info string in its `struct media_device_info`.
# ./mctk --load-by-businfo usb-0000:04:00.3-1
The following command opens a virtual media-ctl device from a YAML dump,
and then quits without performing any action on the resulting model:
# ./mctk --load-yaml dump.yaml
Dump
----
Internally known as "Tool-1".
The currently active model is serialised to a file.
### Usage
The following command line prints a YAML formatted dump of /dev/media0
and its child nodes to stdout:
# ./mctk --load-device /dev/media0 --dump-yaml /proc/self/fd/1
Merge
-----
Internally known as "Tool-3".
A (part of a) serialised state is read and applied to the currently active
in-memory model. If the active model is a kernel device, then the configuration
is also sent to the hardware (minus quirks in the driver/hardware that make the
restoration work less than 100% - it is up to the user to know these details).
If the input file to the merge action contains a remap section, then the
entities to be modified in the active model are identified by names rather
than by entity ID number.
### Usage
The following command line opens a real media-ctl device, disables all links
where possible, and then applies a configuration from a YAML file:
# ./mctk --load-device /dev/media0 --reset-links --merge-yaml config.yaml
### Restrictions and assumptions
#### Existence and reordering
During a merge, it is assumed that the entities, pads, links, properties,
controls, etc. being configured actually exist in the target, and that the
identifiers (id, name, index, etc.) refer to the same things as when the
configuration file was created.
For example, if "CSI 0" and "CSI 1" refer to the front and back camera,
respectively, and then a driver update swaps these two numbers, then the
tool will be unable to detect this, and blindly attempt to apply one
camera's configuration to the other.
It is ultimately up to the user to ensure that the intended semantics of
a configuration file match the device being configured.
##### Remapping
In addition to the `media_ctl` node, configuration files to be merged may
contain a `remap_entity_by_name` node.
This node lists tuples of numerical entity IDs, and for each an associated
entity name, and/or a regular expression to match an entity name.
For example:
```
remap_entity_by_name:
- id: 8
name: Extension 3
- id: 11
name: Processing 2
- id: 14
name: Camera 1
```
When merging, configuration changes mentioning any entity ID that is listed
in `remap_entity_by_name` will instead apply to an entity with the name
mentioned in `remap_entity_by_name`. In the above example, any mention of
entity ID 8, be it in V4L properties or in links, will be replaced with the
ID of an entity in the target that has the name `Extension 3`.
In some media-ctl targets, entity names may change slightly between reboots
or kernel updates. In this case, config files may be manually extended by a
regular expression to match the entity name:
```
remap_entity_by_name:
- id: 11
name_regex: Processing [0-9]
```
In this case, a target node called "Processing X", where X is a single
digit, will be used as a substitute for ID 11.
If a remap entry contains both a `name` and a `name_regex`, `mctk` will
attempt to match by exact `name` first, and by `name_regex` second.
A remap entry with neither a `name` or a `name_regex` is invalid and `mctk`
will abort.
If an entity ID is mentioned in the remap table, then the remapping must
succeed. For example, if ID 11 is remapped to the name `Processing 2`, then
the target media-ctl MUST contain an entity named `Processing 2`. There is
no fall-back to applying the changes to entity 11, that is, matching by ID,
once an entity is listed in the remap table.
##### Examples
If e.g. a control being configured is absent, then the tool may
either skip updating the control in question, or abort.
If e.g. an integer control is to be assigned a string, then the tool may
either skip updating the parameter in question, or abort.
But if there has simply been a reordering between otherwise identical
entities, and both have the same controls, then the tool cannot detect
this and will blindly update the controls.
#### Configuration order
V4L2 drivers are not configured atomically.
Changing one value can result in a driver updating other values, too.
The tool will blindly configure parameters in the order in which they
are listed in the configuration file. If the V4L2 device is not in the
desired state afterwards, then a deeper understanding of the driver is
needed, and a manual reordering of configuration steps is required.
To this end, an entity may be named multiple times in a configuration
file, allowing parameters to be set in a specific order (and even
multiple times).
Autorouter
----------
NOTE: Unfinished old code and outdated documentation!
This tool attempts to detect sensors and route them to viable
outputs on the specified V4L media controller device.
### Usage
# ./mctk --load-device /dev/media0 --reset-links --auto-route
Resetting links.
Autorouting sensors.
SetSelection: ioctl(VIDIOC_SUBDEV_S_SELECTION): Inappropriate ioctl for device
SetSelection: ioctl(VIDIOC_SUBDEV_S_SELECTION): Inappropriate ioctl for device
SetSelection: ioctl(VIDIOC_SUBDEV_S_SELECTION): Inappropriate ioctl for device
SetSelection: ioctl(VIDIOC_SUBDEV_S_SELECTION): Invalid argument
SetFmtVideoCapture: ioctl(VIDIOC_S_FMT): Invalid argument
SetSelection: ioctl(VIDIOC_S_SELECTION): Inappropriate ioctl for device
Routed: /dev/video8 = ov8856 13-0036
# yavta -c /dev/video8
[ ... capture follows ... ]
NOTE: The above error messages are benign - the autorouter attempts to
set properties, whether they are supported or not.
### How this works
1. The tool requests the entire topology of entities and links exposed
by the media controller via MEDIA_IOC_ENUM_ENTITIES and
MEDIA_IOC_ENUM_LINKS.
2. It disables all links between entities.
3. It picks the entities marked as MEDIA_ENT_T_V4L2_SUBDEV_SENSOR, and
for each one, tries to find a path from one of their output pads to
a /dev/videoX device.
It recurses through the tree of links in a DFS fashion, writing down
a path successfully found.
If a device name matches one of a few known patterns, it is ignored
as a routing hop - see v4l_mc_hack_is_ipu6_ignored_entity().
4. It enables the links along each path found.
5. It reads the sensor's picture format, and attempts to set the same
format on each device along the path.
For the final V4L /dev/videoX device, it takes a guess at the format,
but only Bayer raw formats are currently translated.
6. It also sets each V4L selection, using two strategies (to allow for
drivers that support one or the other).
7. It disables IPU6 image compression on any /dev/videoX device enabled
in this process, in case it supports this feature.
### Restrictions and assumptions
Units that are already connected to something are ignored in any further
routing. That is, if there are multiple sensors, then multiple paths will
be generated, but they will never cross by using an entity twice.
It is assumed that DFS routing can result in valid paths for all sensors.
If sensor 0 can only be assigned to outputs {0,1} and sensor 1 can only
be assigned to output 0, then routing the second sensor will fail because
its only viable output will already be in use by sensor 0.
Miscellaneous design decisions
------------------------------
### Thread safety
This program is written with the assumption that it is run single-threaded.