Microsoft DirectX 9.0 |
To preview the project, you need a component called a render engine, which builds a DirectShow filter graph from a timeline. The filter graph is what actually renders the project. You can use the render engine to preview a project or to write the final output file.
This article does not go into detail about the render engine. For preview, you only need a few method calls. You can find a more thorough discussion, including how to write output files, in Rendering a Project. The following code example shows how to construct a preview graph.
IRenderEngine *pRender = NULL;
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC_SERVER,
IID_IRenderEngine, (void**) &pRender);
hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );
hr = pRender->RenderOutputPins( );
Create the render engine using the CoCreateInstance function. Then call the following methods on the render engine's IRenderEngine interface:
Once the graph is built, you can preview the project by running the graph, as you would with any DirectShow filter graph. First, obtain a pointer to the filter graph by calling the IRenderEngine::GetFilterGraph method.
IGraphBuilder *pGraph = NULL;
hr = pRender->GetFilterGraph(&pGraph);
Query the filter graph for the IMediaControl and IMediaEvent interfaces. Use these two interfaces to run the graph and wait for playback to complete. For an explanation of how to use these interfaces, see How To Play a File and Responding to Events. The following code shows one way to use these interfaces.
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
long evCode;
pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
hr = pControl->Run();
hr = pEvent->WaitForCompletion(INFINITE, &evCode);
pControl->Stop();
The code in this example blocks program execution until playback completes, because of the INFINITE parameter in the IMediaEvent::WaitForCompletion method call. If something goes wrong during playback, however, it could cause the program to stop responding. In a real application, use a message loop to wait for playback to complete. It's also recommended that you provide the user with a way to interrupt playback.
When you finish using the render engine, always call the IRenderEngine::ScrapIt method. This method deletes the filter graph and releases any resources held by the render engine.
pRender->ScrapIt();