我已成功设法利用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作为整体在使用现代编解码器等方面是非常有用的。