Bin with one filesink won't preroll
t.i.m at zen.co.uk
Fri Aug 5 00:09:04 UTC 2022
Some quick random comments, haven't tried your code:
> 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.
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.
> 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)
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.
More information about the gstreamer-devel