DirectShow在,数据流(Data Flow)它们是依次流过每Filter的.管理其数据具有其自己的方法,并且并没有向用户提供一个统一的接口,供用户操作数据流.这里以提取视频採集在的每帧为位图数据为例,说说怎样在Directshow中提取数据.
这里我们用到了DirectShow提供给我们的接口ISampleGrabber,并定义了一个供它回调的CSampleGrabberCB对象(继承ISampleGrabberCB接口).
我们知道,DirectShow中的数据存储是通过Sample完毕的,所以提取数据也须要通过SampleGrabber.
过程例如以下:
1.建立CSampleGrabberCB对象.
class CSampleGrabberCB : public ISampleGrabberCB
{
STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize )
{
//Callback method that receives a pointer to the sample buffer.
}
STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
{
//Callback method that receives a pointer to the media sample.
}
}
2.定义ISampleGrabber接口并初始化
CComPtr< ISampleGrabber > m_pGrabber;
HRESULT hr;
hr = m_pGrabber.CoCreateInstance( CLSID_SampleGrabber );
if(FAILED(hr))
//error action;
3.定义Grabber Filter,设置它的媒体类型,并将它增加Graph中
CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabBase( m_pGrabber );
CMediaType VideoType;
VideoType.SetType(&MEDIATYPE_Video);
VideoType.SetSubtype(&MEDIASUBTYPE_RGB24);
hr = m_pGrabber->SetMediaType(&VideoType);
hr = pGraph->AddFilter(pGrabBase,L"Grabber");
4.设置回调(CallBack),使Grabber可以通过BufferCB自己主动完毕採集数据.
// don't buffer the samples as they pass through
//
hr = m_pGrabber->SetBufferSamples( FALSE );
// only grab one at a time, stop stream after
// grabbing one sample
//
hr = m_pGrabber->SetOneShot( FALSE );
// set the callback, so we can grab the one sample
//
hr = m_pGrabber->SetCallback( &mCB, 1 ); //mCB为CSampleGrabber对象
这样,在DirectShow数据流过程,mCB.bufferCB它可以运行在自己主动,摘录Graph数据.
版权声明:本文博客原创文章,博客,未经同意,不得转载。