Windows Media Foundation was introduced in Windows Vista as a future replacement for DirectShow, enhanced in Windows 7, and naturally, further enhanced in Windows 8. I’ve blogged about WMF before. While looking at the MSDN docs on WMF, it seems the content has not yet been updated for Windows 8. Windows 7 enhancements are considered there as such. Looking at the API reference, however, shows some new interfaces that are only supported starting with Windows 8.
One such interface is IMFMediaEngine and its extended version, IMFMediaEngineEx. The docs hint that the former interface is the playback interface used by the Internet Explorer 10 engine for video playback supported in HTML 5. These interfaces work with desktop and Store apps, as well as the new Windows Phone 8, making them all the more useful.
IMFMediaEngine simplifies the task of playing some video source. In classic WMF (prior to Windows 8), video playback required building a proper Topology (in WMF parlance), connecting a media source and a media sink… it wasn’t too difficult, but it was very verbose. IMFMediaEngine simplifies the task by requiring implementing just one interface, IMFMediaEngineNotify, that receives events occurring during playback. For very simple scenarios, the implementation of the primary method, EventNotify, can be empty. Technically, this is a COM interface, so must be implemented as such (IUnknown). Again, this works with Desktop as well as Store apps and Windows Phone 8 apps.
Here’s some simple code that starts a playback from some URL (error handling omitted for clarity):
::MFStartup(MF_VERSION); CComPtr<IMFMediaEngineClassFactory> spCF; spCF.CoCreateInstance(CLSID_MFMediaEngineClassFactory); CComPtr<IMFAttributes> spAttr; ::MFCreateAttributes(&spAttr, 0); spAttr->SetUINT64(MF_MEDIA_ENGINE_PLAYBACK_HWND, (UINT64)GetSafeHwnd()); spAttr->SetUnknown(MF_MEDIA_ENGINE_CALLBACK, this); hr = spCF->CreateInstance(0, spAttr, &m_spEngine); m_spEngine->SetSource(CComBSTR(L"c:\\temp\\movie.wmv")));m_spEngine->Play();
m_spEngine is a CComPtr<IMFMediaEngine>. The this value is the IMFMediaEngineNotify implementation (the object is an MFC dialog in this case). This code is considerably shorter than the equivalent WMF code required for Windows 7.
The extended interface, IMFMediaEngineEx, inherits from IMFMediaEngine and extends it beyond capabilities in the IE 10 usage by HTML 5. Notable additions in this interface are: adding video and audio effects (as MF Transforms) – InsertVideoEffect and InsertAudioEffect; setting the source as a byte stream (and just as a string URL) – SetSourceFromByteStream; FrameStep for frame single stepping; and tighter integration with DirectComposition (out of scope for this post) via GetVideoSwapchainHandle.
Another new interface in Windows 8 is IMFCaptureEngine, that simplifies the process of capturing video from a camera. This interface is only supported in Desktop apps. That’s reasonable, as the Windows Runtime has a good support for video (and audio) capture, using types in the Windows.Media.Capture namespace. Again, this could be done with Windows 7 level WMF, but requires much more setup with a topology, etc.
I only wish the documentation would get updated quickly. WMF never had comprehensive documentation, but perhaps a “decent” level will suffice.