Configure Media Pipelines With media-ctl
Take the kernel-side media controller framework from the previous lecture and drive it from the command line, one link and one pad format at a time.
Configuring media pipelines with media-ctl is the standard way Linux userspace takes control of a camera or video capture chain once the kernel driver has registered a media device. This lecture is part of our free linux device drivers course and picks up right where subdev format negotiation left off: you now have a /dev/mediaN node, and media-ctl is the tool that turns that node into an actively streaming pipeline. We will walk through every relevant flag, the exact order operations must happen in, and a full worked example against an original demo board so you can reproduce every command yourself.
What You Will Learn
- Every important media-ctl command-line flag and what it configures
- The correct four-step sequence for bringing a pipeline online
- How to read and write link descriptors between entities
- How to set pad formats across an entire pipeline in one command
- How to visualize a real pipeline topology as a graph
Prerequisites
- A registered media device (see the previous lecture on format negotiation and registration)
- The
v4l-utilspackage installed (providesmedia-ctlandv4l2-ctl) - Root or appropriate udev permissions on
/dev/mediaNand/dev/videoN
Installing media-ctl
On a Debian or Ubuntu-based root filesystem, media-ctl ships inside the v4l-utils package:
$ sudo apt install v4l-utils
$ media-ctl --version
For a Yocto or Buildroot-based embedded image, enable the v4l-utils recipe or package and make sure libmedia is included, since media-ctl links against it.
media-ctl Command Reference
media-ctl talks to the kernel through the Linux media controller API. These are the flags you will use in almost every session:
| Flag | Purpose |
|---|---|
--device <dev> | Selects the media device node, default /dev/media0 |
--entity <name> | Prints the device node associated with a named entity |
--links <list> | Configures one or more link descriptors between pads |
--set-v4l2 <list> | Sets the active format on one or more pads |
--get-v4l2 <pad> | Prints the active format currently set on a pad |
--reset | Marks every link in the graph inactive |
--print-topology / -p | Dumps the full entity/pad/link graph in text form |
--print-dot | Emits a Graphviz-compatible .dot representation of the graph |
--interactive | Opens an interactive prompt for toggling links |
The Four-Step Pipeline Configuration Sequence
- Reset every link to inactive with
media-ctl --reset - Activate the links that form your desired data path with
media-ctl --links - Push a compatible format down every pad in that path with
media-ctl --set-v4l2 - Start streaming through the terminal video node, typically with
v4l2-ctl --stream-mmap
Skipping the reset step is a common source of confusion: leftover active links from a previous session can silently route frames through the wrong entity.
Worked Example: An Original Four-Entity Pipeline
Consider a demo board exposing four entities registered by our ep_bridge driver from earlier lectures: a sensor ep_camsensor, a MIPI receiver ep_mipi_rx, an image processing block ep_proc, and its capture node ep_proc_capture. The data path is sensor → receiver → processor → capture.
Step 1 — Reset and Link
$ media-ctl --reset
$ media-ctl -l "'ep_camsensor':0 -> 'ep_mipi_rx':0[1]"
$ media-ctl -l "'ep_mipi_rx':1 -> 'ep_proc':0[1]"
$ media-ctl -l "'ep_proc':1 -> 'ep_proc_capture':0[1]"
Each descriptor follows the pattern "<entity>":<src-pad> -> "<entity>":<sink-pad>[<flags>], where the trailing 1 activates the link and a 0 would leave it inactive. All three commands can be merged into one call by comma-separating the descriptors and using -r to reset first:
$ media-ctl -r -l \
'"ep_camsensor":0->"ep_mipi_rx":0[1], \
"ep_mipi_rx":1->"ep_proc":0[1], \
"ep_proc":1->"ep_proc_capture":0[1]'
Step 2 — Set Pad Formats
$ media-ctl -V "'ep_camsensor':0 [fmt:UYVY8_2X8/1280x720]"
$ media-ctl -V "'ep_mipi_rx':0 [fmt:UYVY8_2X8/1280x720]"
$ media-ctl -V "'ep_mipi_rx':1 [fmt:UYVY8_2X8/1280x720]"
$ media-ctl -V "'ep_proc':0 [fmt:UYVY8_2X8/1280x720]"
$ media-ctl -V "'ep_proc':1 [fmt:UYVY8_2X8/1280x720]"
Or merged with -f:
$ media-ctl -f \
'"ep_camsensor":0 [UYVY8_2X8 1280x720], \
"ep_mipi_rx":0 [UYVY8_2X8 1280x720], \
"ep_mipi_rx":1 [UYVY8_2X8 1280x720], \
"ep_proc":0 [UYVY8_2X8 1280x720], \
"ep_proc":1 [UYVY8_2X8 1280x720]'
Step 3 — Verify With Topology
$ media-ctl --print-topology
Expected output (trimmed):
- entity 1: ep_camsensor (1 pad, 1 link)
pad0: Source
[fmt:UYVY8_2X8/1280×720]
-> “ep_mipi_rx”:0 [ENABLED] – entity 4: ep_mipi_rx (2 pads, 2 links) pad0: Sink “ep_proc”:0 [ENABLED] – entity 7: ep_proc (2 pads, 2 links) pad0: Sink “ep_proc_capture”:0 [ENABLED] – entity 9: ep_proc_capture (1 pad, 1 link) pad0: Sink <- “ep_proc”:1 [ENABLED]
Configured Pipeline Data Path
[ep_camsensor] → [ep_mipi_rx] → [ep_proc] → [ep_proc_capture] → /dev/video0
Visualizing the Graph
For pipelines with many optional routes, a text dump is hard to read. media-ctl can export a Graphviz description you can render as an image:
$ media-ctl --print-dot > pipeline.dot
$ dot -Tpng pipeline.dot > pipeline.png
In the resulting graph, solid lines represent links that are currently active, while dashed lines represent links that exist in hardware but are not currently selected — useful when an entity such as a mux has more than one possible source.
Common Mistakes and Troubleshooting
- Forgetting to reset first: stale active links from a previous configuration can route data through an unexpected entity.
- Setting formats before links: some drivers propagate format constraints along active links, so configuring links first avoids rejected format requests.
- Mismatched formats across a link: the source pad and sink pad on either end of a link should normally carry an identical format; a mismatch usually means
--set-v4l2was only applied to one side. - Using the wrong media device: on boards with more than one media device, always confirm you’re targeting the right one with
--device /dev/mediaN.
Best Practices
- Script your configuration sequence so it is reproducible across reboots
- Always verify with
--print-topologybefore starting a capture - Keep pad format strings consistent end to end unless an entity intentionally converts formats
- Use
--print-dotduring bring-up on boards with complex, multi-path topologies
Real-World Use Case
Board bring-up engineers typically wrap the exact sequence shown above into a shell script that runs once at boot, right before a GStreamer or V4L2 application opens the capture node. This decouples pipeline routing from the application itself — the same camera application can run unmodified on two different boards as long as each board ships its own media-ctl configuration script for its own topology.
Summary and Key Takeaways
- media-ctl is the standard userspace tool for configuring V4L2 media controller pipelines
- The correct order is reset, link, format, then stream
--print-topologyand--print-dotare essential verification tools- Format strings must match across both ends of every active link
Conclusion
With media-ctl, the abstract entity/pad/link model from the kernel side of the media controller framework becomes something you can drive interactively from a shell prompt. Once you are comfortable resetting, linking, and formatting a pipeline by hand, the next lecture in this free linux kernel development course walks through a complete, simpler real-world case study — a single mux feeding a CSI capture interface — end to end.
Frequently Asked Questions
Where does media-ctl come from?
It ships in the v4l-utils package, the same package that provides v4l2-ctl and other Video4Linux2 userspace tools.
What does the trailing [1] mean in a link descriptor?
It is the link flag. A value of 1 activates the link; 0 leaves it inactive. Only one source can normally feed a given sink pad at a time.
Can I configure links and formats in a single command?
Yes, media-ctl -l and media-ctl -f both accept comma-separated lists so an entire pipeline can be configured in one invocation each.
Why does –print-topology show both solid and dashed connections in the dot output?
Solid lines are active links currently carrying data; dashed lines are inactive but physically possible connections, common on entities like video muxes with multiple inputs.
Do I need root privileges to run media-ctl?
You need read/write access to the target /dev/mediaN node, which on most distributions requires root or membership in the appropriate udev group.
What happens if I set a format the hardware doesn’t support?
The driver clamps the request to the nearest supported value and media-ctl reports back the format that was actually applied, not an error.
Practice media-ctl on Your Own Board
Continue this free linux device drivers course with a complete single-mux pipeline case study in the next lecture.
Next Lecture Browse Full Course Index