ibasefilter 转

本文介绍了DirectShow中IBaseFilter接口的作用及使用方法。通过示例展示了如何创建一个SampleGrabber Filter并获取其IBaseFilter接口,进而通过该接口访问ISampleGrabber接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.sina.com.cn/s/blog_60d57680010183x5.html


IBaseFilter是一个Filter的接口,为了实现在FilterGraph中的统一,所有的Filter都有一个IBaseFilter接口,并将其暴露在外。在创建一个Filter时总是可以首先获得该接口,然后通过该接口访问其他接口。

       例如,以下创建一个CLSID_SampleGrabber Filter,首先获得其 IID_IBaseFilter接口指针pGrabFilter,然后通过IBaseFilter的接口方法QueryInterface访问接口IID_ISampleGrabber,获得其指针pSampleGrabber。

HRESULT hr;

     CComPtr<IBaseFilter> pGrabFilter = NULL;

     CComPtr<ISampleGrabber> pSampleGrabber = NULL;

     CComPtr <IPin> pTmpPin = NULL;

         JIF(CoCreateInstance(CLSID_SampleGrabber,

             NULL,

             CLSCTX_INPROC_SERVER,

             IID_IBaseFilter,

             (LPVOID *) &pGrabFilter));

     hr = pGrabFilter->QueryInterface(IID_ISampleGrabber,

                         (void * *) &pSampleGrabber);

     if (FAILED(hr))

     {         return hr;    }


