Microsoft DirectX 8.1 (C++) |
To better understand the allocation model for a transform-in-place filter, the following illustration shows a simple and common example of a filter graph.
This simple example demonstrates the model of the transform-in-place filter offering its downstream allocator to its upstream filter. Consider what happens when InPlace E is connected to VidRen F.
Upon connection, the video renderer filter (VidRen F) offers its allocator for use by the upstream in-place filter (InPlace E). Because it is a transform-in-place filter, InPlace E offers the allocator to the next filter upstream, InPlace D, and so on. This reconnection and renegotiation occurs until it encounters either the source filter or a copy transform filter. In this case it meets a decompressor, CopyDec C. (The copy transform filter cannot offer its allocator upstream, because it must perform a copy operation.) So the decompressor will write directly to the video renderer's buffer, which might be a DirectDraw® surface. This demonstrates why it is a good practice to write a transform filter as a transform-in-place filter and pass allocators from the renderer upstream, if possible.
On the other hand, consider filters InPlace B and CopyDec C. What if the downstream filter from a transform-in-place filter is a copy transform filter instead of a renderer? In this case, the copy transform filter will offer to create its own allocator on its input pin (the base classes handle this), and the transform-in-place filter can then offer that allocator downstream upon reconnection (the same as if it were connected to a renderer filter).
However, even though CopyDec C can create its own allocator (from its IMemInputPin::GetAllocator method), the source filter, Source A, uses its own buffer - say, a file. So when InPlace B connects to CopyDec C, InPlace B will have accepted the source filter's allocator already and will force that allocator to be used for the transport between itself and the decompressor filter. InPlace B can then provide the upstream filter, Source A, with the option of using the allocator offered by CopyDec C, but the source filter will refuse this allocator so that an extra copy does not have to be made from the file buffer to the decompressor's input buffer.
Therefore, any upstream filter can force the use of its allocator downstream but should have good reason to do so (such as if it already has a buffer). In this example, only one copy is being made (by the decompression filter) between the file buffer and the video memory.