媒体基础 MP4 编码:IMFSinkWriter 不接受 PCM 输入

Media Foundation MP4 Encoding: IMFSinkWriter doesn't accept PCM input

我正在使用 Windows Media Foundation 对 H264 视频进行编码。 (我使用 MFNet Wrapper 通过 C# 使用它)。

视频编码完美。我拿出一个带H264视频的MP4。

现在我尝试添加音频。我想从内存中传入未压缩的 PCM,然后输出编码的 AAC。我将音频流添加到我的 SinkWriter。 ö但是当调用 SetInputMediaType 时,我得到 MF_E_INVALIDMEDIATYPE

这是为什么?

这是我的代码:

IMFMediaType audioTypeOut, audioTypeIn, videoTypeOut, videoTypeIn;
IMFSinkWriter sinkWriter;

Check = MFCreateSinkWriterFromURL(outputFile.Replace(".avi",".mp4"), null, attributes, out sinkWriter); // the assignment to "Check" throws an exception if a method fails.

//[ ... setup video input & output - works perfectly ...]
Check = sinkWriter.AddStream(videoTypeOut, out videoStreamIndex);
Check = sinkWriter.SetInputMediaType(videoStreamIndex, videoTypeIn, null);

// Now setup Audio:
// Input PCM from memory
Check = MFExtern.MFCreateMediaType(out audioTypeIn);
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio);
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.PCM); // this .PCM enum value is equal to MFAudioFormat_PCM in the C++ api (I checked)
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BLOCK_ALIGNMENT, 4);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 * 4);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_ALL_SAMPLES_INDEPENDENT, 1);

// and output AAC to the MP4 file
Check = MFExtern.MFCreateMediaType(out audioTypeOut);
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio);
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.AAC);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_ALL_SAMPLES_INDEPENDENT, 0);

// pass it to the sinkWriter
Check = sinkWriter.AddStream(audioTypeOut, out audioStreamIndex);
Check = sinkWriter.SetInputMediaType(audioStreamIndex, audioTypeIn, null); // this call fails

现在,当我尝试传入 AAC 时,设置代码运行良好。让我觉得我错误地配置了 PCM IMFMediaType,但我无法发现错误。

音频媒体类型可以这样初始化:

// Input PCM from memory
Check = MFExtern.MFCreateMediaType(out audioTypeIn);
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio);
Check = audioTypeIn.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.PCM);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
Check = audioTypeIn.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16);

// and output AAC to the MP4 file
Check = MFExtern.MFCreateMediaType(out audioTypeOut);
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_MAJOR_TYPE, MFMediaType.Audio);
Check = audioTypeOut.SetGUID(MFAttributesClsid.MF_MT_SUBTYPE, MFMediaType.AAC);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_NUM_CHANNELS, 2);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
Check = audioTypeOut.SetUINT32(MFAttributesClsid.MF_MT_AUDIO_BITS_PER_SAMPLE, 16);

将派生其他属性,并且在您的原始代码片段中错误使用 MF_MT_ALL_SAMPLES_INDEPENDENT 会阻止编解码器的初始化。