标签:
出于兴趣一直以来都断断续续看过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