'gstreamer pipeline for rtp audio forwarding to multiple sinks with different delays

:)

I'm trying to receive an rtp audio stream using gstreamer and forward it to multiple target hosts with different delays.

To insert a delay, I use the queue element with min-threshold-time as suggested here: https://stackoverflow.com/a/17218113/4881938 This works fine so far, however, if I want to have multiple output streams with different delays (or one with no delay at all), no data is set (i.e. the pipeline is paused) until the queue with the longest min-threshold-time is full.

This is not what I want - I want all forwarded streams to start as soon as possible, so if I have target1 one with no delay and target2 with 10s delay, target1 should receive data immediately, and not having to wait 10s.

I tried different sink options (sync=false, async=true) and tee option allow-not-linked=true to no avail; the pipeline remains paused until the longest delay in one of the queues.

What am I missing? How do I get gstreamer to activate the branch with no delay immediately? (and, in case I have multiple different delays: activate each delayed branch as soon as the buffer is full, not only after the longest buffer is filled?)

This is the complete test command I used:

% gst-launch-1.0 \
udpsrc port=10212 caps='application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS' ! \
tee name=t1 allow-not-linked=true \
    t1. ! queue name=q1 leaky=downstream max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=0 q1. ! \
  udpsink host=target1 port=10214 sync=false async=true \
    t1. ! queue name=q2 leaky=downstream max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=5000000000 q2. ! \
  udpsink host=target2 port=10215 sync=false async=true

version: GStreamer 1.18.4

sample pipeline

Thanks everyone for even reading this far! :)

According to @SeB 's comment, I tried out interpipes:

Thank you very much for your input. I tried it out, and it seems the problem is similar. If I omit the queue elements or don't set min-threshold-time to more than 0, it works, but as soon as I add any delay to one or more of the queue elements, the whole pipeline does nothing, the time counter never goes up from 0:00:00.0 I tried out different combinations of the interpipe sink/source options forward-/accept-events and forward-/accept-eos but it didn't change anything. What am I doing wrong? As I understand interpipe, it should decouple any sink/source elements from each other so one stalling pipe doesn't affect the rest(?).

command and output:

% gst-launch-1.0 \
udpsrc port=10212 caps='application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS' ! \
    interpipesink name=t1 \
interpipesrc listen-to="t1" ! queue leaky=downstream max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=5000000000 ! \
    udpsink host=targethost1 port=10214 async=true sync=false \
interpipesrc listen-to="t1" ! queue leaky=downstream max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=10000000000 ! \
    udpsink host=targethost2 port=10215 async=true sync=false
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
0:00:00.0 / 99:99:99..

I also tried shmsource/shmsink, but this also kinda fails -- as soon as I add a delay to one of the pipelines with the shmsource, it remains stuck in prerolling state:

shmsink:

% gst-launch-1.0 \
udpsrc port=10212 caps='application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS' ! \
    queue ! shmsink socket-path=/tmp/blah shm-size=20000000 wait-for-connection=false

shmsource (without is-live):

% gst-launch-1.0 \
shmsrc socket-path=/tmp/blah ! 'application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS' ! \
    queue leaky=downstream max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=5000000000 ! \
    udpsink host=targethost port=10215 async=true sync=false
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...

shmsource (with is-live):

% gst-launch-1.0 \
shmsrc is-live=true socket-path=/tmp/blah ! 'application/x-rtp,media=(string)audio,clock-rate=(int)48000,encoding-name=(string)OPUS' ! \
    queue leaky=downstream max-size-buffers=0 max-size-time=0 max-size-bytes=0 min-threshold-time=50 ! \
    udpsink host=targethost port=10215 async=true sync=false
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock

depending on setting is-live on the src, the behavior is different, but in both cases, no data is actually sent. without the min-threshold-time for the queue element, both shmsource commands work.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source