GStreamer Buffer Synchronization: Examples - GStreamer
![]() | |
Basics and foundation | |
---|---|
|
|
Getting Started | |
|
|
Documentation | |
|
|
Examples | |
|
|
Contact Us | |
|
Gstreamer plugin examples: rrsyncer
Basic pipeline
You can try a basic pipeline for sync with two cameras that sync over two independent video sinks:
gst-launch-1.0 v4l2src device="/dev/video4" ! $CAPS ! videoconvert ! queue ! rrsyncer name=syncer sync-mode=1 ! queue ! autovideosink \ v4l2src device="/dev/video2" ! $CAPS ! videoconvert ! queue ! rrsyncer drop-rate=10 ! syncer.sink_1 syncer.src_1 ! queue ! autovideosink
This example uses the debug parameter of rrsyncer drop-rate, which makes fake gaps in the stream. The synchronization can be deactivated by changing the sync-mode of rrsyncer to 0.
GstD pipeline
You can use the syncer with other plugins as valves or a compositor.
DELAY=${1:-5} # Time in seconds to apply the delay (default: 5) PIPE_NAME="delay_pipe" CAPS="video/x-raw,width=640,height=480,format=RGBA" OUTPUT=output.mp4 echo "Starting pipeline with delay duration: $DELAY seconds" # Delete previous pipeline if it exists gst-client "pipeline_delete $PIPE_NAME" 2>/dev/null # Create the pipeline with valve only affecting the 'ball' pattern gst-client "pipeline_create $PIPE_NAME \ rrsyncer name=syncer sync-mode=1\ videotestsrc is-live=true pattern=ball ! videoconvert ! videoscale ! $CAPS ! valve name=valv0 drop=false ! syncer. syncer. ! timeoverlay ! queue name=queue0 ! comp.sink_0 \ videotestsrc is-live=true pattern=ball ! videoconvert ! videoscale ! $CAPS ! syncer. syncer. ! timeoverlay ! queue name=queue1 ! comp.sink_1 \ videotestsrc is-live=true pattern=ball ! videoconvert ! videoscale ! $CAPS ! syncer. syncer. ! timeoverlay ! queue name=queue2 ! comp.sink_2 \ compositor name=comp background=black \ sink_0::xpos=1280 sink_0::ypos=0 \ sink_1::xpos=640 sink_1::ypos=0 \ sink_2::xpos=0 sink_2::ypos=0 ! \ videoconvert ! x264enc ! h264parse ! mp4mux name=mux ! filesink location=$OUTPUT" # Start playback (recording begins) gst-client "pipeline_play $PIPE_NAME" # Wait before applying delay sleep 5 echo ">> Dropping buffers from valve valv0" gst-client "element_set $PIPE_NAME valv0 drop true" # Apply delay for configurable duration sleep $DELAY echo ">> Resuming buffers from valve valv0" gst-client "element_set $PIPE_NAME valv0 drop false" # Let the stream continue sleep 10 # Send EOS to finalize the file properly gst-client "event_eos $PIPE_NAME" gst-client "bus_filter $PIPE_NAME eos" gst-client "bus_read $PIPE_NAME" # Stop and clean up the pipeline gst-client "pipeline_stop $PIPE_NAME" gst-client "pipeline_delete $PIPE_NAME"
This pipeline will pause all the compositor input to keep the sync when the valve starts dropping buffers. The valve drop differs from the syncer drop, as the valve does not create gap events, which also do not create empty frames on the compositor. These examples use the open-source project GStreamer Daemon; you can read more of it here.
Stitcher pipeline
rrsyncer can also be used with element with special buffer pools as RidgeRun Cuda stitcher. For example,
CAPS="video/x-raw, width=640, height=480, format=RGBA" HOMOGRAPHY_LIST="`cat homographies_basicpipeline.json | tr -d "\n" | tr -d " "`" OUTPUT=output.mp4 gst-launch-1.0 -e \ cudastitcher name=stitcher homography-list=$HOMOGRAPHY_LIST \ rrsyncer name=syncer sync-mode=1 min-latency=100000000 \ videotestsrc pattern=ball motion=1 num-buffers=120 ! syncer. syncer. ! queue ! videoconvert ! $CAPS ! queue ! stitcher.sink_0 \ videotestsrc pattern=ball num-buffers=120 motion=1 ! syncer. syncer. ! queue ! videoconvert ! $CAPS ! queue ! stitcher.sink_1 \ videotestsrc pattern=ball num-buffers=120 motion=1 ! syncer. syncer. ! queue ! videoconvert ! $CAPS ! queue ! stitcher.sink_2 \ stitcher. ! queue ! videoconvert ! autovideosink \ cudastitcher name=stitcher2 homography-list=$HOMOGRAPHY_LIST \ videotestsrc pattern=ball motion=1 num-buffers=120 ! queue ! videoconvert ! $CAPS ! queue ! stitcher2.sink_0 \ videotestsrc pattern=ball num-buffers=120 motion=1 ! queue ! videoconvert ! $CAPS ! queue ! stitcher2.sink_1 \ videotestsrc pattern=ball num-buffers=120 motion=1 ! queue ! videoconvert ! $CAPS ! queue ! stitcher2.sink_2 \ stitcher2. ! queue ! videoconvert ! autovideosink