Question
I have a managed class written in C# that implements a native COM interface. Instances of this class are passed to native code. Is it possible to override AddRef() and Release() to track the COM reference count? If not, then is there any other way to determine when all native references have been released (when the only reference left is the RCW managed reference)?
Background
I have a camera device and a managed API to access the video data captured by the camera. I have created a C# program which uses P/Invoke and COM interop to render and encode the video data using Windows MediaFoundation and created a managed class implementing a custom IMFMediaSource. This all works.
The problem is that the performance of my current implementation is terrible and my workstation can barely keep up with 30 frames of video a second. The camera is capable of capturing at 60 fps.
Currently I am doing the following for every single video frame:
- Call MFCreateSample to create an IMFSample
- Call MFCreateMemoryBuffer to create an IMFMediaBuffer
- Copy video data from managed source to the native IMFMediaBuffer
- Attach buffer to sample
- Raise the MEMediaSample event
This works but memory usage of the application starts at around 40 MiB and very quickly rises to over 2 GiB and then the entire application freezes for a second as the garbage collector kicks in and collects the RCW references to hundreds of IMFSample and IMFMediaBuffer objects and then the memory drops back down to around 40 MiB.
So, to avoid the rediculuous overhead of allocating new buffers and copying the video data for every frame I would like to implement my own IMFSample and IMFMediaBuffer in managed code and reuse these objects. But I need determine when the rest of the MediaFoundation pipeline is finished using the IMFSample (when COM reference count drops to 1 indicating only the managed RCW reference remains) so that I know when it is safe for me to reclaim and reuse the sample and buffer objects. Is there any other way to determine when the rest of MediaFoundation is done using an IMFSample other than by tracking COM reference count?