Microsoft DirectX 8.0 |
The Microsoft® DirectX® SDK provides a debugging utility called GraphEdit, which you can use to create and test filter graphs.
This article contains the following sections:
GraphEdit is a visual tool for building filter graphs. Using GraphEdit, you can experiment with a filter graph before you write any application code. You can also load a filter graph that your application creates, to verify that your application is building the correct graph. If you develop a custom filter, GraphEdit provides a quick way to test it: Simply load a graph with your custom filter and try running the graph. If you are new to DirectShow, GraphEdit is a good way to become familiar with filter graphs and the DirectShow architecture.
The following illustration shows how GraphEdit represents a simple filter graph.
Each filter is represented as a rectangle. Smaller squares along the edges of the filters represent pins. Input pins are on the left side of the filter, and output pins are on the right side. The arrows represent the connections between pins.
With GraphEdit, you can:
When you install the DirectX SDK, GraphEdit appears in the Start menu under Microsoft DirectX 8 SDK, in the submenu DX Utilities. The executable file is GraphEdt.exe. By default, it is installed in the folder Mssdk\Bin\DXUtils. You can open GraphEdit from either of these locations.
What follows are brief descriptions of some things you can do using GraphEdit. For more detailed information about these featuresand othersconsult the GraphEdit application help.
GraphEdit can build a filter graph for file playback. This feature is equivalent to calling the IGraphBuilder::RenderFile method in an application. From the File menu, click Render Media File. GraphEdit displays an Open File dialog box. Select a multimedia file and click Open. GraphEdit builds a filter graph to play the file you've selected.
You can also render a media file located at a URL. From the File menu, click Render URL. GraphEdit displays a dialog box in which to type the URL.
GraphEdit can build a custom filter graph, using any of the filters registered on your system. From the Graph menu, click Insert Filters. A dialog box appears with a list of the filters on your system, organized by filter category. GraphEdit builds this list from information in the registry. The following illustration shows the dialog box.
To add a filter to the graph, select the name of the filter and click the Insert Filters button, or double-click the filter name. After you have added the filters, you can connect two filters by dragging the mouse from one filter's output pin to another filter's input pin. If the pins accept the connection, GraphEdit draws an arrow connecting them.
Once you have built a filter graph in Graph Edit, you can run the graph to see whether it works as you expect. The Graph menu contains the menu commands Play, Pause, and Stop. These commands invoke to the IMediaControl methods Run, Pause, and Stop, respectively. The GraphEdit toolbar has buttons for these commands, as well:
Note The GraphEdit Stop command first pauses the graph and seeks to time zero (assuming the graph is seekable). For file playback, this action resets the video window to the first frame. Then GraphEdit calls IMediaControl::Stop.
If the graph is seekable, you can seek it by dragging the slider bar that appears below the toolbar. Dragging the slider bar invokes the IMediaSeeking::SetPositions method.
Some filters support custom property pages, which provide a user interface for setting properties on the filter. To view a filter's property page in GraphEdit, right-click the filter and select Properties from the pop-up window. GraphEdit displays a property page that contains the property sheets defined by the filter (if any). In addition, GraphEdit includes a property sheet for each pin on the filter. The pin property sheets are defined by GraphEdit, not by the filter. If the pin is connected, the pin property sheet displays the media type for the connection. Otherwise, it lists the pin's preferred media types.
GraphEdit can load a filter graph created by an external process. With this feature, you can see exactly what filter graph your application builds, with only a minimal amount of additional code in your application.
The application must register the filter graph instance in the Running Object Table (ROT). The ROT is a globally accessible look-up table that keeps track of running objects. Objects are registered in the ROT by moniker. To connect to the graph, GraphEdit searches the ROT for monikers whose display name matches a particular format:
!FilterGraph X pid Y
X and Y are hexadecimal numbers, representing the address of the filter graph and the process id, respectively.
When your application first creates the filter graph, call the following function:
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 %08p pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker); if (SUCCEEDED(hr)) { hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister); pMoniker->Release(); } pROT->Release(); return hr; }
This function creates a moniker and a new ROT entry for the filter graph. The first parameter is a pointer to the filter graph. The second parameter receives a value that identifies the new ROT entry. Before the application releases the filter graph, call the following function to remove the ROT entry. The pdwRegister parameter is the identifier returned by the AddToRot function.
void RemoveFromRot(DWORD pdwRegister) { IRunningObjectTable *pROT; if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) { pROT->Revoke(pdwRegister); pROT->Release(); } }
The following code example shows how to call these functions. In this example, the code that adds and removes ROT entries is conditionally compiled, so that it is included only in debug builds.
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();
To view the filter graph in GraphEdit, run your application and GraphEdit at the same time. In the GraphEdit File menu, click Connect. In the Connect To Graph dialog box, select the process id (pid) of your application and click OK. GraphEdit loads the filter graph and displays it. Don't use any other GraphEdit features on this graphit might cause unexpected results. For example, don't add or remove filters, or stop and start the graph. Close GraphEdit before exiting your application.
Note Your application might hit various asserts when it exits.
The following illustration shows the Connect To Graph dialog box.