Synchronised start and stop for GStreamer pipelines

225 Views Asked by At

I have two GStreamer pipelines that I'm currently running using gst-launch-1.0 from console. They store two UDP streams (one for H.264 data and one for RAW) in two separate files. The UDP streams come from the same source: a video played on loop. I want the two files to match frames perfectly, so that when I use VMAF for quality measurement frame mismatch doesn't play a role.

Currently, I have a bash script that executes the two gst-launch-1.0 commands in two different konsole windows:

...
# Save the AVC stream.
konsole --hold -e "gst-launch-1.0 -v -e udpsrc uri=udp://0.0.0.0 port=$port_avc ! \
        \"application/x-rtp, media=(string)video, clock-rate=(int)90000, \
        encoding-name=(string)H264, payload=(int)96\" ! \
        rtph264depay ! h264parse ! mp4mux ! filesink location=$loc_avc" &
# Save the RAW stream.
konsole --hold -e "gst-launch-1.0 -v -e udpsrc uri=udp://0.0.0.0 port=$port_raw ! \
        \"application/x-rtp, media=(string)video, \
        clock-rate=(int)90000, encoding-name=(string)RAW, sampling=(string)YCbCr-4:2:0, \
        depth=(string)8, width=(string)1024, height=(string)768, colorimetry=(string)SMPTE240M, \
        payload=(int)96, a-framerate=(string)60\" ! rtpvrawdepay ! videorate ! \
        \"video/x-raw, framerate=(fraction)60/1\" ! \
        y4menc ! filesink location=$loc_raw" &
...

However, there are a couple of problems with this setup. First, the two commands don't truly start at the same time; there is a fraction-of-a-second delay. Second, I need to manually go to the windows and close the pipelines with Ctrl + C for the files to save correctly; afterwards, I need to go to the console from which I ran the script and manually kill the Konsole windows.

I tried fixing this by adding trap 'kill 0' SIGINT to the script; this does the job by killing the windows automatically when I press Ctrl + C; however, because the gstreamer pipelines don't receive their EOS, the files never save correctly. I've also tried using trap 'kill 0' SIGINT inside the konsole command (by using konsole -e bash -c <command>), but I still don't get the desired effect.

What can I do to solve this? Is there any way to ensure the two pipelines start and end at the same time using console commands? Or is there a better way to do this using gstreamer itself?

1

There are 1 best solutions below

1
SeB On

You may launch the two pipelines with only one gst-launch-1.0 command and add sync to filesinks:

gst-launch-1.0 -ev  \
udpsrc uri=udp://0.0.0.0 port=$port_avc ! \
 \"application/x-rtp, media=(string)video, clock-rate=(int)90000, \
 encoding-name=(string)H264, payload=(int)96\" ! \
 rtph264depay ! h264parse ! mp4mux ! filesink location=$loc_avc sync=1    \
udpsrc uri=udp://0.0.0.0 port=$port_raw ! \
 \"application/x-rtp, media=(string)video, \
 clock-rate=(int)90000, encoding-name=(string)RAW, sampling=(string)YCbCr-4:2:0, \
 depth=(string)8, width=(string)1024, height=(string)768, colorimetry=(string)SMPTE240M, \
 payload=(int)96, a-framerate=(string)60\" ! rtpvrawdepay ! videorate ! \
 \"video/x-raw, framerate=(fraction)60/1\" ! \
 y4menc ! filesink location=$loc_raw sync=1

Also note that it may depend on how much received RTP frames are correctly and synchronously timestamped, and that H264 encoding may need P/B frames so it may not match on startup and closing.