Shared Gst.Buffers make .Dispose() unusable
Submitted by Petteri Aimonen
Link to original bug (#677708)
Description
GStreamer shares buffers between sinks to conserve memory. Gst-sharp returns the same managed object when two sinks receive the buffer. If one sink disposes the object, the other sink gets NullReferenceException.
Obvious way to avoid this problem is not to call .Dispose(), and instead rely on garbage collection. However, this causes a lot of buffers to accumulate before GC kicks in. I measured 100 MB memory overhead on an otherwise 50 MB usage with a simple videotestsrc + appsink combination. With many streams and larger resolution/framerate it could be much worse.
(The same problem exists with shared Glib.Object references, but it is much less acute as they are not circulated as often as Gst.Buffers.)
There are two ways to fix this problem:
- Make Gst.MiniObject not shared. This might have some implications if complex C# objects are built upon MiniObject, as there would be multiple managed instances referring a single unmanaged object. However, all the currently implemented MiniObject derivatives (Buffer, Event, Message, etc.) are simple wrappers with no managed data.
Implemented by this patch: http://code.google.com/p/ossbuild-vs2010/source/detail?r=cdcfefd5b9652a8910f0b27449cb5a7682aa69ce
- Make Gst.MiniObject maintain a count of 'users', a bit like reference counting but not directly tied to the destruction of the underlying unmanaged object. This is less clean than 1, but on the other hand less intrusive.
Implemented by this patch: http://code.google.com/p/ossbuild-vs2010/source/detail?r=6ced992458f96e3b5bf8eb25d81a2ce8808081a9
I vote for 1).