mp4 recording (audio only) using media foundation okay on Win10 but finalize hangs on 11

Judy 0 Reputation points
2023-05-18T20:30:21.89+00:00

As part of a much larger project, I have a piece that records from the microphone to a number of different file formats. For MP4 (AAC) output, I use Media Foundation from a C# application to create a MP4 (AAC) recording. It works perfectly on Windows 10 (MF DLLs version 10.0.19041.1) but MP4 output hangs during finalization on Windows 11 (10.0.22621.1). It also works perfectly on both 10 and 11 for all formats except MP4.

Data is read in from the microphone in PCM format and delivered to whichever one of my various output writer classes is appropriate for the desired format. Code is C# using a wrapper based on MF.Net to talk to the Media Foundation COM objects for MP4 output.

Here is the creation code for the MP4 writer -- error checking is removed here but it is present in the code and all return values are success values.

MFStartup (0x20070, Full);

MFCreateMediaType (out IMFMediaType inputMediaType);
inputMediaType.SetGUID (MF_MT_MAJOR_TYPE, Audio);
inputMediaType.SetGUID (MF_MT_SUBTYPE, PCM);
inputMediaType.SetUINT32 (MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
inputMediaType.SetUINT32 (MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
inputMediaType.SetUINT32 (MF_MT_AUDIO_NUM_CHANNELS, 2);

MFCreateMediaType (out IMFMediaType outputMediaType);
outputMediaType.SetGUID (MF_MT_MAJOR_TYPE, Audio);
outputMediaType.SetGUID (MF_MT_SUBTYPE, AAC);
outputMediaType.SetUINT32 (MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
outputMediaType.SetUINT32 (MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
outputMediaType.SetUINT32 (MF_MT_AUDIO_NUM_CHANNELS, 2);

MFCreateAttributes (out IMFAttributes attributes, 1);
attributes.SetGUID (MF_TRANSCODE_CONTAINERTYPE, MPEG4);

MFCreateFile (ReadWrite, DeleteIfExist, None, filename, out IMFByteStream byteStream);
MFCreateMPEG4MediaSink (byteStream, null, outputMediaType, out IMFMediaSink mediaSink);
MFCreateSinkWriterFromMediaSink (mediaSink, attributes, out IMFSinkWriter sinkWriter);
// audio track stream added when sink writer created from sink
sinkWriter.SetInputMediaType (0, inputMediaType, null);

long currentPosition = 0;
sinkWriter.BeginWriting ();

Since the PCM input is delivered to the C# code in a native buffer and must feed into various file formats, I use a custom media buffer that inherits from IMFMediaBuffer and wraps the native buffer so I don't have to make a copy of the data. Here is the writing code that executes for each input buffer.

CustomMediaBuffer inBuffer = new CustomMediaBuffer (native buffer info);
MFCreateSample (out IMFSample sample);
sample.AddBuffer (inBuffer);

long durationConverted = (10000000L * native buffer length) / averageBytesPerSecond;
sample.SetSampleTime (currentPosition);
sample.SetSampleDuration (durationConverted);

currentPosition += durationConverted;
sinkWriter.WriteSample (0, sample);

There is a lock around both the write and close logic to prevent samples being added after the close is initiated. The close code is:

sinkWriter.Flush (0);
sinkWriter.Finalize_ ();
mediaSink.Shutdown ();

When this runs on Windows 10, everything works correctly to output the MP4 file. On Windows 11, the call to Finalize_ never returns -- no error, no crash, nothing in the event logs, just crickets.

Has anyone else encountered this or have any sort of suggestion to address the problem?

Thanks,

Judy

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
11,144 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,616 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
8,912 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Limitless Technology 44,101 Reputation points
    2023-05-19T11:06:39.3766667+00:00

    Hello Judy,

    Thank you for your question and for reaching out with your question today.

    The Finalize call is dependant on your version of .Net. It is possible that you need to install an older version of .Net in order for the call to function correctly on Windows 11.

    If the reply was helpful, please don’t forget to upvote or accept as answer.


  2. Judy 0 Reputation points
    2023-06-01T16:50:04.0966667+00:00

    I have solved the hang be removing the call to sinkWriter->Flush that was right before the call the sinkWriter->Finalize_. Given that Flush doesn't do anything that Finalize_ doesn't do when called by itself, there is no downside to not calling Flush. (Flush does not push the pending samples through the encoder - it drops them on the floor.) I've verified that the same processing happens at the end of a recording by comparing MFTrace logs from Windows 10 for the cases of with and without Flush.

    0 comments No comments