Как получить видеокадр с помощью DirectShow.net? - PullRequest
2 голосов
/ 06 января 2010

Как часть программы, я должен быть в состоянии извлечь несколько случайных кадров из указанного пользователем видеофайла. У меня нет никакого опыта в программировании обработки видео, так что для меня это ново.

Я решил, что мне нужно использовать DirectShow.net для этого в Windows XP с использованием .Net, но я не могу понять, как это сделать. Я пытаюсь использовать интерфейс ISampleGrabber, но не могу понять все это и не могу найти никаких примеров.

В Интернете очень мало примеров использования DirectShow.net, но наверняка кто-то извлек кадры из видео с использованием .net, поэтому я просто смотрю, знает ли кто-нибудь пример кода, который делает это или что-то похожее .

Пытаясь следовать этой статье проекта кода, я придумал этот код:

// 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);

Часть, которая не будет компилироваться - это строка приведения videoHeader и строка GetCurrentBuffer в конце, потому что нет буферной переменной ... но я не уверен, что делать, чтобы это исправить.

Ответы [ 3 ]

1 голос
/ 01 февраля 2010

Лучшим решением является использование метода IBasicVideo.GetCurrentImage. Он более универсален и будет работать для большинства видео.

1 голос
/ 06 апреля 2010

Измените это на:

VideoInfoHeader videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(connectedMediaType.formatPtr, typeof(VideoInfoHeader));
1 голос
/ 08 января 2010

Попробуйте использовать IMediaDet. Вот пример из моего проекта;

...