分享
 
 
 

在GraphEdit中模拟构建Graph

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

在GraphEdit中模拟构建Graph

智慧的鱼(aoosang)

摘要:本篇文档主要讲述如何使用GraphEdit来模拟构建graph图,测试你的filter。

1 GraphEdit概述

GraphEdit是一个很有用的工具,可以用来构建graph图。通过GraphEdit,你可以在开发代码之前进行一下体验,你也可以装载一个你的应用程序创建的Graph文件。如果你想开发一个自己的filter,GraphEdit 给你提供了一个快速测试的方法:将你的filter添加到graph中,然后运行graph。如果你是一个Directshow的初学者,那么通过GraphEdit你可以熟悉Filter和Dshow的特性。

下面图表演示了GraphEdit如何构建了一个简单的graph。

图1

每一个矩形代表一个Filter,每一个filter的边上的小矩形代表了pin,输入pin在filter的左边,输出pin在Filter的右边,箭头代表两个pin的连接方向。

通过GraphEdit,你可以做到下面的事情:

1 可视化的创建一个Graph,可以动态的拖拉来调整filter。

2 可以模拟如何构建一个graph。

3 运行,停止,暂停,see一个graph。

4可以看看你的机器上都注册了那些filter,以及这些filter的信息

5 查看filter的属性页

6 查看pin连接时采用的媒体类型。

2使用GraphEdit

如果你安装了DirectX的SDK,GraphEdit就会出现在你的开始菜单中找到GraphEdit,启动它。如下图

图2

构建一个文件回放的Graph

GraphEdit可以自动的构建一个文件回放Graph。这个特性其实类似于在应用程序中调用

IGraphBuilder::RenderFile方法。从文件菜单中,选择Render Media File,然后出现一个文件选择对话框,选择一个多媒体文件后单击打开,GraphEdit会自动地建立一个Filter Graph来播放你选择的文件。

你也可以播放一个网络上媒体文件,从文件菜单中,选择Render URL,也会出现一个选择URL的对话框。其他同上。

构建一个普通的Graph图

使用你机器上注册的filter,GraphEdit可以构建一个普通的Filter graph,从Graph菜单中,选择Insert Filters,会出现一个对话框,如下图:

图3

在这个对话框中列出了所有在你机器上注册的Filter的信息。选择filter的名字,然后单击Insert Filters按钮,或者双击filter的名字,filter就会自动添加到graph中,添加完filter以后,你就拖动鼠标,将一个Filter的输出pin和另一个Fiter的输入pin连接起来。如果pin接受这个连接,GraphEdite就会用一个带箭头的

下面的图是一个捕捉桌面的graph图

图4

Run the Graph

当你在GraphEdit中构建好一个Filter graph的时候,你可以让你的graph运行一下看是否和你期望的一样。Graph菜单中包含了Play,Pause,和Stop命令,这些命令会触发IMediaControl

接口的Run, Pause, and Stop,GraphEdit的工具栏也有代表这三个命令的按钮,见下图,单击第一个按钮就开始运行你的Graph图了

图 5

注:GraphEdit的Stop命令首先会暂停Graph,然后Seek到时间的零点(我们坚定graph是可Seek的)。对于文件的回放,这个命令会将视频窗口的图像设置为第一桢,然后GraphEdit才调用IMediaControl::Stop.

查看属性View Property Pages

一些Filter提供了属性页可以让用户设置Filter的属性。鼠标右键单击filter,在弹出的菜单上选择Properties,就会弹出Filter的属性页设置对话框,用户可以从这里设置属性。

图6

图7

3 Loading a Graph From an External Process

GraphEdit可以加载其他进程创建的filter Graph,利用这个特性,只使用少量的代码,你可以清楚地看到你的应用程序创建的所有的filter Graph。

这个特性只有win2000,XP才支持。

应用程序首先必须在Running Object Table (ROT).中注册一个filter graph的实例。ROT是一个全局的对象表,用来查看所有正在运行的对象。对象都是通过moniker注册到rot上。Graph Edit通过搜索ROT中和指定名字moniker就ok。

!FilterGraph X pid Y

这里,x是Filter Graph Manager的地址,y是进程ID,也是16进制。

当你的应用程序创建filter graph的时候,调用下面的代码:

HRESULT AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)

