GStreamer pipeline examples for Jetson: nvarguscamerasrc, nvvidconv, encode, and decode
GStreamer on Jetson uses NVIDIA-specific elements for hardware-accelerated camera capture, format conversion, and encode/decode. These elements, nvarguscamerasrc, nvvidconv, nvv4l2h264enc, nvv4l2decoder, have different properties and caps requirements than their generic Linux equivalents. This post is a practical reference for the GStreamer pipelines that actually work on Jetson Orin, with copy-paste commands for the most common use cases.
Key Insights
- NVMM caps (
video/x-raw(memory:NVMM)) keep frames in GPU memory between NVIDIA elements, always use them between nvarguscamerasrc, nvvidconv, and nvv4l2h264enc - nvarguscamerasrc is for ISP-processed camera capture; v4l2src is for raw sensor frames
- kmssink works without X or Wayland, use it for headless display output on embedded setups
- nvv4l2h264enc and nvv4l2decoder use Jetson’s hardware encode/decode engines;
avenc_h264andavdec_h264are software fallbacks - gst-inspect-1.0 and GST_DEBUG are your primary debugging tools, inspect before troubleshooting
Prerequisites
Install NVIDIA’s GStreamer plugins:
sudo apt install nvidia-l4t-gstreamer gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-tools
Verify NVIDIA elements are available:
gst-inspect-1.0 nvarguscamerasrc
gst-inspect-1.0 nvvidconv
gst-inspect-1.0 nvv4l2h264enc
gst-inspect-1.0 nvv4l2decoder
If any of these fail, the nvidia-l4t-gstreamer package wasn’t installed or its plugins didn’t load. Check gst-inspect-1.0 --gst-plugin-path /usr/lib/aarch64-linux-gnu/gstreamer-1.0/.
Camera capture pipelines
nvarguscamerasrc (ISP path, recommended for production)
Basic display test:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvvidconv ! 'video/x-raw,format=BGRx' ! \
videoconvert ! autovideosink
Headless, capture to file:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 num-buffers=300 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvv4l2h264enc ! h264parse ! qtmux ! \
filesink location=/tmp/capture.mp4
Get ISP-processed frames as NV12 for OpenCV or inference:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1280,height=720,framerate=30/1' ! \
nvvidconv ! 'video/x-raw,format=NV12' ! \
appsink name=sink max-buffers=1 drop=true
Check available sensor IDs:
gst-launch-1.0 nvarguscamerasrc ! fakesink -v 2>&1 | grep "Available Sensor"
v4l2src (raw V4L2 path)
Basic display (format depends on sensor):
gst-launch-1.0 v4l2src device=/dev/video0 ! \
'video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1' ! \
videoconvert ! autovideosink
Display via KMS/DRM without X server:
gst-launch-1.0 v4l2src device=/dev/video0 ! \
'video/x-raw,format=YUY2,width=1920,height=1080,framerate=30/1' ! \
videoconvert ! kmssink
Check what formats your camera supports:
v4l2-ctl --list-formats-ext -d /dev/video0
Raw capture to file (useful for debugging sensor output):
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=30 ! \
'video/x-raw,format=RG10,width=1920,height=1080' ! \
filesink location=/tmp/raw_frames.bin
Hardware encode
H.264 encode
Camera → H.264 file:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvv4l2h264enc bitrate=8000000 ! h264parse ! \
qtmux ! filesink location=output.mp4
Camera → H.264 UDP stream (for remote viewing):
# Sender (Jetson)
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvv4l2h264enc ! h264parse ! \
rtph264pay ! udpsink host=192.168.1.100 port=5000
# Receiver (laptop)
gst-launch-1.0 udpsrc port=5000 ! \
'application/x-rtp,encoding-name=H264,payload=96' ! \
rtph264depay ! avdec_h264 ! autovideosink
H.265 encode
H.265 typically achieves the same quality at half the bitrate:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvv4l2h265enc bitrate=4000000 ! h265parse ! \
qtmux ! filesink location=output.mp4
nvv4l2h264enc key properties:
bitrate, target bitrate in bps (default: 4000000)maxperf-enable, set to true for maximum throughput at higher powerpreset-level, 1 (ultra-fast) to 4 (best quality), default 3
Hardware decode
MP4 file → display:
gst-launch-1.0 filesrc location=video.mp4 ! \
qtdemux ! h264parse ! nvv4l2decoder ! \
nvvidconv ! 'video/x-raw,format=BGRx' ! \
videoconvert ! autovideosink
H.265 decode:
gst-launch-1.0 filesrc location=video.mp4 ! \
qtdemux ! h265parse ! nvv4l2decoder ! \
nvvidconv ! autovideosink
Note: nvv4l2decoder outputs NVMM-format frames. Connect directly to nvvidconv (not videoconvert) to stay in the hardware path.
nvvidconv, format conversion and scaling
nvvidconv is Jetson’s hardware video converter. Use it between NVIDIA elements for format conversion and scaling without CPU involvement.
Convert YUY2 → BGRx:
gst-launch-1.0 v4l2src device=/dev/video0 ! \
'video/x-raw,format=YUY2,width=1920,height=1080' ! \
nvvidconv ! 'video/x-raw,format=BGRx,width=1920,height=1080' ! \
videoconvert ! autovideosink
Scale and convert in one step:
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvvidconv ! 'video/x-raw(memory:NVMM),width=640,height=360' ! \
nvv4l2h264enc ! h264parse ! qtmux ! filesink location=scaled.mp4
Important: When connecting two NVIDIA elements, add (memory:NVMM) to the caps between them:
# Correct — stays in GPU memory
! nvvidconv ! 'video/x-raw(memory:NVMM),format=NV12' ! nvv4l2h264enc
# Wrong — forces CPU copy
! nvvidconv ! 'video/x-raw,format=NV12' ! nvv4l2h264enc
Multi-camera pipelines
View two cameras side by side:
gst-launch-1.0 \
nvarguscamerasrc sensor-id=0 name=cam0 ! \
'video/x-raw(memory:NVMM),width=1280,height=720,framerate=30/1' ! \
nvvidconv ! 'video/x-raw,format=BGRx,width=640,height=360' ! videoconvert ! \
compositor name=mix sink_0::xpos=0 sink_0::ypos=0 sink_1::xpos=640 sink_1::ypos=0 ! \
autovideosink \
nvarguscamerasrc sensor-id=1 ! \
'video/x-raw(memory:NVMM),width=1280,height=720,framerate=30/1' ! \
nvvidconv ! 'video/x-raw,format=BGRx,width=640,height=360' ! videoconvert ! \
mix.
Record both cameras independently:
gst-launch-1.0 \
nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvv4l2h264enc ! h264parse ! qtmux ! filesink location=cam0.mp4 \
nvarguscamerasrc sensor-id=1 ! \
'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1' ! \
nvv4l2h264enc ! h264parse ! qtmux ! filesink location=cam1.mp4
Debugging pipelines
Inspect element properties:
gst-inspect-1.0 nvarguscamerasrc
gst-inspect-1.0 nvv4l2h264enc
Verbose caps negotiation:
gst-launch-1.0 -v nvarguscamerasrc ! fakesink 2>&1 | head -50
Enable debug logging:
# Log all elements at level 3
GST_DEBUG=3 gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! fakesink
# Log specific elements
GST_DEBUG=nvarguscamerasrc:5,nvvidconv:4 gst-launch-1.0 ...
Check pipeline state manually:
# Add -v to see state changes
gst-launch-1.0 -v nvarguscamerasrc sensor-id=0 ! \
'video/x-raw(memory:NVMM)' ! nvvidconv ! autovideosink
Common pipeline errors:
| Error | Cause | Fix |
|---|---|---|
| ”No such element: nvarguscamerasrc” | nvidia-l4t-gstreamer not installed | sudo apt install nvidia-l4t-gstreamer |
| ”Internal data flow error” | Buffer backpressure | Add ! queue after the source |
| ”nvarguscamerasrc: No cameras available” | nvargus-daemon not running | sudo systemctl start nvargus-daemon |
| Pipeline hangs at PLAYING | NVMM path broken | Check caps have (memory:NVMM) between NVIDIA elements |
| ”Cannot identify /dev/video0” | Camera not probed | Check v4l2-ctl --list-devices |
For camera driver bring-up that these pipelines depend on, see CSI camera driver on Jetson: V4L2, Argus, and IMX sensor bring-up. For Argus-specific setup including nvargus-daemon, see NVIDIA Argus API camera driver on Jetson. For pipeline performance issues, nvvidconv throughput collapse under multiple processes, see nvvidconv performance with multiple GStreamer processes on Jetson.
FAQ
Why does nvarguscamerasrc say “No such element or plugin”?
The nvidia-l4t-gstreamer package isn’t installed. Install it with: sudo apt install nvidia-l4t-gstreamer. Also verify gst-inspect-1.0 nvarguscamerasrc returns the element description. If it still fails after install, nvargus-daemon isn’t running, start it with sudo systemctl start nvargus-daemon.
What is the difference between v4l2src and nvarguscamerasrc on Jetson?
v4l2src reads raw frames directly from the V4L2 kernel driver, no ISP processing. nvarguscamerasrc routes through the nvargus-daemon and Jetson ISP, providing auto-exposure, auto-white-balance, and hardware noise reduction. Use nvarguscamerasrc for production pipelines that need ISP output; use v4l2src when you need raw Bayer frames or have a sensor that isn’t Argus-compatible.
What does “video/x-raw(memory:NVMM)” mean in a Jetson GStreamer pipeline?
NVMM keeps frame buffers in GPU memory, avoiding a CPU copy between NVIDIA hardware elements. When connecting nvarguscamerasrc to nvvidconv, or nvvidconv to nvv4l2h264enc, always use NVMM caps to maintain the hardware-accelerated path. Without NVMM, frames are copied through system RAM, adding latency and CPU load.
Why does my GStreamer pipeline stall or produce “Internal data flow error”?
Usually buffer backpressure, a downstream element isn’t consuming frames as fast as they arrive. Add ! queue between the source and a slow downstream element. If the pipeline stops after a few seconds, check for missing NVMM caps, this often causes stalls in the format conversion stage.
How do I display a Jetson camera feed without X or Wayland (headless)?
Use kmssink for DRM/KMS direct rendering without a display server: gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! kmssink. Or pipe to a file or network stream instead of a display sink.
Relevant Services
NVIDIA Jetson Expert Support
Stuck on a Jetson bring-up?
We've debugged this failure mode before. BSP, device tree, camera pipelines, OTA, most blockers clear in the first session. No long retainers. No guessing.
Frequently Asked Questions
Why does nvarguscamerasrc say 'No such element or plugin'?
The nvidia-l4t-gstreamer package isn't installed. Install it with: sudo apt install nvidia-l4t-gstreamer. Also verify gst-inspect-1.0 nvarguscamerasrc returns the element description. If it still fails, the nvargus-daemon isn't running, start it with sudo systemctl start nvargus-daemon.
What is the difference between v4l2src and nvarguscamerasrc on Jetson?
v4l2src reads raw frames directly from the V4L2 kernel driver, no ISP processing. nvarguscamerasrc routes through the nvargus-daemon and Jetson ISP, providing auto-exposure, auto-white-balance, and hardware noise reduction. Use nvarguscamerasrc for production camera pipelines that need ISP output; use v4l2src when you need raw Bayer frames or have a sensor that isn't Argus-compatible.
What does 'video/x-raw(memory:NVMM)' mean in a Jetson GStreamer pipeline?
NVMM (NVIDIA Memory Management) keeps frame buffers in GPU memory, avoiding a CPU copy between NVIDIA hardware elements. When connecting nvarguscamerasrc to nvvidconv, or nvvidconv to nvv4l2h264enc, always use NVMM caps to maintain the hardware-accelerated path. Without NVMM, frames are copied through system RAM, adding latency and CPU load.
Why does my GStreamer pipeline stall or produce Internal data flow error?
Usually a buffer backpressure problem, a downstream element isn't consuming frames as fast as they arrive. Add '! queue' between the source and a slow downstream element. If the pipeline stops after a few seconds, check for nvvidconv NVMM caps, missing NVMM often causes stalls in the format conversion stage.
How do I display a Jetson camera feed without X or Wayland (headless)?
Use kmssink for DRM/KMS direct rendering without a display server: gst-launch-1.0 v4l2src device=/dev/video0 ! videoconvert ! kmssink. Or pipe to a file or network stream instead of a display sink. nvarguscamerasrc also works headless, route to filesink or udpsink instead of autovideosink.
Written by
Aarón AnguloCo-Founder & CEO · ProventusNova
Obsessed with client outcomes. Aarón ensures every engagement delivers real results, on time, on scope, no exceptions.
Connect on LinkedInRelated Articles
nvvidconv performance collapse with multiple GStreamer processes on Jetson
Running multiple GStreamer pipelines as separate processes on Jetson? nvvidconv throughput can drop 5-10x. Here's why VIC contention causes it and the.
Argus camera driver on Jetson: nvarguscamerasrc setup, ISP pipeline, and debugging
Set up the Argus camera driver on NVIDIA Jetson: nvargus-daemon, nvarguscamerasrc pipelines, LibArgus C++ API, ISP features, and common Argus errors debugged.
How to create a hardware-accelerated GStreamer pipeline for live streaming on Jetson
Build a low-latency GStreamer live streaming pipeline on NVIDIA Jetson using nvv4l2h264enc and udpsink or gst-rtsp-server. RTSP, UDP, and SRT examples.
GStreamer hardware-accelerated pipeline on Jetson
Fix slow GStreamer pipelines on NVIDIA Jetson. Replace videoconvert with nvvidconv, use nvv4l2decoder, and keep data in NVMM to cut CPU load by 60–80%.