//指定视频采集设备的友好名字,为它创建一个Filter IBaseFilter * CTestPreviewDlg::CreateVideoDevice(const char * inFriendlyName) { return CreateHardwareFilter(CLSID_VideoInputDeviceCategory,inFriendlyName); } //根据设备的友好名字,创建一个代表该设备的Filter IBaseFilter * CTestPreviewDlg::CreateHardwareFilter(GUID inCategory,const char * inFriendlyName) { //创建一个系统枚举组件对象 ICreateDevEnum * enumHardware = NULL; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL, IID_ICreateDevEnum,(void**)&enumHardware); if(FAILED(hr)) { return NULL; } IBaseFilter * hardwareFilter = NULL; IEnumMoniker * enumMoniker = NULL; //为指定的目录创建枚举器 hr = enumHardware->CreateClassEnumerator(inCategory,&enumMoniker,0); if(enumMoniker) { enumMoniker->Reset(); ULONG fetched = 0; IMoniker * moniker = NULL; char friendlyName[256]; //枚举得到该目录下所有的设备,逐个进行名字匹配 while(!hardwareFilter && SUCCEEDED(enumMoniker->Next(1,&moniker, &fetched)) && fetched) { if(moniker) { IPropertyBag * propertyBag = NULL; VARIANT name; friendlyName[0] = 0; hr = moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&propertyBag); //读取设备的友好名字 if(SUCCEEDED(hr)) { name.vt = VT_BSTR; hr = propertyBag->Read(L"Friendlyname",&name,NULL); } if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP,0,name.bstrVal,-1, friendlyName,256,NULL,NULL); //如果当前设备的友好名字与用户指定的设备名字相同, //则将当前设备标识绑定为Filter形式 if(strcmp(friendlyName,inFriendlyName) == 0) { moniker->BindToObject(0,0,IID_IBaseFilter, (void**)&hardwareFilter); } } //释放使用过的接口 if(propertyBag) { propertyBag->Release(); propertyBag = NULL; } moniker->Release(); } } enumMoniker->Release(); } enumHardware->Release(); return hardwareFilter; }
以下是使用DirectShow的Device Enumerator接口枚举出系统中可用的视频采集设备,并选择其中一个进行采集的示例代码: ```c++ #include <dshow.h> // 定义全局变量 IGraphBuilder* pGraphBuilder = NULL; ICaptureGraphBuilder2* pCaptureGraphBuilder = NULL; IBaseFilter* pVideoCaptureFilter = NULL; IBaseFilter* pNullRendererFilter = NULL; IMediaControl* pMediaControl = NULL; IMediaEvent* pMediaEvent = NULL; // 枚举可用的视频采集设备 void EnumerateVideoCaptureDevices() { HRESULT hr = S_OK; ICreateDevEnum* pCreateDevEnum = NULL; IEnumMoniker* pEnumMoniker = NULL; IMoniker* pMoniker = NULL; ULONG numFetched = 0; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (FAILED(hr)) { // 错误处理 } hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); if (hr == S_FALSE) { // 没有找到视频采集设备 } else if (FAILED(hr)) { // 错误处理 } else { while (pEnumMoniker->Next(1, &pMoniker, &numFetched) == S_OK) { VARIANT varName; VariantInit(&varName); hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&varName)); if (SUCCEEDED(hr)) { // 输出设备名称 wprintf(L"%s\n", varName.bstrVal); VariantClear(&varName); } pMoniker->Release(); } pEnumMoniker->Release(); } pCreateDevEnum->Release(); } // 选择一个视频采集设备进行采集 void SelectVideoCaptureDevice() { HRESULT hr = S_OK; ICreateDevEnum* pCreateDevEnum = NULL; IEnumMoniker* pEnumMoniker = NULL; IMoniker* pMoniker = NULL; ULONG numFetched = 0; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); if (FAILED(hr)) { // 错误处理 } hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMoniker, 0); if (hr == S_FALSE) { // 没有找到视频采集设备 } else if (FAILED(hr)) { // 错误处理 } else { while (pEnumMoniker->Next(1, &pMoniker, &numFetched) == S_OK) { VARIANT varName; VariantInit(&varName); hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&varName)); if (SUCCEEDED(hr)) { // 选择第一个设备进行采集 hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pVideoCaptureFilter); if (SUCCEEDED(hr)) { break; } } VariantClear(&varName); pMoniker->Release(); } pEnumMoniker->Release(); } pCreateDevEnum->Release(); } // 初始化DirectShow void InitDirectShow() { HRESULT hr = S_OK; hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraphBuilder); if (FAILED(hr)) { // 错误处理 } hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pCaptureGraphBuilder); if (FAILED(hr)) { // 错误处理 } hr = pCaptureGraphBuilder->SetFiltergraph(pGraphBuilder); if (FAILED(hr)) { // 错误处理 } hr = pGraphBuilder->AddFilter(pVideoCaptureFilter, L"Video Capture Filter"); if (FAILED(hr)) { // 错误处理 } hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNullRendererFilter); if (FAILED(hr)) { // 错误处理 } hr = pGraphBuilder->AddFilter(pNullRendererFilter, L"Null Renderer Filter"); if (FAILED(hr)) { // 错误处理 } hr = pCaptureGraphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVideoCaptureFilter, NULL, pNullRendererFilter); if (FAILED(hr)) { // 错误处理 } hr = pGraphBuilder->QueryInterface(IID_IMediaControl, (void**)&pMediaControl); if (FAILED(hr)) { // 错误处理 } hr = pGraphBuilder->QueryInterface(IID_IMediaEvent, (void**)&pMediaEvent); if (FAILED(hr)) { // 错误处理 } } // 开始采集视频 void StartVideoCapture() { HRESULT hr = S_OK; hr = pMediaControl->Run(); if (FAILED(hr)) { // 错误处理 } long evCode = 0; pMediaEvent->WaitForCompletion(INFINITE, &evCode); } // 释放资源 void ReleaseResources() { if (pMediaControl != NULL) { pMediaControl->Release(); pMediaControl = NULL; } if (pMediaEvent != NULL) { pMediaEvent->Release(); pMediaEvent = NULL; } if (pNullRendererFilter != NULL) { pNullRendererFilter->Release(); pNullRendererFilter = NULL; } if (pCaptureGraphBuilder != NULL) { pCaptureGraphBuilder->Release(); pCaptureGraphBuilder = NULL; } if (pGraphBuilder != NULL) { pGraphBuilder->Release(); pGraphBuilder = NULL; } if (pVideoCaptureFilter != NULL) { pVideoCaptureFilter->Release(); pVideoCaptureFilter = NULL; } } int main() { // 枚举可用的视频采集设备 EnumerateVideoCaptureDevices(); // 选择一个视频采集设备进行采集 SelectVideoCaptureDevice(); // 初始化DirectShow InitDirectShow(); // 开始采集视频 StartVideoCapture(); // 释放资源 ReleaseResources(); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值