I have difficulty understanding how to work with different types of surfaces. I successfully set up a DECODE -> system memory -> VPP -> system memory chain, using no external allocator, but when I attempt to change it to DECODE -> video memory -> VPP -> system memory, things break left and right.
First, it appears that a session can only have one external frame allocator, set through MFXSession::SetFrameAllocator. But clearly if we are using two different types of surfaces, the same frame allocator cannot be used for both, unless I am mistaken?
I currently have set up a chain like this: DECODE -> video memory -> VPP -> system memory. I have used SetFrameAllocator with the D3D11 allocator. I call RunFrameVPPAsync with the output surface from the decoder and a frame allocated with a SysMemFrameAllocator, and then Sync on the sync point I called it with.
The first thing I noticed is that if I simply do this, a Lock() operation fails on a D3D11 frame. I noticed that this is called
mfxStatus D3D11FrameAllocator::LockFrame(mfxMemId mid, mfxFrameData *ptr)
Here "mid" is the value of the system memory frame, not the D3D11 frame! So of course this fails and returns MFX_ERR_LOCK.
I tried setting the "mid" of the system memory frame to the value of the input D3D11 frame, and then everything returns MFX_ERR_NONE, but no data gets actually copied into my output frame. It's empty. I noticed that Lock doesn't even get called on my output frame.