Sent out a new version, which moves the MFCopyImage() call into the format-specific if() statements. 32-bit, single plane formats are again the default 'else' case.
NV12 uses two MFCopyImage() calls.
I think this should be handling the stride correctly, for two reasons: - We're just getting the stride from MF_MT_DEFAULT_STRIDE, which I'd hope is correct. (Similarly, the destination stride comes from LockRect.) - The stride should be the same for the Y and UV planes (the fact that each of U and V are only half-width is cancelled out by the fact that there are two of them).
Every description of NV12 I can find says that the UV plane directly follows the Y plane, and is the same width, and half-height, so that seems to match this. There does appear to be a separate MFGetPlaneSize() function we maybe could use instead, but I've not looked into this.
My only real concern is around the width/height rounding: everything I've read agrees that the UV plane's size is taken by dividing the video size by 2 and rounding up, but I've not read anything on whether the Y plane's size is similarly rounded up to even. This code does so, but it's trivial to change it.
(Another option might be to just call something like MFCalculateImageSize(), then memcpy() the whole thing, instead of using MFCopyImage(). I've not tried that, but maybe it'd be a way of simplifying everything.)