Search code examples
pythonpython-3.xgstreamergstreamer-1.0python-gstreamer

GStreamer zero copy read only buffer duplication


I have a GStreamer pipeline with an appsink

filesrc location=test.mp4 ! decodebin ! video/x-raw ! queue max-size-bytes=0 max-size-time=100000000 ! appsink name=appSink sync=false max-buffers=1 drop=false

I pull a sample from the appsink then I get the buffer, map it read-only and store the map info (to access raw memory later).

sample: Gst.Sample = self.__sink.pull_sample()
self.__buffer: Gst.Buffer = sample.get_buffer()
self.__buffer_map: Gst.MapInfo = self.__buffer.map(Gst.MapFlags.READ)

Then I would like to use the same data (without copying it) in an output pipeline for e.g.:

appsrc name=appSrc block=true ! video/x-raw,format=(string)NV12,width=1920,height=1080,framerate=30/1 ! videoconvert ! ximagesink

To do this it is the best I could come up with:

shared_buffer_memory = self.__buffer.get_all_memory()
buf = Gst.Buffer.new()
buf.insert_memory(-1, shared_buffer_memory)
self.__src.push_buffer(buf)
#sleep(0.05) 

If I do this I see the first frame correctly but all the other frames are green. It is fine, because the underlying memory of buf goes out of scope and freed meanwhile. If I put sleep(0.05) after push_buffer it displays all of the frames, but I think the memory behind the buffer is double-freed:

** (python3.9:6745): CRITICAL **: 09:23:54.645: gst_vaapi_image_unmap: assertion 'image != NULL' failed

I would like to get the frames from the appsink then push them into output pipelines without copy. What would be the best approach to do this? (a single pipeline is not suitable in my case).


Solution

  • The answer is not mine, I got it on the #gstreamer IRC channel:

    The documentation says the following:

    AppSrc.push_buffer(buffer): Adds a buffer to the queue of buffers that the appsrc element will push to its source pad. This function takes ownership of the buffer.

    This was what misled me. In Python one should easily push the same buffer to multiple AppSrcs.