皖新文化广场翡翠庄园:用DirectShow实现视频采集(三)

来源:百度文库 编辑:偶看新闻 时间:2024/05/01 12:58:16

用DirectShow实现视频采集 (三)


3)创建视频采集过滤器图表

DirectX较高版本中一般都为开发者提供了一个ICaptureGraphBuilder2接口,开发者可以通过它方便地创建视频采集过滤器图表,然后再将它添加到IGraphBuilder图表管理器中(如图3)。





图3


bool InitCaptureGraphBuilder()

{

HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,

CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);


if(FAILED(hr))

return false;


hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,

IID_IGraphBuilder, (void**)&pGraph);


if(FAILED(hr))

{

pBuild->Release();

return false;

}


pBuild->SetFiltergraph(pGraph); ///////////////////// 过滤器图表添加到管理器中


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

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


return true;

}


4)创建剩余的Smart Tee和Video Renderer Filter并连接成完整的图表


在创建完Video Capture Filter后,我们需要将Filter添加到过滤器图表中。


pGraph->AddFilter(pCap,L"Capture Filter");


然后,我们创建剩余的Filter并相连即可,值得注意的是:ICaptureGraphBuilder2为用户提供了一个RenderStream函数,它可以自动构建Smart Tee和Video Renderer Filter并将它们连接成一个完整的图表,从而完成视频采集的功能。


pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,

pCap, NULL, NULL);


为了说明整个过程,这里我们按部就搬,依次创建各个Filter。


Smart Tee


CoCreateInstance(CLSID_SmartTee,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void **)&pSmartTee);


Video Renderer Filter


CoCreateInstance(CLSID_VideoRenderer,NULL,CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void **)&pRender);


创建好各个Filter后,我们依次取得它们的引脚(Pin),将它们按序相连即可。

IPin * GetSmartTeeInputPin() //取得Smart Tee 输入引脚

{

if(pSmartTee)

{

IPin * pPin;

HRESULT hr = pSmartTee->FindPin(L"Input",&pPin);

if(SUCCEEDED(hr))

{

pPin->Release();

return pPin;

}

}

return NULL;

}


IPin * GetSmartTeeCapturePin() //取得Smart Tee Capture引脚

{

if(pSmartTee)

{

IPin * pPin;

HRESULT hr = pSmartTee->FindPin(L"Capture",&pPin);

if(SUCCEEDED(hr))

{

pPin->Release();

return pPin;

}

}

return NULL;

}


IPin * GetSmartTeePreviewPin() //取得Smart Tee Preview引脚

{

if(pSmartTee)

{

IPin * pPin;

HRESULT hr = pSmartTee->FindPin(L"Preview",&pPin);

if(SUCCEEDED(hr))

{

pPin->Release();

return pPin;

}

}

return NULL;

}



IPin * GetRendererPin() //取得Video Renderer Filter的输入Pin

{

if(pBuild)

{

IPin * pPin;

HRESULT hr = pBuild->FindPin(pRender,PINDIR_INPUT,NULL,NULL,FALSE,0,&pPin);

if(SUCCEEDED(hr))

{

pPin->Release();

return pPin;

}

}

return NULL;

}


将各个引脚按序连接:


IPin * pOut = FindVideoPin(&PIN_CATEGORY_CAPTURE);

IPin * pIn = GetSmartTeeInputPin();


pGraph->Connect(pOut,pIn); //Video Capture Filter’ Capture Pin à Smart Tee’Input Pin


IPin * mOut = GetSmartTeePreviewPin();

IPin * mIn = GetRendererPin();





pGraph->Connect(mOut,mIn); //Smart Tee’s Preview Pin à Video Renderer Filter’s Input Pin


这样,一个完整的视频采集图表管理器就构造完成了。


5)开始视频采集


通过用户命令接口,我们可以方便的完成开始,暂停,停止视频采集。


pControl->Run();

pControl->Stop();


4.小结


通过上述视频采集过程的实现,不难发现DirectShow是一个流程清晰,开发容易的多媒体开发工具。我们在使用DirectX为我们提供的Filter构建多媒体功能的同时,也可以自己着手创建具备特定功能的Filter。总之,Direct系统还是 一个巨大的宝藏,等待着我们去发掘和开采。