与 Media Foundation 一起制作视频

Posted

技术标签:

【中文标题】与 Media Foundation 一起制作视频【英文标题】:Video composition with Media Foundation 【发布时间】:2012-10-21 07:24:06 【问题描述】:

我正在尝试将 2 个视频合成为一个(也是音频)并另存为文件。比如说,在最终视频的左半部分显示一个源视频,在右侧显示另一个源。任何编码都可以。不使用 DirectShow。

我怀疑 IMFVideoMixerControl 可能与此有关,但不幸的是,我对 MF 太陌生,无法确定为实现这一目标而采取的正确步骤。如果您能给我一些指导或网络上有任何示例,请告诉我。感谢您的帮助。

【问题讨论】:

据我所知,MF中没有这个功能。对于这样的任务,(有问题的)DirectShow 编辑服务仍然没有替代品! :-( 至少,我认为我应该能够阅读媒体样本(msdn.microsoft.com/en-us/library/windows/desktop/…),对多个视频源执行此操作。将来自源的字节数组帧合成为一个(不理想..)。然后应该能够将样本写入 IMFSinkWriter 以保存为编码视频。我还没有尝试过,但它可能会很慢(虽然我不太关心我的应用程序的性能)。所以我想知道是否有更好的(标准)方法来做到这一点。 【参考方案1】:

IMFVideoMixerControl 用于渲染视频。看着 SourceReader,你走在了正确的轨道上。

我会这样做:

    为每个视频源创建一个IMFSourceReader。 创建一个IMFSinkWriter 并将其配置为与源阅读器帧宽度之和相等的帧宽度。
      使用IMFSourceReader::GetCurrentMediaType 获取源媒体类型。 使用 MFGetAttributeSize 和 GUID MF_MT_FRAME_SIZE 来获取每种源类型的框架尺寸。 使用MFCreateMediaType 为 SinkWriter 创建一个媒体类型,并使用IMFMediaType::CopyAllItems 将属性从源媒体类型复制到接收器媒体类型。 使用 MFSetAttributeSize 和 GUID MF_MT_FRAME_SIZE 设置接收器类型的增加框架尺寸。 使用IMFSinkWriter::AddStream 创建与源类型相同的视频流,宽度属性除外
    为每个来源调用 IMFSourceReader::ReadSample,为每个来源提供一个 IMFSample。 分配一个新的IMFSample,附加一个增加了框架宽度的新IMFMediaBuffer。 使用MFCopyImage 将每个源缓冲区复制到分配的媒体缓冲区的对应端。 使用IMFSinkWriter::WriteSample 将您的IMFSample 写入文件接收器。

有关一些基本的 SourceReader/SinkWriter 处理,请参阅 this sample,尽管此示例使用视频捕获源而不是文件。您可以使用 MFCreateSourceReaderFromURL 而不是 MFCreateSourceReaderFromMediaSource 创建文件 SourceReader。

编辑:我意识到您也询问了音频。我的回答只涉及合成视频流。

【讨论】:

以上是关于与 Media Foundation 一起制作视频的主要内容,如果未能解决你的问题,请参考以下文章

Windows Media Foundation 音视频采集 小记

Media Foundation 捕获的视频是垂直镜像的

使用 Microsoft Media Foundation 从文件播放视频

Media Foundation 将音频流添加到视频文件

使用 Media Foundation 源阅读器阅读 3D(左右)视频

如何使用 Media Foundation 从 MP4 视频中丢弃任意帧?