Media Foundation’s MFT_MESSAGE_SET_D3D_MANAGER with Frame Rate Converter DSP

It might look weird why would someone try Direct3D mode with a DSP, which is not supposed to be Direct3D aware, but still. I am omitting the part why I even got to such scenario. The documentation says a few things about MFT_MESSAGE_SET_D3D_MANAGER:

  • This message applies only to video transforms. The client should not send this message unless the MFT returns TRUE for the MF_SA_D3D_AWARE attribute (MF_SA_D3D11_AWARE for Direct3D 11).
  • Do not send this message to an MFT with multiple outputs.
  • An MFT should support this message only if the MFT uses DirectX Video Acceleration for video processing or decoding.
  • If an MFT supports this message, it should also implement the IMFTransform::GetAttributes method and return the value TRUE…
  • If an MFT does not support this message, it should return E_NOTIMPL from ProcessMessage. This is an exception to the general rule that an MFT can return S_OK from any message it ignores.

Frame Rate Converter DSP is a hybrid DMO/MFT, which in turn basically means that its “legacy” DMO upgraded to MFT using specialized wrapper. It is not supposed to be Direct3D aware, not documented as such.

However it could presumably normalize frame rate of Direct3D aware samples by dropping/duplicating samples respectively. It could easily be Direct3D aware since it does not need, in its simplest implementation, to change the data. It is easy to see that the MFT satisfies the other conditions: it is single output video transform.

The MFT correctly and expectedly does not advertise itself as Direct3D aware. It does not have transform attributes.

However, it fails to comply with documented behavior on returning E_NOTIMPL in MFT_MESSAGE_SET_D3D_MANAGER message. The message is defined to be an exception, however DSP implementation seems to be ignoring that. The wrapper could possibly be created even before the exception was introduced in first place.

The DSP does not make an exception, returns success code as if it does handle the message, and does not act as documented.

Intel Quick Sync Video Consumption by Applications

I wrote a few posts on hardware H.264 encoding (e.g. this and the latest one Applying Hardsubs to H.264 Video with GPU). A blog reader asked a question regarding availability of the mentioned Intel Quick Sync Video support with low end Intel x5-Z8300 CPU.

[…] Intel has advertised that the Cherry Trail CPUs support H264 encoding and / or QSV, but nowhere have I seen a demo of this being used […].
What did you use to encode the video? Is the QSV codec available in the x5-z8300 for possible 720p realtime encoding? I’d like to see this checked in regards to using software like FFmpeg with qsv_h264 -codec and OBS. […]

A picture below explains how applications are consuming Intel’s hardware video compression offering in Windows.

Intel QSV includes hardware implementation of the encoder and corresponding drivers which provide a frontend API to software. This includes a component which integrates the codec with Microsoft’s Media Foundation API. Applications are to choose between interfacing the codec using Windows API – this is the way stock Microsoft applications work, and this is the way I used for video encoding development mentioned on the blog. Other applications prefer to interface through Intel Media SDK, which is an alternate route ending up at the same hardware-backed services.

Intel x5-Z8300 system in question has H.264 video encoding support integrated into Windows API and the services can be consumed without additional Intel runtime and/or development kit. The codec, according to the benchmarks made earlier, is fast enough to handle real-time 720p video encoding nevertheless the device is a budget thing.

Bug in Media Foundation MPEG-4 File Source related to timestamping video frames of a fragmented MP4 file

Some recent update in Media Foundation platform introduced a new bug related to fragmented MP4 files and H.264 video. The bug shows up consistently with file versions:

  • mfplat.dll – 10.0.14393.351 (rs1_release_inmarket.161014-1755)    15-Oct-16 05:48
  • mfmp4srcsnk.dll – 10.0.14393.351 (rs1_release_inmarket.161014-1755)    15-Oct-16 05:45

The nature of the problem is that MPEG-4 File Source is incorrectly time stamping the data: frame time stamps are incorrect, they seems to be getting wrong durations and increments, then quickly jumps into future… and on playback this leads to unobvious playback freezes. As Media Foundation is used by Windows Media Player, Windows 10 Movies & TV Player, the bug is present there as well.

The original report is on MSDN Forums.

