Standard memory allocator works in a way that you set allocator properties, that is fixed buffer size and buffer count, and then commit operator allocates real memory and you cannot change it. There are two issues with this approach: the first is that you choose buffer size before possibly starting reading real data, and the other one is that if small amount of samples need much larger buffers than other - which is typical with temporal compression formats like H.264 - then you need to have all buffers large and you need to allocate much more memory than you actually need.
There are several ways to address the problem.
The cleanest way is to implement custom memory allocator where you can allocate/reallocate buffers on runtime to satisfy unexpectedly large allocations. It is the output pin who chooses memory allocator, so you are in position to mount yours and you are good to go.
Another way which is more or less safe and which is used by some popular filters is to decommit and commit the allocator again on runtime when you need a larger buffer. That is, once you see on runtime that your payload does not fit the buffer, you decommit the allocator, update its properties, commit it back and continue as if nothing has happened at all. This normally works but is not as clean as the first method.
Then with many filters you can voluntary allocate non-allocator media sample and deliver it downstream. This is less safe, this is not how it was supposed to work in first place, but this works out well still in many scenarios.