Media Controller Entities Pads Links-Free Linux Device Drivers Course

PREV_LEC  |  NEXT_LEC

Media Controller Entities Pads Links

Free Linux Kernel Development Course — The graph abstraction model that describes any camera or media pipeline

free linux kernel development course media controller entities pads links free linux device drivers course free embedded systems course

In the last lecture of this free linux kernel development course we established why a graph model was needed. Now we go one level deeper into the media controller entities pads links abstraction itself, and see exactly how V4L2’s own data structures plug into it. By the end of this lecture you will be able to look at any camera SoC block diagram and describe it correctly using entities, pads, and links.

What You Will Learn

  • The precise meaning of entity, pad, and link in the media controller abstraction model
  • How a source pad differs from a sink pad, and why a pad can never be both
  • How struct media_device relates to struct v4l2_device
  • How video_device and v4l2_subdev each embed a media_entity under the hood

Prerequisites

This lecture assumes familiarity with struct v4l2_device, struct video_device, and struct v4l2_subdev from earlier lectures in this free linux device drivers course. If you haven’t covered sub-devices yet, go back to the V4L2 sub-device lecture first.

The Media Device: A Graph, Not A Driver

The media controller framework represents a piece of hardware as an oriented graph. Every node in that graph is called an entity, every connection point on a node is called a pad, and every wire between two pads is called a link. Put all of that together — every entity, every pad, every link on a chip — and you get what the framework calls a media device, exposed to user space as a single /dev/mediaX character device node.

Think of a realistic pipeline: a camera sensor feeds a MIPI receiver, which feeds an image signal processor, which finally feeds the capture buffer. Each stage is one entity. Each stage has at least one pad. Each connection between stages is one link.

Example Media Device Graph

[Sensor:source] → link → [MIPI-RX:sink|source] → link → [ISP:sink|source] → link → [Capture:sink]

Entities: The Functional Blocks

An entity is any functional unit that can produce, consume, or transform a stream of data — video, in most cases, though the model is not restricted to video. In the kernel, an entity is represented by struct media_entity, defined in include/media/media-entity.h. Crucially, drivers almost never allocate a bare media_entity on its own. Instead, it is embedded inside a higher-level structure that the rest of V4L2 already understands — either a video_device or a v4l2_subdev.

Pads: Where Data Enters And Leaves

A pad is an entity’s connection point to the outside world. Every pad is either a sink, meaning it only accepts incoming data, or a source, meaning it only produces outgoing data — never both at once. A raw camera sensor typically has a single source pad, since it only ever feeds data into the pipeline. The final capture device node, on the other hand, typically has a single sink pad, since it is the end of the line and never produces data for another entity to consume.

An intermediate block like an image scaler or an ISP usually has at least one sink pad and at least one source pad, since it both receives and re-emits a stream after transforming it.

Links: How Pads Get Wired Together

A link is a point-to-point connection between exactly one source pad and exactly one sink pad, possibly on the same entity but far more commonly across two different entities. Links can be permanently fixed by hardware design, or they can be enabled and disabled at runtime — for example, choosing whether a scaler sits in the data path or is bypassed entirely. User space discovers, queries, and in some cases modifies these links entirely through the media device, never through private driver interfaces.

How V4L2 Plugs Into This Model

At a higher level, the media controller uses struct media_device to represent what struct v4l2_device represents at the V4L2 level. In fact, v4l2_device carries a direct pointer back to its owning media device:

struct v4l2_device {
    /* ... other fields ... */
#if defined(CONFIG_MEDIA_CONTROLLER)
    struct media_device *mdev;
#endif
    /* ... other fields ... */
};

From the media controller’s point of view, every V4L2 video device node and every V4L2 sub-device is simply another entity in the graph. That’s why both struct video_device and struct v4l2_subdev embed a media_entity directly:

struct video_device {
#if defined(CONFIG_MEDIA_CONTROLLER)
    struct media_entity entity;
    struct media_intf_devnode *intf_devnode;
    struct media_pipeline pipe;
#endif
    /* ... other fields ... */
};

struct v4l2_subdev {
#if defined(CONFIG_MEDIA_CONTROLLER)
    struct media_entity entity;
#endif
    /* ... other fields ... */
};

