Run the GStreamer 1.0 Demo Application With VPU Support on Torizon OS
Introduction
This article describes how to run the Toradex GStreamer 1.0 demo application that uses the Video Processing Unit for hardware-accelerated H.264 encoding and decoding on i.MX 8-based modules running Torizon OS.
Video Processing Unit (VPU)
The VPU is a dedicated hardware block that encodes and decodes video without loading the Arm Cortex-A cores. On i.MX 8-based modules, GStreamer reaches the VPU through one of two video processing backends, Hantro or Amphion, depending on the System on Chip (SoC). Because each backend exposes its own GStreamer elements, select the backend that matches the target module's SoC when running the examples.
Supported Video Backends
| Platform | Backend | Encoder element | Decoder element |
|---|---|---|---|
| i.MX 8M Mini and i.MX 8M Plus | Hantro | vpuenc_h264 | vpudec |
| i.MX 8QuadMax and i.MX 8X | Amphion | v4l2h264enc | v4l2h264dec |
The Amphion decoder outputs frames in a native tiled format, NV12_8L128, rather than a standard planar layout. Using fakesink as the output sink in the decoding example avoids any issues with this tiling, because no display or conversion step depends on the tiling.
Prerequisites
- Hardware:
- An i.MX 8-based Toradex System-on-Module (SoM)
- A compatible Carrier Board
- Software:
- A Toradex SoM with Torizon OS installed
How the Demo Application Works
The provided container image includes two scripts that demonstrate hardware-accelerated H.264 encoding and decoding:
gstreamer-encode: generates a synthetic raw-video stream and encodes it to H.264 using the platform's hardware encodergstreamer-decode: decodes an H.264 elementary stream using the hardware decoder and pushes the raw frames tofakesink
The container's entry point checks device-tree compatibility information to identify the SoC and loads the required digital signal processor (DSP) firmware where needed. The entry point does not select the backend, so specify it with the --backend flag when running the encoding and decoding examples.
The decoding example is headless by design and the decoded frames go straight to fakesink, so the demo application exercises the full decode path without a display or an output file to manage.
Run the Demo Application
Toradex provides all the examples in a single prebuilt Docker image. Start one long-running container and use the docker exec command to run each example inside it, rather than starting a new container for every command. This approach keeps all the device mounts and cgroup rules in one place and covers both the Hantro and Amphion backends:
# docker run -d \
--platform linux/arm64 \
--name gstreamer \
--net host \
--volume /dev:/dev \
--volume /tmp:/tmp \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /run/udev:/run/udev:ro \
--volume /proc/device-tree:/proc/device-tree:ro \
--volume "/home/torizon:/home/torizon" \
--device-cgroup-rule "c 81:* rmw" \
--device-cgroup-rule "c 237:* rmw" \
--device-cgroup-rule "c 238:* rmw" \
--device-cgroup-rule "c 251:* rmw" \
--device-cgroup-rule "c 253:* rmw" \
torizon/gstreamer1.0-examples-imx8:stable-rc \
sleep infinity
With the container running in the background, use the docker exec -it gstreamer <command> command to run the decoding and encoding examples. You can write output files to /tmp or /home/torizon because both paths are mounted into the container and visible on the host.
Hardware-Accelerated H.264 Decoding
To run a decoding example using the VPU, use the gstreamer-decode script on the /usr/share/gstreamer1.0-examples/test-h264.h264 file. No output file is produced, because the decoded frames go to fakesink.
The following command goes through the vpudec element.
# docker exec -it gstreamer \
gstreamer-decode \
--backend hantro \
--input /usr/share/gstreamer1.0-examples/test-h264.h264
The following command goes through v4l2h264dec, which returns native tiled NV12_8L128 frames. Native tiled output is expected because the output sink, fakesink, does not require a specific format.
# docker exec -it gstreamer \
gstreamer-decode \
--backend amphion \
--input /usr/share/gstreamer1.0-examples/test-h264.h264
After running the decoding example, the output indicates that the decoding completed successfully:
H.264 decoding completed successfully
Result: PASS
Hardware-Accelerated H.264 Encoding
The gstreamer-encode script generates a synthetic stream with GStreamer's videotestsrc and encodes it to H.264 using the VPU. The script writes the encoded stream to the file specified by the --output flag. In the following examples, the output file is /tmp/encoded.h264.
The following command goes through the vpuenc_h264 element. The frames come in as I420 and are encoded to H.264.
# docker exec -it gstreamer \
gstreamer-encode \
--backend hantro \
--output /tmp/encoded.h264 \
--frames 120
The following command goes through v4l2h264enc. The frames come in as NV12 and are encoded to H.264.
# docker exec -it gstreamer \
gstreamer-encode \
--backend amphion \
--output /tmp/encoded.h264 \
--frames 120
After running the encoding example, the output indicates that the encoding completed successfully. The following example shows one possible successful output:
Output file: /tmp/encoded.h264
Frames: 120
Resolution: 640x480
Framerate: 30/1
Encoder backend: Hantro
Encoder element: vpuenc_h264
Input format: I420
Encoded bytes: 1257236
H.264 encoding completed successfully
Result: PASS
Finally, confirm that the output file was created:
# ls /tmp/encoded.h264
/tmp/encoded.h264