使用IMFSourceReader打开视频文件

时间:2014-11-18 10:50:09

标签: video windows-runtime c++-cx ms-media-foundation

我想使用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。

2 个答案:

答案 0 :(得分:1)

返回代码听起来很清楚。您要播放的文件的视频/音频格式是什么?如果您无法使用TopoEdit回放,那么您没有此格式的可用编解码器。

  

除了使用之外,还有其他方法可以提取视频帧   IMFSourceReader?

要提取未压缩的视频样本,无论采用何种方式,首先必须从其编码流中对其进行解码。在你的情况下,你错过了一个解码器。也许你的问题应该是是否有我可以使用的另一个框架而不是Media Foundation

我不这么认为。 DirectShow API不适用于Windows RT,据我所知甚至ffmpeg 不能为该操作系统编译。所以我想你唯一的选择就是依靠Media Foundation及其编解码器。

我想到的唯一想法是找到第三方解码器组件(MFT)或构建自己的解码器。

修改

在您的情况下,IMFMSourceReader工厂函数(MFCreateMFByteStreamOnStreamEx)无法创建源阅读器。这意味着您的系统缺少足够的容器解析器(即分离器a.k.a.解复用器)。因此它无法从容器中提取基本媒体流。这实际上是解码之前的阶段。

再次,您可以搜索第三方媒体源解析器,或写入/端口解析器。当然,您将首先了解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

答案 1 :(得分:1)

我找到了The Byte Stream Type of the Given URL is unsupported IMFSourceReader问题的解决方案。我可以读取WMV个文件的Byte Stream,一些MP4个文件但不是所有类型的视频文件。因此,在使用MFCreateSourceReaderFromByteStream()之前,我将视频流转换为VC-1/WMV能够阅读的MFCreateSourceReaderFromByteStream()格式。我使用MSDN的Transcoding media sample将视频转换为WMV视频。现在我可以使用MFCreateSourceReaderFromByteStream()而没有任何错误。