2012-10-27 131 views
0

我已成功设法利用directshownet DirectShow包装器来生成视频文件的缩略图。对于许多测试实例,代码仅适用于罚款renderStream上的'未知错误'

但是对于一些,它会在RenderStream函数调用时抛出一个'未知异常'。

我一直无法追查异常的共鸣,错误代码是'-2147467259',InnerException:null。 我对调查COM接口中的错误没有太多经验,但错误代码似乎没有形成任何逻辑值。

我的第一个想法是缺乏正确的编解码器等,但问题仍然存在于几台测试机器上,大多数流行的编解码器包已安装(ffdshow,k-lite编解码器包等)。在应用程序之外,vido也可以玩得很好。

这些机器运行x64版本的Windows(Windows 7和win server 2008 r2),已安装 x64版本的ffdshow编解码器包,然后与其他设置一起播放,例如安装ffdshow的32位版本以及编译测试应用程序在x64以及x86构建模式。样本剪辑上的所有时间都失败。还尝试启用/禁用FFDSHOW设置面板中的特定编解码器,尤其是在h264上。没有。 有问题的样本视频使用以下规格编码: v型的编解码器:H264 - MPEG-4 AVC(第10部分)AVC1 分辨率:1280×768 FPS:23 ..

我认为用于构建的代码图表是好吧,因为它适用于很多测试用例,但在这里它是:

private void SetupGraph(string FileName) 
{ 
    int hr; 

    // Get the graphbuilder object 
    m_FilterGraph = new FilterGraph() as IFilterGraph2; 

    // Get a ICaptureGraphBuilder2 to help build the graph 
    ICaptureGraphBuilder2 icgb2 = new CaptureGraphBuilder2() as ICaptureGraphBuilder2; 

    try 
    { 
     // Link the ICaptureGraphBuilder2 to the IFilterGraph2 
     hr = icgb2.SetFiltergraph(m_FilterGraph); 
     DsError.ThrowExceptionForHR(hr); 

     // Add the filters necessary to render the file. This function will 
     // work with a number of different file types. 
     IBaseFilter sourceFilter = null; 

     hr = m_FilterGraph.AddSourceFilter(FileName, null, out sourceFilter); 
     DsError.ThrowExceptionForHR(hr); 

     // Get the SampleGrabber interface 
     m_sampGrabber = (ISampleGrabber)new SampleGrabber(); 
     IBaseFilter baseGrabFlt = (IBaseFilter)m_sampGrabber; 

     // Configure the Sample Grabber 
     ConfigureSampleGrabber(m_sampGrabber); 

     // Add it to the filter 
     hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber"); 
     DsError.ThrowExceptionForHR(hr); 


     // Connect the pieces together, use the default renderer 
     hr = icgb2.RenderStream(null, null, sourceFilter, baseGrabFlt, null); 
     DsError.ThrowExceptionForHR(hr); // **HERE** is where the 'unknown exception' is thrown. 

     // Now that the graph is built, read the dimensions of the bitmaps we'll be getting 
     SaveSizeInfo(m_sampGrabber); 

     // Configure the Video Window 
     IVideoWindow videoWindow = m_FilterGraph as IVideoWindow; 
     videoWindow.put_AutoShow(OABool.False); 
     // ConfigureVideoWindow(videoWindow, hWin); 
     // 
     // Grab some other interfaces 
     m_mediaEvent = m_FilterGraph as IMediaEvent; 
     m_mediaCtrl = m_FilterGraph as IMediaControl; 
     m_mediaSeeking = m_FilterGraph as IMediaSeeking; 
     m_mediaSample = m_FilterGraph as IMediaSample; 
     m_mediaPosition = m_FilterGraph as IMediaPosition; 

    } 
    catch 
    { } 
    finally 
    { 
     if (icgb2 != null) 
     { 
      Marshal.ReleaseComObject(icgb2); 
      icgb2 = null; 
     } 
    } 

} 

仍试图缩小问题的范围。 任何意见,将不胜感激,因为我只是根本没有想法。 更新:似乎可以把这个问题放在更具体的位置:如何修改上面的图表,以便使DirecShow utlize h264编解码器在系统上可用?它看起来不会自行发生。 另一个我认为值得更新:我已深入到建设grapsh等主题。我也下载了GrapStudio软件,以玩不同的过滤器设置。 但是,只要我选择渲染媒体文件子菜单,并指向有问题的视频它说'无法渲染文件'!毫无疑问,视频文件在Windows媒体播放器或VLC中播放得很好。它使用由FFDSHOW提供的h264video编解码器进行编码。

另一个更新: 我设法使用K-Lite编解码器包x64使GraphStudio渲染电影(文件 - >渲染MEdia文件)。该图建立(使用LAV视频解码器)。我的应用程序STILL无法自动生成图形,尽管它的目标用于x64平台以及我读过的GraphStudio只是调用相同的API函数。这很奇怪。所以我决定建立一个半自动图形。

Guid gui = new Guid("EE30215D-164F-4A92-A4EB-9D4C13390F9F"); 
Object o; 
ty = Type.GetTypeFromCLSID(gui); 
o = Activator.CreateInstance(ty, false); 
IBaseFilter ibfVideoDec = (IBaseFilter)o; 
hr=m_FilterGraph.AddFilter(ibfVideoDec, "LAV Video decoder"); 
DsError.ThrowExceptionForHR(hr); 

虽然添加了我需要的其他过滤器,然后调用RenderFile。没有。所有的过滤器都通过相应的CLSID初始化,没有错误。它不会渲染。任何人? 如果你问我,DirectShowNet或者DirectShow作为整体在使用现代编解码器等方面是非常有用的。

回答

0

错误是0x80004005E_FAIL“未指定的错误”。图形生成器会将某些内部组件的错误转发给您,而不会提供详细信息。没有办法找到原因,而不是在更精细的步骤中构建图形。它可以是任何包括系统中错误的第三方组件(这很可能是假设你安装了一个编解码器包)。打破RenderStream为个人Connect s和AddFitler s将解释原因。