hi! I have implemented an abstraction on top of a sink pipeline to stream frames from cameras and I was wondering what would be the right approach to transfer data ownership from a gst::Buffer to a custom image struct.
Currently I have the following implementation which from a gst sample I get a readable map and because of that buffer holds a reference to the original data I couldn’t find the way to transfer the ownership of the underlying memory as my Image type has its own deallocation method and conflicts with the fact that gstreamer deallocates that memory resource once I hand the underlying data pointer to the new struct.
The memory is owned by the buffer (or more correctly by the gst::Memorys inside the buffer) and you can’t “take it out”. You also don’t generally know how it was allocated, how it can be freed, etc. so that wouldn’t work anyway.
What you can do is to map the buffer (or its gst::Memorys) and by that get access to the memory as &[u8] (or &mut [u8] if mapping writable).
There are two ways how you can do that
buffer.map_readable() gives you a gst::MapInfo which borrows from the buffer
buffer.into_mapped_buffer_readable() gives you a gst::MappedBuffer that behaves approximately like a Box<[u8]> (and e.g. implements AsRef<[u8]>) and you can pass it around
To have this wrapped by your Image struct you would have to make it generic over the storage of the data and e.g. have it accept any kind of AsRef<[u8]> so you can store a gst::MappedBuffer inside it.
If that’s not an option and your library wants to decide how memory is allocated, you either need to copy, or you can write a gst::Allocator that makes use of your library’s allocator and provide that to the pipeline. Depending on your pipeline, the data can be directly stored in memory allocated in that way then and you wouldn’t necessarily have to copy (note that exclusive ownership of the memory is still difficult to guarantee, depending on lots of details, and you might have to make use of reference counting).