GStreamer Plugin (sol3src)

sol3src is a GStreamer source element that reads pre-encoded H.264 or H.265 video from the Sol3 camera server via shared memory and pushes it into a GStreamer pipeline. It must run on the Sol3 device since it requires direct shared memory access.

Camera Server -> VideoEncodedPacket (shmem) -> sol3src -> GStreamer Pipeline

Prerequisites

Camera server running with venc_config configured for the target camera. See Video Encoding.

The plugin is built as gstsol3src.so (ARM64 only, voxl-cross preset) and installed to /opt/sol3/lib/gstreamer-plugins/. sol3_services sets GST_PLUGIN_PATH to that directory system-wide, so GStreamer discovers the plugin automatically.

Properties

Property

Type

Default

Description

cam-id

uint (1–12)

1

Camera to read encoded frames from

endpoint

string

"/run/sol3/camera"

Shmem endpoint to connect to

is-live

boolean

true

Whether to operate as a live source

The plugin automatically detects the codec (H.264 or H.265) from the first keyframe’s codec config at startup.

Output Caps

video/x-h264, stream-format=(string)byte-stream, alignment=(string)au
video/x-h265, stream-format=(string)byte-stream, alignment=(string)au

The plugin outputs Annex B byte-stream NAL units and waits for the first keyframe with codec config (SPS/PPS) before pushing any data downstream.

Timestamps

The plugin extracts the measurement timestamp from the camera frame header and uses it as the GStreamer PTS. When multiple sol3src elements share the same pipeline, their PTS values are synchronized through a shared base time — the first camera to produce a measurement timestamp sets the reference.

Recording

Warning

For unattended or time-bounded captures, prefer a container format that survives ungraceful termination (power loss, SIGKILL, timeout(1), etc.). Plain mp4mux writes the moov atom only on EOS; without it the file is unplayable. gst-launch-1.0 -e sends EOS on SIGINT (Ctrl+C) but not on SIGTERM, so timeout 20s gst-launch-1.0 -e ... will still produce a broken MP4. See the container options below for the trade-offs.

Save to fragmented MP4

fragment-duration makes mp4mux flush moof/mdat boxes at a fixed cadence, so the file is playable past the last completed fragment without an EOS.

gst-launch-1.0 sol3src cam-id=2 ! h265parse ! mp4mux fragment-duration=100 ! filesink location=cam2.mp4

Save to MKV

Matroska accepts byte-stream directly, so no explicit parser is needed. Like plain MP4, MKV expects a clean EOS to finalize, but most players tolerate truncated MKVs better.

gst-launch-1.0 -e sol3src cam-id=2 ! matroskamux ! filesink location=cam2.mkv

Save to plain MP4

Use only when a clean shutdown is guaranteed and a non-fragmented MP4 is required. Pass -e to gst-launch-1.0 so Ctrl+C sends EOS and mp4mux finalizes the moov atom.

# H.265 camera
gst-launch-1.0 -e sol3src cam-id=2 ! h265parse ! mp4mux ! filesink location=cam2.mp4

# H.264 camera
gst-launch-1.0 -e sol3src cam-id=1 ! h264parse ! mp4mux ! filesink location=cam1.mp4

Streaming

Stream over TCP (SSH port-forwarding)

UDP does not work through SSH port-forwarding. Use TCP with gdppay/gdpdepay. GDP preserves the caps, so the receiver auto-detects the codec.

On the device (sender):

gst-launch-1.0 sol3src cam-id=1 ! \
    gdppay ! \
    tcpserversink host=127.0.0.1 port=8554

On the host (receiver), forward the port over SSH and display:

ssh -L 8554:localhost:8554 <device>

gst-launch-1.0 tcpclientsrc host=localhost port=8554 ! \
    gdpdepay ! \
    decodebin ! \
    videoconvert ! \
    autovideosink

Stream over UDP (direct network)

# Sender (on device) — H.265 example
gst-launch-1.0 sol3src cam-id=2 ! \
    h265parse ! \
    rtph265pay ! \
    udpsink host=192.168.1.100 port=8554

# Receiver (on host)
gst-launch-1.0 udpsrc port=8554 caps="application/x-rtp" ! \
    rtph265depay ! \
    decodebin ! \
    videoconvert ! \
    autovideosink

Display Locally

gst-launch-1.0 sol3src cam-id=1 ! \
    decodebin ! \
    videoconvert ! \
    autovideosink

Troubleshooting

No Frames Arriving

The plugin logs a warning every 5 seconds if no encoded frames are received from the camera component. Verify that sol3_server is running and the camera config has venc_config enabled.

Pipeline Stalls on Startup

The plugin waits up to 10 seconds for the first keyframe with codec config (SPS/PPS) during start(). This delay depends on the configured GOP interval. If the camera server is not running, the pipeline will time out and advertise both codecs.

not-linked Error with mp4mux

mp4mux requires hvc1/avc stream format, not byte-stream. Use an explicit h265parse or h264parse between sol3src and mp4mux. Note that parsebin cannot do this conversion — its internal capsfilter constrains the output to byte-stream. For codec-agnostic recording, use matroskamux instead.