DirectShow グラフをリバース エンジニアリングするにはどうすればよいですか?
-
09-06-2019 - |
質問
ネットワーク ストリームから MPEG2/4 ムービーをレンダリングする DirectShow グラフがあります。ピンを手動で接続してグラフを組み立てると、レンダリングされません。しかし、GraphBuilder で Render を呼び出すと、正常にレンダリングされます。
明らかに、GraphBuilder が実行しているグラフ内の一部のフィルターに対して実行していないセットアップ ステップがいくつかあります。
GraphBuilder がグラフを組み立てるときに、GraphBuilder からのデバッグ出力を確認する方法はありますか?
動作中のグラフをダンプして、それがどのように組み立てられているかを確認する方法はありますか?
DirectShow ボックスに潜む謎を解明するための他のアイデアはありますか?
ありがとう!-Z
解決
DirectShow SDK のツールである GraphEdit を使用して作成したグラフを確認できます。GraphEdit で、[ファイル] -> [リモート グラフに接続] を選択します。
リスト内でグラフを見つけるには、実行中のオブジェクト テーブルにグラフを登録する必要があります。
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 からグラフを削除する必要があります。
他のヒント
Roman Ryltsov は、DirectShow Filter Graph Spy ツールを作成しました (http://alax.info/blog/777)、FilterGraph インターフェイス上のラッパー COM DLL。FilterGraph メソッドへのすべての呼び出しをログに記録します。
また、作成されたすべてのグラフがランニング オブジェクト テーブル (ROT) に追加され、GraphEdit や GraphStudio などのツールを使用して視覚化できます。Windows Media Player のグラフがどのように表示されるかを確認する必要がある場合に非常に便利です。
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
これに関する詳細な MSDN エントリがあります。http://msdn.microsoft.com/en-us/library/windows/desktop/dd390650(v=vs.85).aspx
必要がある:
- 以下のコードを使用して、フィルタ グラフを「実行オブジェクト テーブル」に登録します - ROT -
- GraphEdit ([ファイル] -> [リモート グラフに接続]) を使用してフィルター グラフに接続するか、さらに良い方法を使用してフィルター グラフに接続します。 グラフ編集プラス
フィルター グラフを「接続可能な」グラフとして登録するには、フィルター グラフでこれを呼び出します。
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();
}
}
`
DirectX の古いバージョンでは、9a には dshow の「デバッグ モード」があったと思いますが、9b にはありませんでした。デバッグ情報のログをデバッグ コンソールに出力します。
したがって、古いバージョンをダウンロードし、デバッグに設定します。次に、Visual Studio で debugview を開くか、graphedt.exe をロードしてデバッグ情報を確認します。
グラフを .grfgraphedit ファイルに「保存」(シリアル化) できます。おそらく次のとおりです。 https://stackoverflow.com/a/10612735/32453
また、graphedit は実行中のグラフに「リモート接続」できるようです。 http://rxwen.blogspot.com/2010/04/directshow-debugging-tips.html