使用C++中的DirectShow解码带有H.264流的MP4视频。

3
我有一个包含单个H.264流和无音频流的MP4视频。我想使用C++和DirectShow解码视频,但我在设置DirectShow过滤器时遇到了困难,希望有人能帮助我。
以下是我用于使用DirectShow解码WMV3流的设置代码,它已经工作良好:
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGraph);

if (SUCCEEDED(hr))      hr = CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&m_pFilter);
if (SUCCEEDED(hr))      hr = m_pFilter->QueryInterface(IID_IVMRFilterConfig9, reinterpret_cast<void**>(&filterConfig));
if (SUCCEEDED(hr))      hr = filterConfig->SetRenderingMode( VMR9Mode_Renderless );
if (SUCCEEDED(hr))      hr = filterConfig->SetNumberOfStreams(2);
if (SUCCEEDED(hr))      hr = SetAllocatorPresenter( m_pFilter, g_pMainWindow );
if (SUCCEEDED(hr))      hr = m_pGraph->AddFilter(m_pFilter, L"Video Mixing Renderer 9");
if (SUCCEEDED(hr))      hr = m_pGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&m_pMediaControl));
if (SUCCEEDED(hr))      hr = m_pGraph->QueryInterface(IID_IBasicAudio, reinterpret_cast<void**>(&m_pBasicAudio));
if (SUCCEEDED(hr))      hr = m_pGraph->RenderFile( lpFilename, NULL );

我无法弄清如何正确设置解码MP4。我已经像在其他文章中发现的那样安装了3ivx和ffdshow,现在GraphEdit可以打开我的文件并显示正确的图形(注意-我在64位机器上运行64位版本的GraphEdit时这并不起作用,但是32位版本可以……可能与此有关?)。 VLC可以正常播放我的视频。
我已在整个互联网上寻找了特定于此的示例,但没有找到。
我的视频文件格式如下(ffmpeg输出):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    creation_time   : 2013-01-16 19:14:52
  Duration: 00:05:25.62, start: 0.033367, bitrate: 3396 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 3393 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc
    Metadata:
      creation_time   : 2013-01-16 19:14:52
      handler_name    : ?Mainconcept Video Media Handler

任何帮助都将不胜感激!
敬礼, 格雷厄姆
1个回答

0

Windows中没有标准/默认的MP4分离器,因此您必须安装一个扩展DirectShow以覆盖MP4的分离器。

  • 您需要安装适当位数(32位与64位)的分离器,以匹配您的代码/应用程序(或GraphEdit)的位数
  • VLC并不重要,因为它有自己内置的分离器
  • 您还需要H.264解码器,而且您似乎已经有了一个

您的代码基本正确,但是这种构建图形的方法并不太可靠。首先,您需要查看是否在RenderFile调用上获得任何有用的错误代码。

如果GraphEdit Win32在此系统上工作,则所有所需组件(过滤器)都应可用。区别在于GraphEdit不会像您一样构建图形。相反,它使用IGraphBuilder::AddSourceFilter为给定文件添加起始过滤器,然后呈现其引脚。如果您采用相同的方法,并在最后一步添加VMR过滤器进行视频呈现,则可以很好地解决此问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接