媒体基础 MP4 编码:IMFSinkWriter 不接受 PCM 输入
Posted
技术标签:
【中文标题】媒体基础 MP4 编码:IMFSinkWriter 不接受 PCM 输入【英文标题】:Media Foundation MP4 Encoding: IMFSinkWriter doesn't accept PCM input 【发布时间】:2017-01-03 16:05:28 【问题描述】:我正在使用 Windows Media Foundation 对 H264 视频进行编码。 (我通过 C# 使用 MFNet Wrapper)。
视频编码完美运行。我拿出一个带有 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,但我无法发现错误。
【问题讨论】:
仅供参考,库存 AAC 编码器的输入必须是MFAudioFormat_PCM
。您的 LPCM 可能需要进行不可自动转换的转换。
@RomanR。谢谢,我把它改成PCM。没有变化 - 出现相同的错误。 (并且我确认我在 C# api 中的“PCM”与官方 SDK 中的 MFAudioFormat_PCM 具有相同的值)
好的,接下来看起来不太好的事情是你的MF_MT_ALL_SAMPLES_INDEPENDENT
AAC 类型。你为什么不把它完全注释掉。
太棒了,解决了!非常感谢。
【参考方案1】:
音频媒体类型可以这样初始化:
// 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
sn-p 会阻止编解码器的初始化。
【讨论】:
以上是关于媒体基础 MP4 编码:IMFSinkWriter 不接受 PCM 输入的主要内容,如果未能解决你的问题,请参考以下文章
通过 ICodecAPI 为 H.264 IMFSinkWriter 编码器设置属性
“无法解码媒体资源 FILEPATH/FILENAME.mp4。”尝试在 Firefox 35 上播放 h264 编码文件时