Valmir Junior
Valmir Junior

Reputation: 137

Delaying a single branch of a tee by n seconds in a GStreamer pipeline

Assume a pipeline like the following:

videotestsrc +-> timeoverlay +-> tee +-> queue +-> autovideosink
                                     |
                                     +-> queue +-> autovideosink

The first branch of the tee must act as a passthrough, simply letting samples flow onto the rest of the pipeline. The second branch must be very similar, the only difference is that it should have a delay of n seconds relative to the first branch.

Unfortunately I have not been able to achieve this by myself.

I've tried setting the max-size-* and min-threshold-time properties of the queue (like suggested in this answer) of the second branch but it did not work.

I also tried to modify the running time of the second branch through queue.get_sink_pads().first().unwrap().set_offset(-5000000000) but alas, it also didn't work.

I also tried to attach a pad probe and retimestamp the buffers passing through the sink pad of the queue of the second branch to be n seconds in the future hoping that they would get retained on the queue until the running time of the pipeline caught up but it also didn't work (I imagine that it didn't work because even though the tee element creates separate branches, the buffers are still shared through a reference).

I've attached below a code snippet showing the progress I've made (which isn't much, to be honest).

Is it possible to achieve this behaviour without having to implement a plugin from scratch?


To try and implement this behaviour, I've begun by instantiating the basic elements ...

let videotestsrc = ElementFactory::make("videotestsrc", None)?;
let timeoverlay = ElementFactory::make("timeoverlay", None)?;
let tee = ElementFactory::make("tee", None)?;

... then I instantiated the pipeline ...

let pipeline = Pipeline::new(None);
pipeline.add(&videotestsrc)?;
pipeline.add(&timeoverlay)?;
pipeline.add(&tee)?;

... then I created the branches ...

{
    let queue = ElementFactory::make("queue", None)?;
    let autovideosink = ElementFactory::make("autovideosink", None)?;

    pipeline.add(&queue)?;
    pipeline.add(&autovideosink)?;

    tee.link(&queue)?;
    queue.link(&autovideosink)?;
}

{
    let queue = ElementFactory::make("queue", None)?;
    let autovideosink = ElementFactory::make("autovideosink", None)?;

    // queue.set_property_from_str("leaky", "downstream");
    // queue.set_property("max-size-buffers", &0u32)?;
    // queue.set_property("max-size-bytes", &0u32)?;
    // queue.set_property("max-size-time", &0u64)?;
    // queue.set_property("min-threshold-time", &5000000000u64)?;

    pipeline.add(&queue)?;
    pipeline.add(&autovideosink)?;

    tee.link(&queue)?;
    queue.link(&autovideosink)?;
}

The comments on the second branch are from an attempt I've made without success.

Upvotes: 0

Views: 745

Answers (1)

Sebastian Dröge
Sebastian Dröge

Reputation: 2143

I also tried to modify the running time of the second branch through queue.get_sink_pads().first().unwrap().set_offset(-5000000000) but alas, it also didn't work.

That's almost the solution: set a positive value and it should work. You're currently shifting it into the past. And in addition make sure to a) set the offset on the source pad of the queue, and b) that the queue can hold at least as much data as the offset you're setting.

Upvotes: 2

Related Questions