2
votes

I am building a DirectShow Filter in Delphi 6 Pro using the DSPACK DirectShow component library. In their Push Source Filter example, for some items they use CoTaskMemAlloc(), especially with allocating memory for items used in Windows API calls such as video bitmap info headers (PVIDEOINFOHEADER) and buffers used in O/S file operations such as ReadFile, etc. Other items are allocated using the usual (Object).Create() call or by creating dynamic arrays directly.

What are the rules/guidelines for when you must use CoTaskMemAlloc() inside a DirectShow filter?
This SO reply by @Vinay gives the succinct answer that it should be used with any memory that will crosses process boundaries:

Usage of CoTaskMemAlloc?

But I would like to know if there are any common memory allocation mistakes I am likely to make in my DirectShow filter, especially when rendering or providing data via input/output pins, due to my failure to use CoTaskMemAlloc().

2
I don't see why CoTaskMemAlloc would help with memory that crosses process boundaries. My understanding is that you use CoTaskMemAlloc whenever you pass ownership of memory to another COM object.David Heffernan

2 Answers

3
votes

CoTaskMemAlloc is part of the COM memory allocator. It is used with CoTaskMemRealloc and CoTaskMemFree.

The COM memory allocator is designed to allow a COM client to allocate memory that is later freed by the COM server or vice versa. You only need to use it when ownership of the memory is transferred across the COM client/server boundary.

This solves a very common interop problem. Different programming systems have different implementations for heaps. Consequently memory allocated on one heap can only be deallocated on the same heap. If you have a COM method that returns a string, say, you have a problem. If the server and client use different heaps you now need to ask the server to deallocate the string when you are done with it. The COM allocator solves this by virtue of being a single, shared heap that all participants can use.

Having said this it should come as no surprise to learn that a BSTR, i.e. what is called WideString in Delphi, is allocated with the COM allocator.

I'm not familiar with the DirectShow interfaces but the principles of COM are universal. When you implement GetMediaType in your server you must allocate the struct that is returned. Since the client has to free that struct, as specified in the documentation, clearly you must use the COM allocator since that is what your clients will use.

You also mentioned ReadFile. No point at all using COM allocator here since the caller is responsible for both allocating and freeing the buffer.

The bottom line is that COM is an interface contract. If a pointer crosses the interface boundary and has ownership transferred from client to server, or vice versa, then the COM allocator must be used.

1
votes

You MUST use CoTaskMemAlloc for any allocation of memory in COM that will be passed to the outside world. Directshow filtrers use COM and pass the buffers from filter to filter to avoid copying the data.