最简单的基于DirectShow的示例:获取Filter信息
=====================================================
最简单的基于DirectShow的示例文章列表:
最简单的基于DirectShow的示例:视频播放器
最简单的基于DirectShow的示例:视频播放器图形界面版
最简单的基于DirectShow的示例:视频播放器自定义版
最简单的基于DirectShow的示例:获取Filter信息
=====================================================
本文记录一个获取DirectShow的Filter信息的程序。该程序可以遍历当前系统中的DirectShow Filter并且将它们的信息打印到控制台中。通过本程序可以搞清楚DirectShow中Filter,Pin,MediaType等几个关键结构之间的关系,以及它们的信息的获取方法。
流程图
该程序的流程图如下所示。由于该图的尺寸比较大,在页面中显示不下,所以在相册中上传了一份:
接口
该流程图中涉及到以下接口:
ICreateDevEnum *pSysDevEnum:设备列举接口。
IEnumMoniker *pEnumCat:Moniker(别名)枚举接口。
IMoniker *pMoniker:Moniker(别名)接口。
IPropertyBag *pPropBag:存储属性值的接口。
IBaseFilter *pFilter:Filter接口。
IEnumPins * pinEnum:Filter枚举接口。
IPin * pin: Pin接口。
PIN_INFO pinInfo:存储Pin的信息的结构体。
IEnumMediaTypes *mtEnum:MediaType枚举接口。AM_MEDIA_TYPE *mt:描述媒体类型的结构体。
流程图
该流程图中涉及到以下函数:
【初始化】
CoInitialize():初始化COM运行环境。
CoCreateInstance(…,pSysDevEnum):用指定的类标识符创建一个Com对象。在该示例中类标识符为“IID_ICreateDevEnum”,用于创建ICreateDevEnum。
【Filter的枚举】
pSysDevEnum->CreateClassEnumerator(…,pEnumCat):通过ICreateDevEnum查询IEnumMoniker枚举接口,枚举指定类型目录下的设备Moniker(别名)。
pEnumCat->Next(…,pMoniker):通过IEnumMoniker查询下一个IMoniker接口。
pMoniker->BindToStorage(…,pPropBag):通过IMoniker查询IPropertyBag接口(用于获取Filter信息)。
pPropBag->Read("FriendlyName"):通过IPropertyBag获取“FriendlyName”属性的值。pMoniker->BindToObject(…,pFilter):通过IMoniker查询IBaseFilter接口(用于获取Filter,注意和BindToStorage()区别)。
【Pin的枚举】
pFilter->EnumPins(pinEnum):通过IBaseFilter查询IEnumPins枚举接口。
pinEnum->Next(…,pin):通过IEnumPins查询下一个IPin接口。pin->QueryPinInfo(PinInfo):通过IPin获取Pin的信息。
【MediaType的枚举】
pin->EnumMediaTypes(&mtEnum):通过IPin查询IEnumMediaTypes枚举接口。
mtEnum->Next(…, &mt):通过IEnumMediaTypes查询下一个AM_MEDIA_TYPE。GuidToString(mt->majortype):把AM_MEDIA_TYPE的GUID转换成字符串(方便输出)。
【释放】
CoUninitialize():释放CoInitialize()初始化的COM运行环境。
再附上一张代码中涉及到的接口之间的关系:
可以看出从上到下他们之间顺序的排列如下所示:
ICreateDevEnum-->IEnumMoniker-->IMoniker-->IBaseFilter-->IEnumPins-->IPin-->IEnumMediaTypes-->AM_MEDIA_TYPE
源代码
/*** 最简单的Directshow信息显示例子* Simplest DirectShow Info** 雷霄骅 Lei Xiaohua* leixiaohua1020@126.com* 中国传媒大学/数字电视技术* Communication University of China / Digital TV Technology* http://blog.csdn.net/leixiaohua1020** 本程序是一段获取DirectShow滤镜信息的代码。通过本代码可以获得* DirectShow滤镜信息。适合初学者学习DirectShow。* * This code can be used to get Directshow Filter's information.* Suitable for the beginner of DirectShow.*/#include "stdafx.h"
#include <dshow.h>
#include <atlconv.h>#define OUTPUT_PIN 1
#define OUTPUT_MEDIATYPE 1char* GuidToString(const GUID &guid)
{int buf_len=64;char *buf =(char *)malloc(buf_len);_snprintf(buf,buf_len,"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",guid.Data1, guid.Data2, guid.Data3,guid.Data4[0], guid.Data4[1],guid.Data4[2], guid.Data4[3],guid.Data4[4], guid.Data4[5],guid.Data4[6], guid.Data4[7]);//printf("%s\n",buf);return buf;
}int _tmain(int argc, _TCHAR* argv[])
{USES_CONVERSION;// Init COMHRESULT hr=NULL;hr= CoInitialize(NULL);if (FAILED(hr)){printf("Error, Can not init COM.");return -1;}printf("===============Directshow Filters ===============\n");ICreateDevEnum *pSysDevEnum = NULL;hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void **)&pSysDevEnum);if (FAILED(hr)){return hr;}IEnumMoniker *pEnumCat = NULL;//Category /************************************************************************Friendly Name CLSID-------------------------------------------------------------------------Audio Capture Sources CLSID_AudioInputDeviceCategoryAudio Compressors CLSID_AudioCompressorCategoryAudio Renderers CLSID_AudioRendererCategoryDevice Control Filters CLSID_DeviceControlCategoryDirectShow Filters CLSID_LegacyAmFilterCategoryExternal Renderers CLSID_TransmitCategoryMidi Renderers CLSID_MidiRendererCategoryVideo Capture Sources CLSID_VideoInputDeviceCategoryVideo Compressors CLSID_VideoCompressorCategoryWDM Stream Decompression Devices CLSID_DVDHWDecodersCategoryWDM Streaming Capture Devices AM_KSCATEGORY_CAPTUREWDM Streaming Crossbar Devices AM_KSCATEGORY_CROSSBARWDM Streaming Rendering Devices AM_KSCATEGORY_RENDERWDM Streaming Tee/Splitter Devices AM_KSCATEGORY_SPLITTERWDM Streaming TV Audio Devices AM_KSCATEGORY_TVAUDIOWDM Streaming TV Tuner Devices AM_KSCATEGORY_TVTUNERWDM Streaming VBI Codecs AM_KSCATEGORY_VBICODEC ************************************************************************/hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);//hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);//hr = pSysDevEnum->CreateClassEnumerator(CLSID_AudioCompressorCategory, &pEnumCat, 0);//hr = pSysDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumCat, 0);//hr = pSysDevEnum->CreateClassEnumerator(CLSID_MediaMultiplexerCategory, &pEnumCat, 0);//hr = pSysDevEnum->CreateClassEnumerator(CLSID_LegacyAmFilterCategory, &pEnumCat, 0);if (hr != S_OK) {pSysDevEnum->Release();return -1;}IMoniker *pMoniker = NULL;ULONG monikerFetched;//Filterwhile(pEnumCat->Next(1, &pMoniker, &monikerFetched) == S_OK){IPropertyBag *pPropBag;VARIANT varName;IBaseFilter *pFilter;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,(void **)&pPropBag);if (FAILED(hr)){pMoniker->Release();continue;}VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);//"FriendlyName": The name of the device.//"Description": A description of the device.//Filter Info================printf("[%s]\n",W2A(varName.bstrVal));VariantClear(&varName);//========================
#if OUTPUT_PINhr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,(void**)&pFilter);if (!pFilter){continue;}IEnumPins * pinEnum = NULL;IPin * pin = NULL;ULONG pinFetched = 0;if (FAILED(pFilter->EnumPins(&pinEnum))){pinEnum->Release();continue; }pinEnum->Reset();//Pin Infowhile (SUCCEEDED(pinEnum->Next(1, &pin, &pinFetched)) && pinFetched){if (!pin){continue;}PIN_INFO pinInfo;if (FAILED(pin->QueryPinInfo(&pinInfo))){continue;}printf("\t[Pin] ");switch(pinInfo.dir){case PINDIR_INPUT:printf("Dir:Input \t");break;case PINDIR_OUTPUT:printf("Dir:Output \t");break;default:printf("Dir:Unknown\n");break;}printf("Name:%s\n",W2A(pinInfo.achName));//MediaType
#if OUTPUT_MEDIATYPEIEnumMediaTypes *mtEnum=NULL;AM_MEDIA_TYPE *mt=NULL;if( FAILED( pin->EnumMediaTypes( &mtEnum )) )break;mtEnum->Reset();ULONG mtFetched = 0;while (SUCCEEDED(mtEnum->Next(1, &mt, &mtFetched)) && mtFetched){printf("\t\t[MediaType]\n");//Videochar *MEDIATYPE_Video_str=GuidToString(MEDIATYPE_Video);//Audiochar *MEDIATYPE_Audio_str=GuidToString(MEDIATYPE_Audio);//Streamchar *MEDIATYPE_Stream_str=GuidToString(MEDIATYPE_Stream);//Majortypechar *majortype_str=GuidToString(mt->majortype);//Subtypechar *subtype_str=GuidToString(mt->subtype);printf("\t\t Majortype:");if(strcmp(majortype_str,MEDIATYPE_Video_str)==0){printf("Video\n");}else if(strcmp(majortype_str,MEDIATYPE_Audio_str)==0){printf("Audio\n");}else if(strcmp(majortype_str,MEDIATYPE_Stream_str)==0){printf("Stream\n");}else{printf("Other\n");}printf("\t\t Subtype GUID:%s",subtype_str);free(MEDIATYPE_Video_str);free(MEDIATYPE_Audio_str);free(MEDIATYPE_Stream_str);free(subtype_str);free(majortype_str);printf("\n");}
#endifpin->Release();}pinEnum->Release();pFilter->Release();
#endifpPropBag->Release();pMoniker->Release();}pEnumCat->Release();pSysDevEnum->Release();printf("=================================================\n");CoUninitialize();return 0;
}
运行结果
程序运行的结果如下图所示。从图中可以看出,程序打印出了系统中DirectShow的Filter信息。每个Filter的信息中包含了它的Pin的信息。每个Pin中又包含了Pin中的MediaType信息。
可以通过定义在代码最前面宏 控制输出的Filter信息的类型。定义成“0”的话则不会输出该类的信息。如下所示。
#define OUTPUT_PIN 1
#define OUTPUT_MEDIATYPE 1
下载
Simplest DirectShow Example
项目主页
SourceForge:https://sourceforge.net/projects/simplestdirectshowexample/
Github:https://github.com/leixiaohua1020/simplest_directshow_example
开源中国:http://git.oschina.net/leixiaohua1020/simplest_directshow_example
CDSN下载地址:http://download.csdn.net/detail/leixiaohua1020/8348163
本程序包含了DirectShow开发的示例程序。适合DirectShow初学者进行学习。
它包含了以下几个子程序:
simplest_directshow_player: 最简单的基于DirectShow的视频播放器。
simplest_directshow_player_custom: 最简单的基于DirectShow的视频播放器(Custom)。
playerGUI: 最简单的基于DirectShow的播放器-图形界面版。
simplest_directshow_info: 最简单的Directshow信息显示例子。
simplest_directshow_filter: 目前还未完成。
最简单的基于DirectShow的示例:获取Filter信息相关推荐
- 最简单的基于DirectShow的示例:视频播放器自定义版
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
- 最简单的基于DirectShow的示例:视频播放器图形界面版
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
- 最简单的基于DirectShow的示例:视频播放器
===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...
- 最简单的基于 DirectShow 的视频播放器
源程序下载链接:https://download.csdn.net/download/bmjhappy/11250669 50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍 ...
- 转:最简单的基于 DirectShow 的视频播放器
50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...
- 最简单的基于librtmp的示例:发布H.264(H.264通过RTMP发布)
===================================================== 最简单的基于libRTMP的示例系列文章列表: 最简单的基于librtmp的示例:接收(RT ...
- 50行代码实现的一个最简单的基于 DirectShow 的视频播放器
本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectShow 播放视频所有必备的函数. 直接贴上代码,具体代码的含义都写在注释中 ...
- 一个简单的基于 DirectShow 的播放器 2(对话框类)
上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器 1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...
- 一个简单的基于 DirectShow 的播放器 1(封装类)
DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...
最新文章
- Centos7状态下查看防火墙状态及修改服务端口
- 读硕期间给你最大帮助的不是你的导师,而是他们
- 使用Rekit开发可扩展的前端应用
- eax ax ah al
- 在eclipse里配置Android ndk环境 适用于windows mac 和linux[转]
- 问题:二进制数中1的个数。
- boost::core模块default_allocator
- 基于MHA+semi sync实现mysql数据库的高可用
- python做视频特效_python实现超简单的视频对象提取功能
- 【选手分享】你想知道的比赛思路这里都有!速查收!
- Mybatis参数Integer类型值为0 源码处理
- 贪心 Codeforces Round #303 (Div. 2) B. Equidistant String
- 一次惨痛的微软AA面经历
- 从JPG和JPEG图片获取压缩比详细教程
- 计算机怎样设置光盘启动项,怎么设置开机启动项-设置光盘启动教程
- 莫队算法完整总结(普通莫队、带修莫队、树上莫队、回滚莫队)
- 05-Node.js—http模块
- 【修真院小课堂】JWT简单介绍
- 特斯拉 开源_开源与癌症作斗争,特斯拉采用Coreboot,Uber和Lyft发行开源机器学习...
- 【ADNI】对 nii 3D 数据进行裁剪(Matlab)待完善...