标签:
出于兴趣一直以来都断断续续看过dshow的东西,可没怎么系统地总结过(学习还是要多实践,多总结啊).
dshow预览摄像头捕捉的视频比较简单基础,网上相关的资料很多,简单的思路由下面代码所示:
ICaptureGraphBuilder2 *pBuild; // Capture Graph Builder // Initialize pBuild (not shown). IBaseFilter *pCap; // Video capture filter. /* Initialize pCap and add it to the filter graph (not shown). */ hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pCap, NULL, NULL);dshow 提供了一个 Capture Graph Builder COM 组件使得捕捉graph 图的生成更加简单。 Capture Graph Builder 提供了一ICaptureGraphBuilder2接口 ,这个接口提供了一些方法用来构建和控制捕捉 graph。video capture filter则由系统设备枚举得到可用视频设备,并生成filter;最后智能连接graph即可.具体见代码和注释:
#include <dshow.h>
#include <stdio.h>
#include <atlconv.h>
#pragma comment(lib,"quartz.lib")
#pragma comment(lib, "strmiids.lib")
void main()
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
IVideoWindow *pVideoWindow = NULL;
ICaptureGraphBuilder2 *pBuild = NULL;
// Initialize the COM library.
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)){
printf("ERROR - Could not initialize COM library");
return;
}
//创建Capture Graph Builder 对象
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
if (SUCCEEDED(hr)){
// 创建 graph manger 对象.
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void**)&pGraph);
if (SUCCEEDED(hr))
// 初始化 Capture Graph Builder.
pBuild->SetFiltergraph(pGraph);
}
//各个查询接口.
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
hr = pGraph->QueryInterface(IID_IVideoWindow, (void**)&pVideoWindow);
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
//创建一个系统设备枚举对象
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,reinterpret_cast<void**>(&pDevEnum));
if (SUCCEEDED(hr))
//创建一个枚举器,用来枚举视频设备
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnum, 0);
IMoniker *pMoniker = NULL;
//开始枚举设备
while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
{
IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);//为设备生成 filter
if (SUCCEEDED(hr))
{
hr = pGraph->AddFilter(pCap, L"Capture Filter");//将filter加入到graph
}
if (SUCCEEDED(hr))
{
//PIN_CATEGORY_PREVIEW: specifying a pin category;
//MEDIATYPE_Video: the major media types.
//pCap: pointer to the starting filter for the connection
hr = pBuild->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video, pCap, NULL, NULL);//连接graph
break;
}
else{
pMoniker->Release();
continue; //尝试下一个
}
}
pVideoWindow->put_AutoShow(OATRUE);//graph自动显示视频窗口
//pVideoWindow->put_Visible(OATRUE/*OAFALSE*/);
if (SUCCEEDED(hr))
{
// Run the graph.
hr = pControl->Run();
if (SUCCEEDED(hr)){
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);//一直阻塞在这边;
}
}
pBuild->Release();
pMoniker->Release();
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}
参考资料:
标签:
原文地址:http://blog.csdn.net/li_chihang/article/details/43378429