使用 IMFSourceReader 打开视频文件
Posted
技术标签:
【中文标题】使用 IMFSourceReader 打开视频文件【英文标题】:Using IMFSourceReader to open a video file 【发布时间】:2014-11-18 10:50:09 【问题描述】:我想使用IMFSourceReader
打开一个视频文件,以将其帧作为 IMFSample 访问。
在 WinRT C++ 类中,我发送视频文件的 RandomAccessStream
并使用以下代码创建 IMFSourceReader
对象。
HRESULT hr = S_OK;
ComPtr<IMFSourceReader> pSourceReader;
ComPtr<IMFByteStream> spByteStream;
if (SUCCEEDED(hr))
// Initialize the Media Foundation platform.
hr = MFStartup(MF_VERSION);
hr = MFCreateMFByteStreamOnStreamEx((IUnknown*)InputVideoStream, &spByteStream);
ComPtr<IMFAttributes> Atrr;
hr = MFCreateAttributes(&Atrr, 10);
hr = Atrr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true);
hr = MFCreateSourceReaderFromByteStream(spByteStream.Get(), Atrr.Get(), &pSourceReader);
但是函数 MFCreateSourceReaderFromByteStream() 的 HRESULT 正在返回 The Byte Stream Type of the Given URL is unsupported
。
我不知道我做错了什么。谁能告诉我正确的方法?我使用的是 Windows 8.1。
【问题讨论】:
返回码听起来很清楚。您要播放的文件的视频/音频格式是什么?如果您也无法使用 TopoEdit 播放它,那么您没有此格式的可用编解码器。 我可以打开一些 MP4 文件(编解码器 ID isom),但不能打开每个 MP4 文件(例如编解码器 ID mp42)。除了使用 IMFSourceReader 之外,还有其他方法可以提取视频帧吗? 【参考方案1】:返回码听起来很清楚。您要播放的文件的视频/音频格式是什么?如果您也无法使用 TopoEdit 播放它,那么您没有此格式的可用编解码器。
除了使用 IMFSourceReader?
无论如何,要提取未压缩的视频样本,首先您必须从其编码流中对其进行解码。在您的情况下,您缺少解码器。也许您的问题应该是我可以使用另一个框架来代替 Media Foundation?
我不这么认为。 DirectShow API 不适用于 Windows RT,据我所知,即使 ffmpeg 无法 为该操作系统编译。所以我猜你唯一的选择就是依赖 Media Foundation 和它的编解码器集。
我想到的唯一想法是找到第三方解码器组件 (MFT) 或构建自己的解码器。
编辑:
在您的情况下,IMFMSourceReader 工厂函数 (MFCreateMFByteStreamOnStreamEx) 无法创建源阅读器。这将意味着您的系统缺少足够的容器解析器(即分离器又名解复用器)。因此它无法从容器中提取基本媒体流。这真的是解码前的阶段。
同样,您可以搜索第三方媒体源解析器,或写入/移植一个。当然,您首先会发现 MF 缺少源代码阅读器的特定格式是什么。
一些链接:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms700134%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ee318417%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/windows/desktop/aa371872%28v=vs.85%29.aspx
【讨论】:
我在这里有点困惑,因为我是新手。据我所知,MFT 有一个 ProcessInput(),其中传递了一个 IMFSample,ProcessOutput() 返回解码的 IMFSample。因此,首先我需要使用 IMFSourceReader->ReadSample() 从视频中提取 IMFSample,然后才能使用 MFT。但是 SourceReader 一开始就无法加载视频。因此,需要有一种方法可以同时使用 MFT 解码器通过源阅读器打开视频。你能指导我找到任何教程或链接吗? 我已经编辑了我的答案。我不知道好的MF教程,我也会有兴趣发布一些。你可以在 MSDN 上查看资料,也可以在 MF 的博客上查看:blogs.msdn.com/b/mf。你也可以看看这个项目:sourceforge.net/projects/mfnode 我可以用 TopoEdit 播放视频文件。它在图中显示它使用“Microsoft H264 Video Decoder MFT”。那么这是否意味着我已经为这种格式安装了必要的编解码器?如果我能以某种方式调用这个解码器 MFT,我是否能够使用 IMFSourceReader 来读取该视频的 IMFSamples? 您是否尝试过使用源解析器?首先创建IMFSoureResolver,然后调用它的方法创建媒体源对象。如图所示:msdn.microsoft.com/en-us/library/windows/desktop/… 如果您能够在 TopoEdit 中播放媒体文件,那么您拥有必要的 MF 解复用器/解码器。【参考方案2】:我找到了解决IMFSourceReader
的The Byte Stream Type of the Given URL is unsupported
问题的方法。我可以读取WMV
文件的字节流,一些MP4
文件,但不是所有类型的视频文件。所以在使用MFCreateSourceReaderFromByteStream()
之前,我将视频流转换为VC-1/WMV
可以读取的MFCreateSourceReaderFromByteStream()
格式。我使用 MSDN 的Transcoding media sample 将他的视频转换为 WMV 视频。现在我可以毫无错误地使用MFCreateSourceReaderFromByteStream()
。
【讨论】:
以上是关于使用 IMFSourceReader 打开视频文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Media Foundation 从 IMFSourceReader 播放音频缓冲区
处理来自 IMFSourceReader 和 IMFSample 的图像数据