【问题标题】:How can I reverse engineer a DirectShow graph?如何对 DirectShow 图形进行逆向工程?
【发布时间】:2008-08-26 12:02:08
【问题描述】:

我有一个 DirectShow 图表,可以从网络流中渲染 MPEG2/4 电影。当我通过手动连接引脚来组装图形时,它不会呈现。但是当我在 GraphBuilder 上调用 Render 时,它渲染得很好。

显然,我没有对 GraphBuilder 正在执行的图表中的某些过滤器执行一些设置步骤。

有没有办法在 GraphBuilder 组装图时查看调试输出?

有没有办法转储工作图以查看它是如何组合在一起的?

对于解开 DirectShow 盒子中的谜团还有其他想法吗?

谢谢! -Z

【问题讨论】:

    标签: video directx directshow mpeg


    【解决方案1】:

    您可以使用 DirectShow SDK 中的工具 GraphEdit 观看您创建的图表。在 GraphEdit 中,选择 File->Connect to remote Graph...

    为了在列表中找到你的图表,你必须在运行对象表中注册它:

    void AddToRot( IUnknown *pUnkGraph, DWORD *pdwRegister ) 
    {
        IMoniker* pMoniker;
        IRunningObjectTable* pROT;
        GetRunningObjectTable( 0, &pROT );
    
        WCHAR wsz[256];     
        swprintf_s( wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId() );
        CreateItemMoniker( L"!", wsz, &pMoniker );
    
        pROT->Register( 0, pUnkGraph, pMoniker, pdwRegister );
    
        // Clean up any COM stuff here ...
    }
    

    销毁图表后,应通过调用 IRunningObjectTable::Revoke 将其从 ROT 中删除

    【讨论】:

      【解决方案2】:

      Roman Ryltsov 创建了 DirectShow Filter Graph Spy 工具 (http://alax.info/blog/777),它是 FilterGraph 接口上的包装 COM dll,用于记录对 FilterGraph 方法的所有调用。

      它还将所有创建的图形添加到运行对象表 (ROT) 中,然后您可以使用 GraphEdit 或 GraphStudio 等工具对其进行可视化。当您需要查看 Windows Media Player 图表的外观时非常有用。

      【讨论】:

        【解决方案3】:

        IGraphBuilder::SetLogFile(请参阅http://msdn.microsoft.com/en-us/library/dd390091(v=vs.85).aspx)将为您提供有关在图形构建过程中发生的情况的大量有用诊断信息。传入文件句柄(例如由 CreateFile 打开)并将其转换为 DWORD_PTR。在关闭文件句柄之前再次调用 NULL 以完成日志记录。

        以下博客文章中用于转储图表的代码将为您提供一些额外信息来解释日志文件中的数字。

        http://rxwen.blogspot.com/2010/04/directshow-debugging-tips.html

        【讨论】:

        • 太棒了!我学到了一个关于 DirectShow 的非常有用的新信息 :-)
        【解决方案4】:

        【讨论】:

          【解决方案5】:

          你需要:

          1. 将您的过滤器图注册到“运行对象表” - ROT - 使用下面的代码
          2. 使用 GraphEdit(文件->连接到远程图)或更好的方法连接到您的过滤器图 - 使用 GraphEditPlus

          要将您的过滤器图注册为“可连接”图,请使用您的过滤器图调用它:

          void AddToROT( IUnknown *pUnkGraph, DWORD *pdwRegister ) 
          {
              IMoniker * pMoniker;
              IRunningObjectTable *pROT;
              WCHAR wsz[128];
              HRESULT hr;
          
              if (FAILED(GetRunningObjectTable(0, &pROT)))
                  return;
          
              wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
          
              hr = CreateItemMoniker(L"!", wsz, &pMoniker);
              if (SUCCEEDED(hr)) 
              {
                  hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
                  pMoniker->Release();
              }
          
              pROT->Release();
          }
          

          并在发布图表之前调用它:

          void RemoveFromROT(DWORD pdwRegister)
          {
              IRunningObjectTable *pROT;
          
              if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) 
              {
                  pROT->Revoke(pdwRegister);
                  pROT->Release();
              }
          }
          

          `

          【讨论】:

            【解决方案6】:

            旧版本的 DirectX,我相信 9a,但 9b 没有 dshow 的“调试模式”。它将调试信息的日志输出到调试控制台。

            所以下载一个旧版本,将其设置为调试。然后在 Visual Studio 中打开 debugview 或加载 graphedt.exe 以查看调试信息。

            【讨论】:

              【解决方案7】:

              您可以将图形“保存”(序列化)到 .grf graphedit 文件,可能是:https://stackoverflow.com/a/10612735/32453

              graphedit 似乎也可以“远程附加”到正在运行的图表? http://rxwen.blogspot.com/2010/04/directshow-debugging-tips.html

              【讨论】:

                猜你喜欢
                • 2014-02-22
                • 2011-05-09
                • 2016-04-01
                • 1970-01-01
                • 1970-01-01
                • 2018-08-26
                • 2010-09-30
                • 2015-04-23
                相关资源
                最近更新 更多