gvastreamdemux#
Routes a single muxed stream back to per-source output pads based on GstAnalyticsBatchMeta
attached upstream by gvastreammux. The element is the companion to gvastreammux and
must be paired with it; it cannot work standalone.
Overview#
gvastreamdemux reads the GstAnalyticsBatchMeta attached by gvastreammux and routes each
source’s buffer to src_<index>. This enables the common multi-stream pattern:
N sources → gvastreammux → shared inference → gvastreamdemux → N independent outputs
It transparently handles both of the mux’s output modes:
PASSTHROUGH input (plain video buffers): each buffer carries a single-stream meta; the demux forwards it to
src_<streams[0].index>as-is.CONTAINER input (caps
multistream/x-analytics-batch): each buffer is a container holdingn_streamssources. The demux unpacks everystreams[i], recovers that source’s original caps from itsGST_EVENT_CAPSsticky event, forwards those caps tosrc_<index>(lazily, once per pad), and pushes the source’s buffer (objects[0]). This is how heterogeneous video + lidar batches are split back into avideo/x-rawbranch and anapplication/x-lidarbranch.
Key design points:
Metadata-driven routing — buffers are forwarded based on stream index. Buffers without a usable
GstAnalyticsBatchMetacause a pipeline error.Per-pad caps in CONTAINER mode — each
src_*pad emits its own stream’s caps, so different pads can carry different media types (e.g.src_0video,src_2lidar).No frame dropping — every source buffer is pushed to its target pad.
Sparse src indices — names like
demux.src_5work even ifsrc_0..src_4were never created, mirroring the mux side. Indices must be in[0, 256).No strict count match — the upstream
n_streamsand the number of requestedsrc_*pads do not have to match. Buffers whose stream index exceeds the highest requested src pad are dropped with aGST_ERROR. Match the indices to the mux indices to receive every frame.
Important: as with
gvastreammux, downstreamgvadetectshould keepinference-interval=1(default). Higher values would skip whole batches in arrival order, meaning some source ids consistently miss inference results.
How It Works#
The pipeline requests source pads (
src_0,src_1, …) — typically one per upstream sink pad. Pad index is parsed from the requested name; sparse indices are allowed up to 255.On the sink
CAPSevent the demux detects whether the input is plain video (PASSTHROUGH) or themultistream/x-analytics-batchcontainer (CONTAINER). In CONTAINER mode it does not forward the container caps downstream — per-stream caps come from the buffers instead.When a buffer arrives:
PASSTHROUGH: read
streams[0].indexand push the buffer tosrc_<index>.CONTAINER: for each
streams[i], forward that stream’s caps tosrc_<index>the first time the pad is used, then pushobjects[0](the source’s buffer) to that pad. If no matchingsrc_<index>pad exists, the buffer is dropped withGST_FLOW_ERROR.
EOS on the sink pad is forwarded to all source pads.
Properties#
Property |
Type |
Default |
Description |
|---|---|---|---|
|
Double |
|
Output rate cap shared across all source pads (0 = unlimited). Only set for local file sources; setting on RTSP/live sources can stall the pipeline. |
Pipeline Examples#
Local files with per-source FPS counters#
gst-launch-1.0 \
gvastreammux name=mux max-fps=30 \
! queue \
! gvadetect model=model.xml device=GPU \
pre-process-backend=va-surface-sharing \
! gvastreamdemux name=demux \
demux.src_0 ! queue ! gvafpscounter ! fakesink \
demux.src_1 ! queue ! gvafpscounter ! fakesink \
filesrc location=video0.h265 ! h265parse ! vah265dec ! mux.sink_0 \
filesrc location=video1.h265 ! h265parse ! vah265dec ! mux.sink_1
RTSP sources#
gst-launch-1.0 \
gvastreammux name=mux \
! queue \
! gvadetect model=model.xml device=GPU \
pre-process-backend=va-surface-sharing \
! gvastreamdemux name=demux \
demux.src_0 ! queue ! gvafpscounter ! fakesink \
demux.src_1 ! queue ! gvafpscounter ! fakesink \
rtspsrc location=rtsp://host:8554/stream latency=200 \
! rtph265depay ! h265parse ! vah265dec ! mux.sink_0 \
rtspsrc location=rtsp://host:8555/stream latency=200 \
! rtph265depay ! h265parse ! vah265dec ! mux.sink_1
Per-source watermark and display#
gst-launch-1.0 \
gvastreammux name=mux \
! queue \
! gvadetect model=model.xml device=GPU \
pre-process-backend=va-surface-sharing \
! gvastreamdemux name=demux \
demux.src_0 ! queue ! gvawatermark ! videoconvert ! autovideosink \
demux.src_1 ! queue ! gvawatermark ! videoconvert ! autovideosink \
rtspsrc location=rtsp://host:8554/stream latency=200 \
! rtph265depay ! h265parse ! vah265dec ! mux.sink_0 \
rtspsrc location=rtsp://host:8555/stream latency=200 \
! rtph265depay ! h265parse ! vah265dec ! mux.sink_1
Heterogeneous video + lidar (CONTAINER input)#
When the mux runs in CONTAINER mode, gvastreamdemux unpacks each batch back into per-source
pads, restoring each source’s own caps. Note there is no gvadetect between the mux and the
demux (a container buffer is not raw video). Per-stream inference (gvadetect for video,
g3dinference for lidar) would attach after the corresponding demux branch; here each branch
ends in fakesink:
gst-launch-1.0 -e \
gvastreammux name=mux sync-mode=first-pts \
! queue \
! gvastreamdemux name=demux \
demux.src_0 ! queue ! gvafpscounter ! fakesink \
demux.src_1 ! queue ! gvafpscounter ! fakesink \
demux.src_2 ! queue ! fakesink \
filesrc location=video0.h265 ! h265parse ! vah265dec ! mux.sink_0 \
filesrc location=video1.h265 ! h265parse ! vah265dec ! mux.sink_1 \
multifilesrc location=velodyne/%06d.bin start-index=0 caps=application/octet-stream \
! g3dlidarparse frame-rate=10 ! mux.sink_2
Here src_0 and src_1 emit video/x-raw, while src_2 emits application/x-lidar.
Required Metadata#
gvastreamdemux requires a usable GstAnalyticsBatchMeta on every incoming buffer. The fields it
reads depend on the input mode:
PASSTHROUGH input:
Field |
Type |
Description |
|---|---|---|
|
guint |
Source pad index this buffer originated from. |
|
gsize |
Number of contributing pads in the batch. |
CONTAINER input:
Field |
Type |
Description |
|---|---|---|
|
gsize |
Number of sources packed in this container. |
|
guint |
Destination |
|
GstBuffer |
The buffer pushed to that pad. |
|
GstEvent |
The source caps ( |
Error Conditions#
Condition |
Behavior |
|---|---|
Buffer missing |
|
|
Buffer dropped with |
No |
Buffer dropped with |
Pad index ≥ 256 on request |
|
Element Details (gst-inspect-1.0)#
Factory Details:
Long-name GVA Stream Demuxer
Klass Video/Demuxer
Description Demuxes a single stream into multiple output pads based on
GstAnalyticsBatchMeta streams[0].index. Must be used with
gvastreammux.
Author Intel Corporation
Pad Templates:
SINK template: 'sink' (Always, video/x-raw, video/x-raw(memory:VAMemory) NV12,
video/x-raw(memory:DMABuf) DMA_DRM,
multistream/x-analytics-batch(meta:GstAnalyticsBatchMeta))
SRC template: 'src_%u' (On request, the video caps above OR application/x-lidar)
Element Properties:
max-fps Double, range 0-Inf, default 0
Run gst-inspect-1.0 gvastreamdemux against your installation for the authoritative output.