{

IMoniker * pMoniker;

IRunningObjectTable *pROT;

if (FAILED(GetRunningObjectTable(0, &pROT))) {

return E_FAIL;

}

WCHAR wsz[256];

wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());

HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);

if (SUCCEEDED(hr)) {

hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,

pMoniker, pdwRegister);

pMoniker->Release();

}

pROT->Release();

return hr;

}

这个函数创建了一个moniker作为filter graph在ROT中的入口,第一个参数是指向filter Graph的指针,第二个参数返回filter graph在ROT中的入口。当应用程序销毁filter graph的时候,一定要调用下面的函数来删除这个ROT入口

void RemoveFromRot(DWORD pdwRegister)

{

IRunningObjectTable *pROT;

if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {

pROT->Revoke(pdwRegister);

pROT->Release();

}

}

下面的代码演示了如何调用上面的两个函数,

IGraphBuilder *pGraph;

DWORD dwRegister;

// Create the filter graph manager.

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,

IID_IGraphBuilder, (void **)&pGraph);

#ifdef _DEBUG

hr = AddToRot(pGraph, &dwRegister);

#endif

// Rest of the application (not shown).

#ifdef _DEBUG

RemoveFromRot(dwRegister);

#endif

pGraph->Release();

同时运行你的应用程序和GraphEdit,你就可以在GraphEdit中查看你应用程序中的filter graph了。在GraphEdit中,如下

图8

然后就出现了下面的对话框

图9

4 Saving a Filter Graph to a GraphEdit File

下面的代码演示了如何保存一个GraphEdit(.gif)文件,这个可以用来调试你的应用程序。

HRESULT SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath)

{

const WCHAR wszStreamName[] = L"ActiveMovieGraph";

HRESULT hr;

IStorage *pStorage = NULL;

hr = StgCreateDocfile(

wszPath,

STGM_CREATE | STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,

0, &pStorage);

if(FAILED(hr))

{

return hr;

}

IStream *pStream;

hr = pStorage->CreateStream(

wszStreamName,

STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE,

0, 0, &pStream);

if (FAILED(hr))

{

pStorage->Release();

return hr;

}

IPersistStream *pPersist = NULL;

pGraph->QueryInterface(IID_IPersistStream, (void**)&pPersist);

hr = pPersist->Save(pStream, TRUE);

pStream->Release();

pPersist->Release();

if (SUCCEEDED(hr))

{

hr = pStorage->Commit(STGC_DEFAULT);

}

pStorage->Release();

return hr;

}

例如,下面的代码创建了文件回放的graph并保存为MyGraph.grf:

void __cdecl main(void)

{

HRESULT hr;

IGraphBuilder *pGraph;

CoInitialize(NULL);

// Create the Filter Graph Manager and render a file.

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,

IID_IGraphBuilder, reinterpret_cast<void**>(&pGraph));

hr = pGraph->RenderFile(L"C:\\Video.avi", NULL);

if (SUCCEEDED(hr))

{

hr = SaveGraphFile(pGraph, L"C:\\MyGraph.grf");

}

pGraph->Release();

CoUninitialize();

}

5 Loading a GraphEdit File Programmatically

在应用程序中可以通过IPersistStream接口来加载一个GraphEdit (.grf) file,实例代码如下

HRESULT LoadGraphFile(IGraphBuilder *pGraph, const WCHAR* wszName)

{

IStorage *pStorage = 0;

if (S_OK != StgIsStorageFile(wszName))

{

return E_FAIL;

}

HRESULT hr = StgOpenStorage(wszName, 0,

STGM_TRANSACTED | STGM_READ | STGM_SHARE_DENY_WRITE,

0, 0, &pStorage);

if (FAILED(hr))

{

return hr;

}

IPersistStream *pPersistStream = 0;

hr = pGraph->QueryInterface(IID_IPersistStream,

reinterpret_cast<void**>(&pPersistStream));

if (SUCCEEDED(hr))

{

IStream *pStream = 0;

hr = pStorage->OpenStream(L"ActiveMovieGraph", 0,

STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);

if(SUCCEEDED(hr))

{

hr = pPersistStream->Load(pStream);

pStream->Release();

}

pPersistStream->Release();

}

pStorage->Release();

return hr;

}

必须要注意的是,GraphEdit文件只是用来测试或者调试用的,并不是为了让终端客户用的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有