Bin with one filesink won't preroll

Simon Guillot simon at vivid-machines.com
Wed Aug 3 21:53:12 UTC 2022


Hi there –

It seems a bit recurrent, but I too have issues with pre-rolling...
I have a rather complex (live) pipeline, and from time to time I need to take snapshots. The pipeline needs to remain in playing state at all times.
I have read from the documentation that to avoid a state change of the pipeline, all added elements need to be in playing state before adding them to the pipeline.

My process for adding my snapshot bin is:
- Create the bin (in the simplest form ` videoconvert ! pngenc snapshot=true ! filesink location=/tmp/snapshot.png`)
- Set its state to PAUSED
- Send EOS to each sink
- Add to the pipeline (another bin in my case)
- Sync state with parent
- Link to source (a tee with allow-not-linked=true)

Here's a Rust test of the pre-rolling described above. It fails at the state check towards the end, as the bin remains in "READY -> PAUSED".

> gst::init().unwrap();
>
> let snapshotbin = gst::parse_launch(
>     "bin. ( videoconvert ! pngenc snapshot=true ! filesink location=/tmp/snapshot.png )"
> ).unwrap().downcast::<gst::Bin>().unwrap();
>
> match snapshotbin.set_state(gst::State::Paused).unwrap() {
>     gst::StateChangeSuccess::Async => {
>         println!("Prerolling snapshotbin");
>         let mut iter = snapshotbin.iterate_sinks();
>         loop {
>             match iter.next() {
>                 Ok(Some(sink)) => {
>                     println!("Sending EOS to {}", sink.name());
>                     assert!(sink.send_event(gst::event::Eos::new()));
>                 }
>                 Ok(None) => break,
>                 Err(gst::IteratorError::Resync) => iter.resync(),
>                 Err(gst::IteratorError::Error) => panic!("Error while iterating over sinks"),
>             }
>         }
>     }
>     _ => println!("No preroll needed")
> }
>
> let (res, state, _) = snapshotbin.state(gst::ClockTime::from_seconds(5));
> assert_eq!(res.unwrap(), gst::StateChangeSuccess::Success);
> assert_eq!(state, gst::State::Paused);

My snapshot bin is actually a custom bin that is a bit more complex than this example, but it seems to show the problem quite well.
I tried sending EOS to the whole bin but it puts it in a state that makes it unusable, I suspect because of snapshot=true on pngenc.
In case that's of any use, I'm using GStreamer 1.20.3.

What am I doing wrong?

Simon


More information about the gstreamer-devel mailing list