video_device carries two extra fields that a plain sub-device doesn’t need: intf_devnode, of type struct media_intf_devnode, which gives the media controller access to the underlying character device node’s major/minor numbers, and pipe, of type struct media_pipeline, which tracks streaming-pipeline state for that video device.

A Minimal Original Driver Skeleton

Here is an original skeleton, ep_mcdemo, showing where media device initialization fits relative to everything you already know from the async lectures. We are not registering any entities yet — that comes in the next lecture — this just shows the ordering.

struct ep_mcdemo_dev {
    struct device *dev;
    struct media_device mdev;
    struct v4l2_device v4l2_dev;
    struct v4l2_async_notifier notifier;
};

static int ep_mcdemo_probe(struct platform_device *pdev)
{
    struct ep_mcdemo_dev *epm;
    int ret;

    epm = devm_kzalloc(&pdev->dev, sizeof(*epm), GFP_KERNEL);
    if (!epm)
        return -ENOMEM;

    epm->dev = &pdev->dev;

    epm->mdev.dev = &pdev->dev;
    strscpy(epm->mdev.model, "ep-mcdemo", sizeof(epm->mdev.model));
    media_device_init(&epm->mdev);

    ret = v4l2_device_register(&pdev->dev, &epm->v4l2_dev);
    if (ret)
        return ret;

    epm->v4l2_dev.mdev = &epm->mdev;

    v4l2_async_nf_init(&epm->notifier, &epm->v4l2_dev);

    /* fwnode graph parsing + notifier registration go here,
       exactly as covered in the earlier async lectures */

    return 0;
}

Notice the key new line: epm->v4l2_dev.mdev = &epm->mdev;. This is the single line that ties the two worlds together — from this point on, any entity registered against v4l2_dev automatically becomes visible in the media graph.

Common Mistakes To Avoid

  • Forgetting to set v4l2_dev.mdev — without it, sub-devices you register never show up in the media graph, and media-ctl will report an empty or missing topology.
  • Assuming a pad can act as both a sink and a source at the same time — the flags are mutually exclusive by design.
  • Confusing a link with a physical wire on the PCB — a link is a logical data-path connection between pads, not a description of chip pinout.

Best Practices

  • Give every entity a clear, descriptive name — it is exactly what user-space tools like media-ctl display, so a vague name makes debugging painful later.
  • Initialize media_device as early as possible in probe, before any sub-device registration attempts, so the mdev pointer is always valid.
  • Keep the entity/pad/link topology in your head as a real graph while designing a driver — draw it out before writing code.

Summary

The media controller abstraction model boils an entire hardware pipeline down to three ideas: entities that do work, pads that connect them, and links that wire pads together. V4L2 plugs directly into this model — every video_device and every v4l2_subdev is already carrying a media_entity inside it, and one pointer assignment (v4l2_dev.mdev) is all it takes to connect a driver’s V4L2 world to its media graph. In the next lecture of this free embedded systems course, we dig into struct media_device and struct media_entity field by field.

FAQ

Can a pad be both a sink and a source?

No. A pad is defined as exactly one or the other using the MEDIA_PAD_FL_SINK / MEDIA_PAD_FL_SOURCE flags — never both.

What character device represents the media device to user space?

A media device is exposed as /dev/mediaX, which tools like media-ctl open to enumerate entities, pads, and links.

Do all V4L2 drivers need to set v4l2_dev.mdev?

Only drivers that register with the media controller framework need to. It is what links a driver’s V4L2 device to its media graph.

What is the difference between an entity and a sub-device?

Every V4L2 sub-device embeds a media entity, but not every entity is a sub-device — a plain video_device capture node is also represented as an entity.

Is the pipe field in video_device the same as a media controller link?

No. pipe tracks streaming-pipeline state for that video device; links are the graph connections between pads, a separate concept.

Next: struct media_device and struct media_entity in depth

Continue this free linux kernel development course to see every field explained with original examples.

Next Lecture Browse Full Course

PREV_LEC  |  NEXT_LEC

Leave a Reply

Your email address will not be published. Required fields are marked *