Soonts Soonts - 11 days ago 6
C++ Question

MF doesn't play video from my source

I’m developing a media foundation-based h264 player to play h264 video and HE-AAC audio from my own custom media source.

My prototype doesn't play video, only audio.
How to fix that?

Here's the problem. I open my URL.

The framework creates and initializes my media source, which in turn creates and initializes my 2 streams, audio and video.

Then it asks for video samples until the end of the file is reached.
The log is filled with CMFTransformDetours::ProcessOutput failed hr=0xC00D6D72 MF_E_TRANSFORM_NEED_MORE_INPUT

Then after my video stream sends MEEndOfStream, the framework asks for a few more audio samples, finally transitions the state to playing, and starts to play audio only.

What does the framework tries to find in my video stream that isn’t there?

The same file plays OK by the same player code if opened by the built-in stream source.
mftrace.exe says when the built-in stream source plays the file, the first video sample is 38 bytes longer then when my stream source plays it (all other samples are exactly the same length).
38 bytes is exactly the size of my MF_MT_MPEG_SEQUENCE_HEADER for my video (i.e. 00 00 01 + SPS + 00 00 01 + PPS). I’ve tried to prepend MF_MT_MPEG_SEQUENCE_HEADER value to my first frame, didn’t help.

System-provided stream source sets undocumented attribute on video samples, GUID = {19124E7C-AD4B-465F-BB18-20186287B6AF}, values are 8-bytes binary values like “09 00 00 00 29 0d 00 00”, and change each frame — what’s that and can it be the reason?

What else can I try?

Is there any documentation on what exactly does the MF h264 decoder wants on input?

Thanks in advance.

Answer

There were two major problems in my code.

  1. My stream source didn’t output those attributes with GUID = {19124E7C-AD4B-465F-BB18-20186287B6AF} The attribute is documented, just the MFTrace.exe logging tool isn't aware so it prints GUID instead of name. The GUID stands for MF_NALU_LENGTH_INFORMATION attruibute.

My video stream descriptor had MF_NALU_LENGTH_SET attribute set to TRUE. That's why h264 decoder skipped all my video samples - it looked for MF_NALU_LENGTH_INFORMATION attribute on them, and it wasn't there.

Simple way to fix — remove MF_NALU_LENGTH_SET from the descriptor, the decoder is OK without that data.

  1. For this prototype, I read video samples from .mp4 container. NALUs in the container are preceded by their length in bytes. The MS decoder requires NALUs to be preceded by the start code "00 00 00 01". See this SO answer for more information about that. In the samples I feed to decoder, I had to replace NALU lengths with "00 00 00 01".