UPDATE SUCCESS! see edit below
Some partial success, but perhaps enough to answer your question. Read please.
On my system, debugging an exception showed that when I tried to call TransferVideoFrame() the OnTimer() function OnTimer() . The error he gave was an InvalidArgumentException .
So, a bit of Googling led to my first discovery - obviously, a bug in the NVIDIA drivers - which means that video playback seems to have 11 and 10 levels of features.
So, my first change was in the CreateDX11Device() function as follows:
static const D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 };
Now TransferVideoFrame() still fails, but instead indicates E_FAIL (like HRESULT).
More googling led to my second discovery -
What an example was shown using TransferVideoFrame() without using CreateTexture2D() to pre-create the texture. I see that you already have code in OnTimer() similar to this but not used, so I think you found the same link.
In any case, I used this code to get the video frame:
ComPtr <ID3D11Texture2D> spTextureDst; m_spDX11SwapChain->GetBuffer (0, IID_PPV_ARGS (&spTextureDst)); m_spMediaEngine->TransferVideoFrame (spTextureDst.Get (), nullptr, &m_rcTarget, &m_bkgColor);
After that, I see that TransferVideoFrame() succeeds (good!), But the Map() call on your copied texture - m_spCopyTexture - fails because this texture was not created with read access to the CPU.
So, I just used your read / write m_spRenderTexture as the copy target instead, because it has the correct flags, and because of the previous change, I no longer used it.
Now, on my system, the OnTimer() function does not work. Video fragments are displayed in the texture, and pixel data is successfully copied to the memory buffer.
Before looking to see if there are any additional issues, this may be the right time to see if you can make the same progress as I still have. If you comment on this answer with additional information, I will edit the answer to add additional help, if possible.
EDIT
Changes to the texture description in FramePlayer::CreateBackBuffers()
Note also that there is a memory leak that needs to be cleaned up someday (I'm sure you know) - the memory allocated on the next line is never freed:
void* buffer = ::CoTaskMemAlloc(176 * 144 * 3); // sizes changed for my test
SUCCESS
I managed to save a separate frame, but now without using copy texture.
Firstly, I downloaded the latest DirectXTex library , which provides DX11 texture helper functions, for example, to extract an image from a texture and save it to a file. The instructions for adding the DirectXTex library to your solution as an existing project must be carefully followed, taking into account the changes necessary for the Windows 8 Store applications.
After the above library is enabled, FramePlayer.cpp and built, add the following #include to FramePlayer.cpp
#include "..\DirectXTex\DirectXTex.h"
Finally, the central section of code in FramePlayer::OnTimer() should look like the following. You will see that I just save one file name every time, so this will require changes, for example. frame number for name
I don’t have time right now to take this further, but I am very pleased with what I have achieved so far :-))
Can you take a fresh look and update your results in the comments?