Bin with one filesink won't preroll

Simon Guillot simon at
Fri Aug 5 14:40:32 UTC 2022


Thanks for answering!

On 5 Aug 2022, at 02:09, Tim-Philipp Müller <t.i.m at<mailto:t.i.m at>> wrote:

The mechanism is usually to only state change of the new elements once
they're inside the pipeline, but set sink elements to async=false so
they don't do the usual asynchronous state change / preroll dance.

By adding I meant "linking". I believe what you described is what I've been doing: add,
set state, link?

`async=false` indeed solves the issue of having the pipeline change its state when linking. That leaves
me with two questions though:
- Is there no way to achieve an insertion without putting back the pipeline in preroll mode with `async=true`?
- If that doesn't change the overall behaviour, on what occasions would I even want to keep `async=true`?

Adding to my initial example, I'm starting with the following pipeline:

videotestsrc is-live=true \
        ! tee name=tee allow-not-linked=true

Once the pipeline is started, I add/set state/link the following bin:

bin. ( videoconvert ! \
pngenc snapshot=true ! \
filesink async=false location=/tmp/snapshot.png )

That works well. EOS is reached and I can catch it from the filesink. However if I add a queue before
the videoconvert element, filesink seems to never posts EOS:
- pngenc has the same behaviour (GST_FLOW_EOS after the first buffer)
- file is created but empty
- only if I politely terminate the pipeline by setting it to null, the file will be written and contain the snapshot

I've tried various combinations of properties for the queue without success (flush-on-eos, max-size of 1 buffer, leaky, ...).
It still works if I link before starting the pipeline...

What's going on?

(I need the queue because the real use case is a bit more complex and I have various snapshots happening in
different formats.)

My suggestion would be this:

1. Have a branch with a fakesink (or fakesink async=false if buffer
flow is not assured) that's always in the pipeline and receives the
latest raw video buffers on a regular basis.

2. When you want to take a snapshot, you retrieve the last video frame
from the fakesink via the "last-sample" property. This gives you a
GstSample with the last raw video buffers plus the caps etc.

3. You can then pass that GstSample to gst_video_convert_sample() or
gst_video_convert_sample_async() to encode it to png or jpeg
(optionally also scale or adjust the aspect ratio).

4. You then get back a new GstSample with the encoded image. Just map
the buffer and write it to file yourself or with g_file_set_contents().

Not as fancy, but should work just fine and should be fairly robust.

Looks good, thanks for suggesting that! However we also have the same process for recording
samples instead of snapshots so I'll run into problems there as well if I can't find a solution that works
for both.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the gstreamer-devel mailing list