在GraphEdit中模拟构建Graph

原创 2005年05月26日 10:14:00

GraphEdit中模拟构建Graph

智慧的鱼(aoosang

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

 

 

1 GraphEdit概述

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

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

           1

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

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

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

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

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

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

  5 查看filter的属性页

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

 2使用GraphEdit

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

           2

构建一个文件回放的Graph

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

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

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

构建一个普通的Graph

  使用你机器上注册的filterGraphEdit可以构建一个普通的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菜单中包含了PlayPause,和Stop命令,这些命令会触发IMediaControl

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

5

注:GraphEditStop命令首先会暂停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

这个特性只有win2000XP才支持。

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

!FilterGraph X pid Y

这里,xFilter 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 graphROT中的入口,第一个参数是指向filter Graph的指针,第二个参数返回filter graphROT中的入口。当应用程序销毁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文件只是用来测试或者调试用的,并不是为了让终端客户用的。

 

DirectShow中的工具GraphEdit使用小结

一. 安装完Windows SDK 7.0或7.1后,在C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin下有32位的graphedt.exe,及x64目...

GraphEdit使用

GraphEdit 是一个用于建立和测试Filter graph 的可视化工具。在DirectX SDK.中附带一个可执行程序版本(在SDK目录中的Bin/DXUtils/graphedt.exe...

使用GraphEdit调试你的Filter

Posted by 令狐葱 on 2006年03月12日 今天看到在VC6.0里面可以直接使用 GraphEdit调试你自己编写的 Filter,但是反复试了多次就是摸不着门路。后来在网上找...
  • xyh922
  • xyh922
  • 2013年09月07日 20:33
  • 900

JZOJ4769 【GDOI2017模拟9.9】graph CDQ分治+用按秩合并维护带撤销的并查集(BZOJ 4025)

题目大意现在有NN个点,MM个操作,对于每个操作有两种情况 1. Ord=1Ord = 1:读入u,vu,v表示连接u,vu,v。 2. Ord=0Ord = 0:读入uu表示删除第uu次连接的边...

【NOIP2017模拟赛】二分图+状态压缩DP Graph(好题)

这道题其实是一个NPNP完全问题(2333323333),但是由于数据小啊,我们可以搞一搞。很容易发现,如果我们将一个点拆成两个点,一个代表出点,一个代表入点。当增加了一条有向边,就出点向入点连一条边...

NOIPの模拟_2016_7_20_t2_Graph Coloring

Description现在你有一张无向图包含n个节点m条边。最初,每一条边都是蓝色或者红色。每一次你可以将一个节点连接的所有边变色(从红变蓝,蓝变红)。 找到一种步数最小的方案,使得所有边的颜色相同...

HDU 3726 Graph and Queries splay 离线 模拟

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3726 题意:给一个无向图,图中有n(1...
  • dpppBR
  • dpppBR
  • 2017年01月29日 19:04
  • 217

HDU 4365 Palindrome graph 模拟题

题意:求用k种颜料将n*n大的方格涂满的方法有多少种,这里已经有m个格子上过色了 涂满后的方格要满足:中心对称,翻转对称,旋转对称   思路: 1、从对称可以得到 方格可以分为对称的8瓣 所以我们用2...

GraphEdit使用

http://blog.csdn.net/max2008/article/details/1676778 GraphEdit 是一个用于建立和测试Filter graph 的可视化工具。在Dir...
  • JUNGOU1
  • JUNGOU1
  • 2012年04月12日 09:25
  • 204

GraphEdit,无法加载此文件的源筛选器, ERROR: 0x80040241的解决方法

相信搞directshow开发的CSDN们也会经常遇到这样的问题: 当你将一个文件直接拖到graphedit建图播放的时候,会返回无法加载此文件的源筛选器, ERROR: 0x80040241的错误...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在GraphEdit中模拟构建Graph
举报原因:
原因补充:

(最多只允许输入30个字)