Presumably it is possible to roll certain Windows Update package back, or alternatively one has to wait for Microsoft to fix the problem and deliver a new update deploying the fix.

Applicability of Virtual DirectShow Sources

Virtual DirectShow  sources have been a long time synonym of software-only camera implementation exposed to applications along with physical cameras in a way that applications consume the sources without making a difference whether the camera is real or virtual. Vivek’s template was a starting point for many:

Capture Source Filter filter (version 0.1) 86 KB zipped, includes binaries.  A sample source filter that emulates a video capture device contributed by Vivek (rep movsd from the public newsgroups).  Thanks Vivek!  TMH has not tested this filter yet.  Ask questions about this on microsoft.public.win32.programmer.directx.video.

With API changes over years, the sample and the concept is still understood as the method of adding a virtual camera, however new scenarios exist where the concept no longer works. Typical problems:

  1. 64-bit applications cannot consume virtual 32-bit virtual sources
  2. Virtual sources are no visible and accessible to applications consuming video using Media Foundation API

The diagram below explains the applicability of virtual cameras:

Applicability of Virtual DirectShow Sources

Important is that virtual sources can only be consumed by the DirectShow-based applications of the same bitness.

If source developer needs to synchronize virtual source throughout multiple applications (e.g. video is synthesized by another application and needs to be deliverable to multiple clients), he needs to add interprocess synchronization on the backyard of virtual source.

If developer needs to support both 32- and 64-bit apps, he needs both variants of virtual sources registered, and possibly synchronization of the kind of the paragraph above.

The only virtual device which is visible to all video capture applications if implemented by kernel level driver (implementations are rare but exist).

See also:

KB3176938’s Frame Server update visually

  1. M-JPEG and H.264 media types are available again (good)
  2. Nevertheless connected, H.264 video is not processed correctly; new bug or old one? Not clear. Even though it sort of works, in DirectShow it looks broken in another new way (this and not just this), perhaps a collateral damage and maybe never ever fixed…
  3. There is no camera sharing between the applications even though it was the justification for the changes in first place. For now Frame Server is just useless overhead, which adds bad stuff, is polished a bit to do not so much harm, and maybe turns to be good some time later.
    • for the record, the camera works in Skype when it is not consumed elsewhere concurrently

BTW the hack that bypasses FrameServer survived the update and remains in good standing.

DirectShowCaptureCapabilities and MediaFoundationCaptureCapabilities: API version of EnableFrameServerMode state

Both tools now include exact version of the API and also include an export or registry key related to frame server.

Capture Capabilities: API Version and State

mfcore.dll version of 10.0.14393.105 corresponds to Cumulative Update for Windows 10 Version 1607: August 31, 2016 also known as KB3176938 with DirectShow and Media Foundation improvement for Windows 10 Anniversary Update that restores availability of compressed media types.

See:

Enumeration of DirectShow Capture Capabilities (Video and Audio)

Media Foundation Video/Audio Capture Capabilities

Number of streams served by IMFSourceReader interface

It looks confusing that IMFSourceReader interface does not offer a dedicated method to find out the number of streams behind it. There is a IMFMediaSource instance behind the reader, and its streams are available through IMFMediaSource::CreatePresentationDescriptor method and IMFPresentationDescriptor::GetStreamDescriptorCount method call.

I am under impression that source reader’s method just has to be there even though I am not seeing it looking at the list of methods. Okay, there are other methods, namely IMFSourceReader::GetStreamSelection method, which takes either ordinal stream index or an alias as the first argument, then returns MF_E_INVALIDSTREAMNUMBER if you run out of streams. However the problem is that this is associated with an internal exception, and I consider exceptions as exceptional conditions the code should not normally hit. I would expect to have a legal exception-free way to find out the number of streams. I am using debugger that breaks on exception or at least pollutes output log for no reason, I use other tools that intercept and log exceptions as something that needs attention – getting number of streams is nowhere near there.

Internal MF_E_INVALIDSTREAMNUMBER Exception

Even though it is not a real drawback of the API since it is still possible to get the data and the API acts as documented, I still think someone overlooked this and API like this should have have a normal method or argument to request number of streams explicitly. Or I am just not seeing it even though I am trying thoroughly.