views:

1849

answers:

4

As part of a program I have to be able to pull a few random frames from a user specified video file. I do not have any experience with video processing programming, so this is new to me.

I've determined that I need to use DirectShow.net to do this on Windows XP using .Net, but I cannot figure out how to get it done. I'm trying to use the ISampleGrabber interface but I can't get it all figured out and can't find any examples.

There are very few examples of DirectShow.net usage on the internet, but surely someone has pulled frames from a video using .net, so I'm just looking to see if anyone knows of sample code that does this or something close.

Trying to follow along with this code project article I've come up with this code:

// step 1
IGraphBuilder graphBuilder = (IGraphBuilder)new FilterGraph();

// step 2
IBaseFilter grabberBaseFilter;
ISampleGrabber sampleGrabber;
AMMediaType mt;
grabberBaseFilter = (IBaseFilter)new SampleGrabber();
sampleGrabber = (ISampleGrabber)grabberBaseFilter;
graphBuilder.AddFilter(grabberBaseFilter, "Grabber");

// step 3

mt = new AMMediaType();
mt.majorType = MediaType.Video;
mt.subType = MediaSubType.RGB24;
mt.formatType = FormatType.VideoInfo;
sampleGrabber.SetMediaType(mt);
graphBuilder.RenderFile(filename, null);

IMediaControl mediaControl = (IMediaControl)graphBuilder;
IMediaEvent mediaEventEx = (IMediaEvent)graphBuilder;

sampleGrabber.SetBufferSamples(true);
sampleGrabber.SetOneShot(true);

// step 4

mediaControl.Run();

EventCode evCode;
mediaEventEx.WaitForCompletion(int.MaxValue, out evCode);

AMMediaType connectedMediaType = new AMMediaType();
sampleGrabber.GetConnectedMediaType(connectedMediaType);

VideoInfoHeader videoHeader = (VideoInfoHeader)connectedMediaType.formatType;

BitmapInfo bitmapInfo = new BitmapInfo();
bitmapInfo.bmiHeader = videoHeader.BmiHeader;

// ::CreateDIBSection(0, &BitmapInfo, DIB_RGB_COLORS, &buffer, NULL, 0); 
// legacy - GdiFlush(); 

// Copy the image into the buffer. 
int size = 0;
sampleGrabber.GetCurrentBuffer(ref size, buffer);

The part that wont compile is the videoHeader cast line and the GetCurrentBuffer line at the end because there is no buffer variable... but I'm not sure what to do to fix it.

+1  A: 

Try using IMediaDet. Here is a sample from my project;

Jeremiah Morrill
That's what I ended up using, just hadn't gotten around to posting it back on here. Thanks for the answer though.
Max Schmeling
IMediaDet has one huge problem - it doesn't supports videos with VIDEOINFOHEADER2 format.
Yurec
A: 

Better solution is to use IBasicVideo.GetCurrentImage method. It is more universal and will work for most of videos.

Yurec
A: 

Change that to:

VideoInfoHeader videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(connectedMediaType.formatPtr, typeof(VideoInfoHeader));
Boyan Kostadinov
A: 

How is it go? can u fix it? share it,,thank u

Opal