前面的话 GraphEdit 微软的SDK里面有个DirectShow的辅助工具GraphEdit,这里的文字简单介绍如何将应用程序生成的GraphBuilder插入到GraphEdit中直观的显示。 可能一开始我们对这种应用有点儿不理解,既然是自己写的代码,GraphBuilder里面的链路也是自己建立的,有必要多此一举么? 其实不然,微软在生成GraphBuilder其中的数据链路时,并不是完全按照咱们的代码中指示连接的,连接的真正过程包含了一些自动化的因素。比如我设置一个H.264 Decoder Filter直接连接播放Render Filter,Connet是成功的,从代码里看是Decoder的输出PIN直接连到Render的输入PIN,但是实际情况并不是这样,在GraphEdit里面显示你会发现,Decoder和Render之间被插入一个Color Space Converter的Filter,它负责吧Decoder的输出从YUV420的格式转换成Render能接受的RGB32格式。另一个例子,摄像头的输出可以直接接Render Filter,但是实际系统会在采集设备和Render之间插入解码器MJPEG Decompressor和色彩空间转换模块Color Space Converter。微软的这种自动化手段可以大大的简化我们建立GraphBuilder的过程(我粗略的统计了一下,基本每个工程都能减少40%到70%的代码量),产生的问题是这种自动化是隐性的,不直观可见的,不会体现在代码中。GraphEdit这个小工具就给我们提供了这样一个手段,去一窥其中究竟。 GraphEdit的简单使用 GraphEdit是一个很简单的工具软件,其实基本不用教大家也会用,但是为了文章的完整性,这里简单介绍两个最基本的功能。 GraphEdit上方蓝色方块的按钮<Add Filter to graph>,点击后会出现上面图示的对话框。这个对话框中,你可以查看系统里现有的所有注册Filter;你可以知道Filter对应的文件的位置和名称;你可以知道Filter的FriendlyName用来枚举识别;你可以知道Filter的GUID用来直接创建实例,你可以知道Filter所有PIN的类型数量,并且可以知道每个PIN支持什么样的媒体类型,并知道该媒体类型的GUID或者名称。 在设计一个GraphBuilder之初,浏览这个名为Which filters do you want to insert的对话框,比查询MSDN可要方便快速多了。当然更多的细节还是要到如下地址去查询。MSDN Filters 功能(2)测试 GraphEdit也可以作为一个Filter的测试平台。当我们自己写好一个Filter并对它进行注册后,就可以在Filter列表中找到我们自己的Filter〈一般会出现在DircetShow Filters那个目录树底下〉。我们可以插入自己的Filter然后组建起一个链路,点击绿色箭头运行就可以测试了。这样进行测试不用写Test程序,实现快速容易,可以避免引入额外的错误。当然这一切的前提是您Filter的Propage要好好地写,使用Propage能配置你Filter运行需要的一切参数。 用GraphEdit辅助调试 这就是本文的重点了,首先必须要告诉您一个技巧,在使用GraphEdit加载您应用程序中的GraphBuilder之前,您必须先注册一个名为proppage.dll的文件,这个DLL就在GraphEdit同一个不录下,一般在SDK的Bin目录中。加载方法罗嗦一下,管理员权限的CMD窗口中"regsvr32 ./proppage.dll"回车。加载这个DLL以后GraphEdit的功能会稍稍出现变化,Filter的属性页会增加一两个Tab,你可以在属性页中查询一个Filter当前的输入输出的媒体类型和参数,也可以查询未连接PIN支持的所有媒体类型和参数。 要使用GraphEdit辅助调试应用程序,只需如下两步: Step(1)代码中实现AddGraphToRot( )和RemoveGraphFromRot( ) ------------------------------------------------------------------------------------------------------------------------------------------------------------------- HRESULT AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) if (!pUnkGraph || !pdwRegister) if (FAILED(GetRunningObjectTable(0, &pROT))) hr = StringCchPrintfW(wsz, NUMELMS(wsz), L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, hr = CreateItemMoniker(L"!", wsz, &pMoniker); pROT->Release(); ------------------------------------------------------------------------------------------------------------------------------------------------------------------- void RemoveGraphFromRot(DWORD pdwRegister) if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) ------------------------------------------------------------------------------------------------------------------------------------------------------------------- 这两个函数无需修改,直接贴到代码里面就可以使用。 在主函数调用时,首先声明一个DWORD 的句柄g_dwGraphRegister; 然后在初始化完GraphBuilder后Run之前调用AddGraphToRot( pMyGraph, &dwGraphRegister); 最后在函数推出之前调用RemoveGraphFromRot(DWORD dwGraphRegister); Step(2)在程序运行过程中显示 使用很简单了,点击"Connect to a running graph in another application"这个快捷键〈图标跟GraphEdit图标一样的那个〉就会出现以下对话框,选择一个点OK。
我总结要注意的有以下两点: 一是运行程序的权限要和运行GraphEdit的一致,比如我调试SDK例子用的管理员权限,启动调试后打开GraphEdit必须也用管理员权限,否则啥也别想看见; 二是调试中不要试图用GraphEdit加载一个已经被中断的Application,那样您的GraphEdit就等着杀进程吧。
另外,有时候GraphEdit会不能正常显示,一启动就被最小化。那时候打开任务管理器到应用程序页面,选GraphEdit点右键选最大化就可以了。 |