1.加入Sample Grabber Filter
当我们加入Sample Grabber Filter的时候,我们能够直接调用其接口(interface)ISampleGrabber。该接口能够获取经过该Filter的单独的Media Samples。详情请参见DXSDK。

1.1 派生出自己的Sample Grabber
从ISampleGrabberCB中派生出自己的类,然后实现其虚函数,详情请参见SDK中的示例程式(DXSDK ROOT\Samples\C \DirectShow\Editing\GrabBitmaps)。

1.2 直接调用Sample Grabber Filter的接口
假如我们在播放的过程中动态的加入Filter的话,操作和效率都不乐观。所以我采用下面的方法:

该方法传递的是时间,不是在播放的时候动态加入Filter然后截图,而是另外打开源文档进行操作。

A)。申明以下接口:

#001 IGraphBuilder *pGraph = NULL; //for graph builder



#002 IMediaControl *pControl = NULL; //media control



#003 IMediaSeeking *pSeeking = NULL; //media seeking



#004 IMediaEventEx *pEvent = NULL; //media envent



#005 IBaseFilter *pNullFilter =NULL;//for holding the Sample grabber Filter



B)。初始化接口:

#001 JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,

#002 IID_IGraphBuilder, (void **)&pGraph));

#003

#004 JIF(CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC,

#005 IID_IBaseFilter, (void **)&pNullFilter));

#006 JIF(pGraph->QueryInterface(IID_IMediaControl,(void **)&pControl));

#007 JIF(pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pSeeking));

#008 JIF(pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent));

C)。创建Sample Grabber

#001 // Create the Sample Grabber.



#002 IBaseFilter *pGrabberF = NULL;

#003 JIF(CoCreateInstance(CLSID_SampleGrabber,NULL, CLSCTX_INPROC_SERVER,

#004 IID_IBaseFilter, (void**)&pGrabberF));

#005

#006 JIF(pGraph->AddFilter(pGrabberF, L"Sample Grabber"));

#007 JIF(pGraph->AddFilter(pNullFilter, L"Null Render Filter"));

#008

#009 ISampleGrabber *pGrabber;

#010 JIF(pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber));

配置Sample Grabber的媒体格式:调用SetMediaType,该函数接受一个AM_MEDIA_TYPE的结构,主要是配置该结构中的majortype,和subtype域。

D)。添加Source Filter:

#001 IBaseFilter *pSrc;

#002 JIF(pGraph->AddSourceFilter(T2W(m_szFile), L"Source", &pSrc));

E)。连接Grabber 和 NullRender两个Filter:

#001 IPin *pOutPin;

#002 hr = GetPin(pGrabberF, PINDIR_OUTPUT, &pOutPin);

#003

#004 IPin *pInPin;

#005 hr = GetPin(pNullFilter, PINDIR_INPUT, &pInPin);

#006

#007 pGraph->Connect(pOutPin, pInPin);

F)。取得当前所连接媒体的类型

#001 AM_MEDIA_TYPE mt;

#002 hr = pGrabber->GetConnectedMediaType(&mt);

#003 // Examine the format block.



#004 VIDEOINFOHEADER *pVih;

#005 if ((mt.formattype == FORMAT_VideoInfo) &&

#006 (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) &&

#007 (mt.pbFormat != NULL) )

#008 {

#009 pVih = (VIDEOINFOHEADER*)mt.pbFormat;

#010 }

#011 else



#012 {

#013 // Wrong format. Free the format block and return an error.



#014 FreeMediaType(mt);

#015 return VFW_E_INVALIDMEDIATYPE;

#016 }

#017

#018 // Do buffer the samples as they pass through



#019 //



#020 hr = pGrabber->SetBufferSamples(TRUE);

#021

#022 // Only grab one at a time, stop stream after



#023 // grabbing one sample



#024 //



#025 hr = pGrabber->SetOneShot( TRUE );

G)。Seeking文档,使其到达要截图的时间帧

#001 pSeeking->SetPositions(pCurrentPos,

#002 AM_SEEKING_AbsolutePositioning,

#003 NULL, AM_SEEKING_NoPositioning );

#004

#005 pControl->Run();

#006

#007 long EvCode = 0;

#008

#009 hr = pEvent->WaitForCompletion( INFINITE, &EvCode );

H)。取得当前的buffer数据

#001 // Find the required buffer size.



#002 long cbBuffer = 0;

#003 hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);

#004 LONGLONG currentPos;

#005 pSeeking->GetCurrentPosition(&currentPos);

#006 BYTE *pBuffer = new BYTE[cbBuffer];

#007 if (!pBuffer)

#008 {

#009 // Out of memory. Return an error code.



#010 Msg("Out of Memory");

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!