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.

  • GST_PLUGIN_PATH set to the plugin location:

export GST_PLUGIN_PATH="/devel/sol3/gstreamer-plugins/"

The plugin ships as gstsol3src.so (ARM64, on the Sol3 device) and is installed to lib/gstreamer-1.0/.

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

Save to MP4

MP4 requires a container-compatible stream format (avc/hvc1), not byte-stream. Use the correct parser for the camera’s codec between sol3src and mp4mux.

Important

Always use the -e flag with gst-launch-1.0 when recording to MP4. This sends an EOS event on Ctrl+C, which tells mp4mux to finalize the moov atom. Without -e, the file will be unplayable.

# 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

Save to MKV

Matroska containers accept byte-stream directly, so no explicit parser is needed:

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

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.