I have successfully managed to utilize directshownet DirectShow wrapper for the purpose of generating thumbnails of video files. For many test instances the code works just fine.
However for some, it throws an 'unknown exception' at the RenderStream function call.
I have been unable to trace the reson of the exception, the error code is '-2147467259', InnerException:null. I do not have much experience with investigating faults in COM interface, but the error code does not seem to form any logical value.
My first thought was the lack of proper codecs etc. however the problem persists on a couple of test machines, where most of the popular codec-packs have been installed (ffdshow, k-lite codec packs etc). THe vido also plays just fine outside of the app.
The machines are running x64 versions of windows (windows 7 and win server 2008 r2),have installed x64 versions of ffdshow codec packs, then played with other settings like installing 32bit version of ffdshow as well, coupled with compiling test app in x64 as well as in x86 build mode. Fails all the time on the sample clip. Also tried to enable/disable particular codecs in the FFDSHOW settings panel looking especially at the h264 one. Nothing. The problematic sample video is encoded using the following specification: v-codec:H264 - MPEG-4 AVC (part 10) avc1 Resolution:1280x768 FPS:23..
I think the code for building Graph is allright as it works for lots of test cases, however here it is:
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;
}
}
}
Still trying to narrow down the problem. Any comments would be appreciated as I have simply runed out of ideas. Update: Seems like the problem can be put more specific: how to modify the above graph in order to make DirecShow utlize h264 codec available on the system? It does not happen by itself from what it seems. Another I believe worthy update: I have dived deeper into the subject of building grapsh etc. I have also downloaded the GrapStudio software in order to play with different filter settings. However, as soon as I choose the Render Media File submenu and point it to the problematic video it says 'cannot render file'! Nothing less, nothing more,the video file plays just fine in Windows media player, or VLC. It was encoded with h264video codec, provided by FFDSHOW.
Another Update: I have managed to make GraphStudio render movie (File->Render MEdia File), with use of K-Lite codec pack x64. The graph is built (takes use of LAV Video Decoder). My app STILL fails to auto-generate a graph, though its targeted for x64 platform as well and from what I've read GraphStudio just calls the same API function. That is very strange. So I have decided to build a semi-automatic graph.
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);
While adding other filters which I need, followed by a call to RenderFile. NOTHING. All of the filters were initialized by their corresponding CLSID, no error there. It wont render.Anyone? if you ask me that DirectShowNet or maybe DirectShow as whole is terribly documented when it comes to use of modern codecs etc.