Media Foundation EVR no video displaying <p>I've been trying in vain to come up with a no frills example of displaying video using Microsoft's Media Foundation Enhanced Video Renderer (EVR). I'm testing on Windows 7 with Visual Studio 2013.</p> <p>I'm pretty sure I've got the media types configured correctly as I can export and save the buffer from the IMFSample in my read loop to a bitmap. I can also get the video to render IF I get MF to automatically generate the topology but in this case I need to wire up the source reader and sink writer manually so I can get access to the different parts of the pipeline.</p> <p>I have used mftrace to see if I can spot anything different between the automatically generated topology and the manually wired up example but nothing obvious jumps out.</p> <p>The code is below (full sample project at <a href="https://github.com/sipsorcery/mediafoundationsamples/tree/master/MFVideoEVR" rel="nofollow">https://github.com/sipsorcery/mediafoundationsamples/tree/master/MFVideoEVR</a>).</p> <p>Is there a step I've missed to get the IMFSample from the SinkWriter to display on the video window? I've been looking at a few examples that go deeper into the DirectX pipeline but should that be necessary or is the EVR meant to abstract those mechanics aways?</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;evr.h&gt; #include &lt;mfapi.h&gt; #include &lt;mfplay.h&gt; #include &lt;mfreadwrite.h&gt; #include &lt;mferror.h&gt; #include "..\Common\MFUtility.h" #include &lt;windows.h&gt; #include &lt;windowsx.h&gt; #pragma comment(lib, "mf.lib") #pragma comment(lib, "evr.lib") #pragma comment(lib, "mfplat.lib") #pragma comment(lib, "mfplay.lib") #pragma comment(lib, "mfreadwrite.lib") #pragma comment(lib, "mfuuid.lib") #pragma comment(lib, "Strmiids") #pragma comment(lib, "wmcodecdspuuid.lib") #define CHECK_HR(hr, msg) if (hr != S_OK) { printf(msg); printf("Error: %.2X.\n", hr); goto done; } void InitializeWindow(); // Constants const WCHAR CLASS_NAME[] = L"MFVideoEVR Window Class"; const WCHAR WINDOW_NAME[] = L"MFVideoEVR"; // Globals. HWND _hwnd; using namespace System::Threading::Tasks; int main() { CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); MFStartup(MF_VERSION); IMFMediaSource *videoSource = NULL; UINT32 videoDeviceCount = 0; IMFAttributes *videoConfig = NULL; IMFActivate **videoDevices = NULL; IMFSourceReader *videoReader = NULL; WCHAR *webcamFriendlyName; IMFMediaType *videoSourceOutputType = NULL, *pvideoSourceModType = NULL, *pSrcOutMediaType = NULL; IMFSourceResolver *pSourceResolver = NULL; IUnknown* uSource = NULL; IMFMediaSource *mediaFileSource = NULL; IMFAttributes *pVideoReaderAttributes = NULL; IMFMediaType *pVideoOutType = NULL; MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID; IMFMediaSink *pVideoSink = NULL; IMFStreamSink *pStreamSink = NULL; IMFMediaTypeHandler *pMediaTypeHandler = NULL; IMFMediaType *pMediaType = NULL; IMFMediaType *pSinkMediaType = NULL; IMFSinkWriter *pSinkWriter = NULL; IMFVideoRenderer *pVideoRenderer = NULL; IMFVideoPresenter *pVideoPresenter = nullptr; IMFVideoDisplayControl *pVideoDisplayControl = nullptr; IMFGetService *pService = nullptr; IMFActivate* pActive = NULL; MFVideoNormalizedRect nrcDest = { 0.5f, 0.5f, 1.0f, 1.0f }; IMFPresentationTimeSource *pSystemTimeSource = nullptr; IMFMediaType *sinkPreferredType = nullptr; IMFPresentationClock *pClock = NULL; IMFPresentationTimeSource *pTimeSource = NULL; CHECK_HR(MFTRegisterLocalByCLSID( __uuidof(CColorConvertDMO), MFT_CATEGORY_VIDEO_PROCESSOR, L"", MFT_ENUM_FLAG_SYNCMFT, 0, NULL, 0, NULL ), "Error registering colour converter DSP.\n"); Task::Factory-&gt;StartNew(gcnew Action(InitializeWindow)); Sleep(1000); if (_hwnd == nullptr) { printf("Failed to initialise video window.\n"); goto done; } // Set up the reader for the file. CHECK_HR(MFCreateSourceResolver(&amp;pSourceResolver), "MFCreateSourceResolver failed.\n"); CHECK_HR(pSourceResolver-&gt;CreateObjectFromURL( L"..\\..\\MediaFiles\\big_buck_bunny.mp4", // URL of the source. MF_RESOLUTION_MEDIASOURCE, // Create a source object. NULL, // Optional property store. &amp;ObjectType, // Receives the created object type. &amp;uSource // Receives a pointer to the media source. ), "Failed to create media source resolver for file.\n"); CHECK_HR(uSource-&gt;QueryInterface(IID_PPV_ARGS(&amp;mediaFileSource)), "Failed to create media file source.\n"); CHECK_HR(MFCreateAttributes(&amp;pVideoReaderAttributes, 2), "Failed to create attributes object for video reader.\n"); CHECK_HR(pVideoReaderAttributes-&gt;SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID), "Failed to set dev source attribute type for reader config.\n"); CHECK_HR(pVideoReaderAttributes-&gt;SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, 1), "Failed to set enable video processing attribute type for reader config.\n"); CHECK_HR(MFCreateSourceReaderFromMediaSource(mediaFileSource, pVideoReaderAttributes, &amp;videoReader), "Error creating media source reader.\n"); CHECK_HR(videoReader-&gt;GetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, &amp;videoSourceOutputType), "Error retrieving current media type from first video stream.\n"); Console::WriteLine("Default output media type for source reader:"); Console::WriteLine(GetMediaTypeDescription(videoSourceOutputType)); Console::WriteLine(); // Set the video output type on the source reader. CHECK_HR(MFCreateMediaType(&amp;pvideoSourceModType), "Failed to create video output media type.\n"); CHECK_HR(pvideoSourceModType-&gt;SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), "Failed to set video output media major type.\n"); CHECK_HR(pvideoSourceModType-&gt;SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), "Failed to set video sub-type attribute on EVR input media type.\n"); CHECK_HR(pvideoSourceModType-&gt;SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive), "Failed to set interlace mode attribute on EVR input media type.\n"); CHECK_HR(pvideoSourceModType-&gt;SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE), "Failed to set independent samples attribute on EVR input media type.\n"); CHECK_HR(MFSetAttributeRatio(pvideoSourceModType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1), "Failed to set pixel aspect ratio attribute on EVR input media type.\n"); CHECK_HR(CopyAttribute(videoSourceOutputType, pvideoSourceModType, MF_MT_FRAME_SIZE), "Failed to copy video frame size attribute from input file to output sink.\n"); CHECK_HR(CopyAttribute(videoSourceOutputType, pvideoSourceModType, MF_MT_FRAME_RATE), "Failed to copy video frame rate attribute from input file to output sink.\n"); CHECK_HR(videoReader-&gt;SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, pvideoSourceModType), "Failed to set media type on source reader.\n"); Console::WriteLine("Output media type set on source reader:"); Console::WriteLine(GetMediaTypeDescription(pvideoSourceModType)); Console::WriteLine(); // Create EVR sink . //CHECK_HR(MFCreateVideoRenderer(__uuidof(IMFMediaSink), (void**)&amp;pVideoSink), "Failed to create video sink.\n"); CHECK_HR(MFCreateVideoRendererActivate(_hwnd, &amp;pActive), "Failed to created video rendered activation context.\n"); CHECK_HR(pActive-&gt;ActivateObject(IID_IMFMediaSink, (void**)&amp;pVideoSink), "Failed to activate IMFMediaSink interface on video sink.\n"); // Initialize the renderer before doing anything else including querying for other interfaces (https://msdn.microsoft.com/en-us/library/windows/desktop/ms704667(v=vs.85).aspx). CHECK_HR(pVideoSink-&gt;QueryInterface(__uuidof(IMFVideoRenderer), (void**)&amp;pVideoRenderer), "Failed to get video Renderer interface from EVR media sink.\n"); CHECK_HR(pVideoRenderer-&gt;InitializeRenderer(NULL, NULL), "Failed to initialise the video renderer.\n"); CHECK_HR(pVideoSink-&gt;QueryInterface(__uuidof(IMFGetService), (void**)&amp;pService), "Failed to get service interface from EVR media sink.\n"); CHECK_HR(pService-&gt;GetService(MR_VIDEO_RENDER_SERVICE, __uuidof(IMFVideoDisplayControl), (void**)&amp;pVideoDisplayControl), "Failed to get video display control interface from service interface.\n"); CHECK_HR(pVideoSink-&gt;GetStreamSinkByIndex(0, &amp;pStreamSink), "Failed to get video renderer stream by index.\n"); CHECK_HR(pStreamSink-&gt;GetMediaTypeHandler(&amp;pMediaTypeHandler), "Failed to get media type handler.\n"); // Set the video output type on the source reader. CHECK_HR(MFCreateMediaType(&amp;pVideoOutType), "Failed to create video output media type.\n"); CHECK_HR(pVideoOutType-&gt;SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), "Failed to set video output media major type.\n"); CHECK_HR(pVideoOutType-&gt;SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), "Failed to set video sub-type attribute on EVR input media type.\n"); CHECK_HR(pVideoOutType-&gt;SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive), "Failed to set interlace mode attribute on EVR input media type.\n"); CHECK_HR(pVideoOutType-&gt;SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE), "Failed to set independent samples attribute on EVR input media type.\n"); CHECK_HR(MFSetAttributeRatio(pVideoOutType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1), "Failed to set pixel aspect ratio attribute on EVR input media type.\n"); CHECK_HR(CopyAttribute(videoSourceOutputType, pVideoOutType, MF_MT_FRAME_SIZE), "Failed to copy video frame size attribute from input file to output sink.\n"); CHECK_HR(CopyAttribute(videoSourceOutputType, pVideoOutType, MF_MT_FRAME_RATE), "Failed to copy video frame rate attribute from input file to output sink.\n"); //CHECK_HR(pMediaTypeHandler-&gt;GetMediaTypeByIndex(0, &amp;pSinkMediaType), "Failed to get sink media type.\n"); CHECK_HR(pMediaTypeHandler-&gt;SetCurrentMediaType(pVideoOutType), "Failed to set current media type.\n"); Console::WriteLine("Input media type set on EVR:"); Console::WriteLine(GetMediaTypeDescription(pVideoOutType)); Console::WriteLine(); CHECK_HR(MFCreatePresentationClock(&amp;pClock), "Failed to create presentation clock.\n"); CHECK_HR(MFCreateSystemTimeSource(&amp;pTimeSource), "Failed to create system time source.\n"); CHECK_HR(pClock-&gt;SetTimeSource(pTimeSource), "Failed to set time source.\n"); //CHECK_HR(pClock-&gt;Start(0), "Error starting presentation clock.\n"); CHECK_HR(pVideoSink-&gt;SetPresentationClock(pClock), "Failed to set presentation clock on video sink.\n"); Console::WriteLine("Press any key to start video sampling..."); Console::ReadLine(); IMFSample *videoSample = NULL; DWORD streamIndex, flags; LONGLONG llTimeStamp; while (true) { CHECK_HR(videoReader-&gt;ReadSample( MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, // Flags. &amp;streamIndex, // Receives the actual stream index. &amp;flags, // Receives status flags. &amp;llTimeStamp, // Receives the time stamp. &amp;videoSample // Receives the sample or NULL. ), "Error reading video sample."); if (flags &amp; MF_SOURCE_READERF_ENDOFSTREAM) { printf("End of stream.\n"); break; } if (flags &amp; MF_SOURCE_READERF_STREAMTICK) { printf("Stream tick.\n"); } if (!videoSample) { printf("Null video sample.\n"); } else { printf("Attempting to write sample to stream sink.\n"); CHECK_HR(videoSample-&gt;SetSampleTime(llTimeStamp), "Error setting the video sample time.\n"); //CHECK_HR(videoSample-&gt;SetSampleDuration(41000000), "Error setting the video sample duration.\n"); CHECK_HR(pStreamSink-&gt;ProcessSample(videoSample), "Streamsink process sample failed.\n"); } SafeRelease(&amp;videoSample); } done: printf("finished.\n"); getchar(); return 0; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, uMsg, wParam, lParam); } void InitializeWindow() { WNDCLASS wc = { 0 }; wc.lpfnWndProc = WindowProc; wc.hInstance = GetModuleHandle(NULL); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszClassName = CLASS_NAME; if (RegisterClass(&amp;wc)) { _hwnd = CreateWindow( CLASS_NAME, WINDOW_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, GetModuleHandle(NULL), NULL ); if (_hwnd) { ShowWindow(_hwnd, SW_SHOWDEFAULT); MSG msg = { 0 }; while (true) { if (PeekMessage(&amp;msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&amp;msg); DispatchMessage(&amp;msg); } else { Sleep(1); } } } } } </code></pre>