123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- Media Controller devices
- ------------------------
- Media Controller
- ~~~~~~~~~~~~~~~~
- The media controller userspace API is documented in
- :ref:`the Media Controller uAPI book <media_controller>`. This document focus
- on the kernel-side implementation of the media framework.
- Abstract media device model
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Discovering a device internal topology, and configuring it at runtime, is one
- of the goals of the media framework. To achieve this, hardware devices are
- modelled as an oriented graph of building blocks called entities connected
- through pads.
- An entity is a basic media hardware building block. It can correspond to
- a large variety of logical blocks such as physical hardware devices
- (CMOS sensor for instance), logical hardware devices (a building block
- in a System-on-Chip image processing pipeline), DMA channels or physical
- connectors.
- A pad is a connection endpoint through which an entity can interact with
- other entities. Data (not restricted to video) produced by an entity
- flows from the entity's output to one or more entity inputs. Pads should
- not be confused with physical pins at chip boundaries.
- A link is a point-to-point oriented connection between two pads, either
- on the same entity or on different entities. Data flows from a source
- pad to a sink pad.
- Media device
- ^^^^^^^^^^^^
- A media device is represented by a struct :c:type:`media_device`
- instance, defined in ``include/media/media-device.h``.
- Allocation of the structure is handled by the media device driver, usually by
- embedding the :c:type:`media_device` instance in a larger driver-specific
- structure.
- Drivers register media device instances by calling
- :c:func:`__media_device_register()` via the macro ``media_device_register()``
- and unregistered by calling :c:func:`media_device_unregister()`.
- Entities
- ^^^^^^^^
- Entities are represented by a struct :c:type:`media_entity`
- instance, defined in ``include/media/media-entity.h``. The structure is usually
- embedded into a higher-level structure, such as
- :c:type:`v4l2_subdev` or :c:type:`video_device`
- instances, although drivers can allocate entities directly.
- Drivers initialize entity pads by calling
- :c:func:`media_entity_pads_init()`.
- Drivers register entities with a media device by calling
- :c:func:`media_device_register_entity()`
- and unregistred by calling
- :c:func:`media_device_unregister_entity()`.
- Interfaces
- ^^^^^^^^^^
- Interfaces are represented by a
- struct :c:type:`media_interface` instance, defined in
- ``include/media/media-entity.h``. Currently, only one type of interface is
- defined: a device node. Such interfaces are represented by a
- struct :c:type:`media_intf_devnode`.
- Drivers initialize and create device node interfaces by calling
- :c:func:`media_devnode_create()`
- and remove them by calling:
- :c:func:`media_devnode_remove()`.
- Pads
- ^^^^
- Pads are represented by a struct :c:type:`media_pad` instance,
- defined in ``include/media/media-entity.h``. Each entity stores its pads in
- a pads array managed by the entity driver. Drivers usually embed the array in
- a driver-specific structure.
- Pads are identified by their entity and their 0-based index in the pads
- array.
- Both information are stored in the struct :c:type:`media_pad`,
- making the struct :c:type:`media_pad` pointer the canonical way
- to store and pass link references.
- Pads have flags that describe the pad capabilities and state.
- ``MEDIA_PAD_FL_SINK`` indicates that the pad supports sinking data.
- ``MEDIA_PAD_FL_SOURCE`` indicates that the pad supports sourcing data.
- .. note::
- One and only one of ``MEDIA_PAD_FL_SINK`` or ``MEDIA_PAD_FL_SOURCE`` must
- be set for each pad.
- Links
- ^^^^^
- Links are represented by a struct :c:type:`media_link` instance,
- defined in ``include/media/media-entity.h``. There are two types of links:
- **1. pad to pad links**:
- Associate two entities via their PADs. Each entity has a list that points
- to all links originating at or targeting any of its pads.
- A given link is thus stored twice, once in the source entity and once in
- the target entity.
- Drivers create pad to pad links by calling:
- :c:func:`media_create_pad_link()` and remove with
- :c:func:`media_entity_remove_links()`.
- **2. interface to entity links**:
- Associate one interface to a Link.
- Drivers create interface to entity links by calling:
- :c:func:`media_create_intf_link()` and remove with
- :c:func:`media_remove_intf_links()`.
- .. note::
- Links can only be created after having both ends already created.
- Links have flags that describe the link capabilities and state. The
- valid values are described at :c:func:`media_create_pad_link()` and
- :c:func:`media_create_intf_link()`.
- Graph traversal
- ^^^^^^^^^^^^^^^
- The media framework provides APIs to iterate over entities in a graph.
- To iterate over all entities belonging to a media device, drivers can use
- the media_device_for_each_entity macro, defined in
- ``include/media/media-device.h``.
- .. code-block:: c
- struct media_entity *entity;
- media_device_for_each_entity(entity, mdev) {
- // entity will point to each entity in turn
- ...
- }
- Drivers might also need to iterate over all entities in a graph that can be
- reached only through enabled links starting at a given entity. The media
- framework provides a depth-first graph traversal API for that purpose.
- .. note::
- Graphs with cycles (whether directed or undirected) are **NOT**
- supported by the graph traversal API. To prevent infinite loops, the graph
- traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``,
- currently defined as 16.
- Drivers initiate a graph traversal by calling
- :c:func:`media_entity_graph_walk_start()`
- The graph structure, provided by the caller, is initialized to start graph
- traversal at the given entity.
- Drivers can then retrieve the next entity by calling
- :c:func:`media_entity_graph_walk_next()`
- When the graph traversal is complete the function will return ``NULL``.
- Graph traversal can be interrupted at any moment. No cleanup function call
- is required and the graph structure can be freed normally.
- Helper functions can be used to find a link between two given pads, or a pad
- connected to another pad through an enabled link
- :c:func:`media_entity_find_link()` and
- :c:func:`media_entity_remote_pad()`.
- Use count and power handling
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Due to the wide differences between drivers regarding power management
- needs, the media controller does not implement power management. However,
- the struct :c:type:`media_entity` includes a ``use_count``
- field that media drivers
- can use to track the number of users of every entity for power management
- needs.
- The :c:type:`media_entity<media_entity>`.\ ``use_count`` field is owned by
- media drivers and must not be
- touched by entity drivers. Access to the field must be protected by the
- :c:type:`media_device`.\ ``graph_mutex`` lock.
- Links setup
- ^^^^^^^^^^^
- Link properties can be modified at runtime by calling
- :c:func:`media_entity_setup_link()`.
- Pipelines and media streams
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- When starting streaming, drivers must notify all entities in the pipeline to
- prevent link states from being modified during streaming by calling
- :c:func:`media_entity_pipeline_start()`.
- The function will mark all entities connected to the given entity through
- enabled links, either directly or indirectly, as streaming.
- The struct :c:type:`media_pipeline` instance pointed to by
- the pipe argument will be stored in every entity in the pipeline.
- Drivers should embed the struct :c:type:`media_pipeline`
- in higher-level pipeline structures and can then access the
- pipeline through the struct :c:type:`media_entity`
- pipe field.
- Calls to :c:func:`media_entity_pipeline_start()` can be nested.
- The pipeline pointer must be identical for all nested calls to the function.
- :c:func:`media_entity_pipeline_start()` may return an error. In that case,
- it will clean up any of the changes it did by itself.
- When stopping the stream, drivers must notify the entities with
- :c:func:`media_entity_pipeline_stop()`.
- If multiple calls to :c:func:`media_entity_pipeline_start()` have been
- made the same number of :c:func:`media_entity_pipeline_stop()` calls
- are required to stop streaming.
- The :c:type:`media_entity`.\ ``pipe`` field is reset to ``NULL`` on the last
- nested stop call.
- Link configuration will fail with ``-EBUSY`` by default if either end of the
- link is a streaming entity. Links that can be modified while streaming must
- be marked with the ``MEDIA_LNK_FL_DYNAMIC`` flag.
- If other operations need to be disallowed on streaming entities (such as
- changing entities configuration parameters) drivers can explicitly check the
- media_entity stream_count field to find out if an entity is streaming. This
- operation must be done with the media_device graph_mutex held.
- Link validation
- ^^^^^^^^^^^^^^^
- Link validation is performed by :c:func:`media_entity_pipeline_start()`
- for any entity which has sink pads in the pipeline. The
- :c:type:`media_entity`.\ ``link_validate()`` callback is used for that
- purpose. In ``link_validate()`` callback, entity driver should check
- that the properties of the source pad of the connected entity and its own
- sink pad match. It is up to the type of the entity (and in the end, the
- properties of the hardware) what matching actually means.
- Subsystems should facilitate link validation by providing subsystem specific
- helper functions to provide easy access for commonly needed information, and
- in the end provide a way to use driver-specific callbacks.
- .. kernel-doc:: include/media/media-device.h
- .. kernel-doc:: include/media/media-devnode.h
- .. kernel-doc:: include/media/media-entity.h
|