2. Starting the DirectShow Trip This chapter is mainly some of the basic concepts you need to write DirectShow applications, you can use it as a advanced introduction, understanding these contents require general programming and related multimedia knowledge. 2.1. Setting the DirectShow Development Compilation Environment This section describes how to compile DirectShow applications. You can use the command line to compile a project or implement it in the Microsoft Visual Studio integration environment (including VC ). Header file: All DirectShow applications require DSHOW.H of this header file, some DirectShow interfaces require additional header files, referred to the instructions for details. Library file: DirectShow Use the Library file: strMiids.lib Output Class ID (CLSID) and Interface Identification (IID), all DirectShow applications require this library. Quartz.lib outputs an AMGETERRORTEXT function, if this function is not called, this library is not required. With these header files and library files, you can write DirectShow applications, but Microsoft recommends using the DirectShow base library to write Filter, which greatly reduces the workload written by the program. To use the DirectShow base class, you need to compile it first. The base class is located under the SDK's Samples / MultiMedia / DirectShow / BaseClasses folder, contains two versions of libraries: Release (Retail version) Strmbase.LIB and debugging version (Debug Strmbasd.lib. See "Creating the DirectShow Filter" section in detail. 2.2. DirectShow App Programming Introduction This section introduces some of the basic terms and concepts used by DirectShow. After reading this section, you will be able to write your first DirectShood application. Filter and Filter Graph A DirectShow application is combined by a software component called Filter. Filter performs some multimedia flows, such as: reading files, gets video from video acquisition devices, streaming different formats Decodes such as MPEG1, send the data to the graphics card or sound card. Filter receives input and generates output. For example, a Filter that decodes the MPEG1 video stream, enter a video stream in the MPEG1 format, output a series of uncompressed video frames. In DirectShow, the application must be enabled together to link these Filter, so the output of a FILTER has become another filter input. This series of strings are called Filter Graph. For example, the following figure shows a Filter Graph: file source (askYNC) Filter playing AVI files from the hard disk; AVI Splitter Filter analyzes files and breaks down into two streams: a compressed video stream and one Avi Decompressor Filter decodes the video frame, Video Renderer Filter displays the decoded video frame to DirectDraw or GDI; Default DirectSound Device Filter uses DirectSound to play audio streams. The application is not necessary to manage these data streams, but control these Filter through a Up-layer component called Filter Graph Manager.
The application calls the upper layer API such as "run" (via GRAPH mobile data) or "stop". If you need more operations for data streaming, you can enter the filter directly through the COM interface. Filter Graph Manager also outputs an event notification to the application. Another use of Filter Graph is to create a Filter Graph together. Write a DirectShow application generally requires three steps: 1. Create an instance of a Filter Graph Manager 2. Create a Filter Graph using Filter Graph Manager. At this time, you need to have all necessary filters. 3. Use the Filter Graph Manager to control Filter Graph and through these Filter's streams, during which applications receive events sent by Filter Graph Manager. After these, the application needs to post this filter graph manager and all filters. 2.3. This chapter playing a file ends with this festive example, this example is a simple console program that plays audio or video files. The program only has a few rows, but it shows the powerful power of DirectShow programming. As three steps to create a DirectShow application, first step, first, first, you need to call Coinitialize to initialize, then call CocreateInstance: HRESULT HR = Coinitialize (NULL); if (Failed " ))) {Returnifer * pgraph; hResult hr = cocreateInstance (CLSID_FILTERGRAPH, NULL, CLSCTX_INPROC_SERVER, IID_IGRAPHBUILDER, (Void **) & pgraph);
As shown above, the class identifier (CLSID) is CLSID_FILTERGRAPH. Filter Graph Manager is provided by the process DLL (In-Process DLL), so the parameter 3, the value of dwclsContext is CLSCTX_INPROC_SERVER. Since DirectShow runs free-threading mode, you can also use the Coinit_MultithReaded parameter to call CoinitializeEx. The second step is to create a Filter Graph, calling the CocreateInstance The IGRAPHBuilder interface contains most of the way to create a Filter Graph. In this example, two additional interfaces are required: iMediaControl and IMEDIaEvent. IMEDIACONTROL Controls the data stream, which contains methods that open and stop graph; iMediaEvent contains methods from Filter Graph Manager to get events in this example, which is used to get playback end events. All of these interfaces are provided by Filter Graph Manager, and the obtained IGRAPHBUILER interface pointer is queried.
IMediaControl * pControl; IMediaEvent * pEvent; hr = pGraph-> QueryInterface (IID_IMediaControl, (void **) & pControl); hr = pGraph-> QueryInterface (IID_IMediaEvent, (void **) & pEvent); now you can create a filter graph, For file playback only requires a simple call:
HR = pgraph-> renderfile (l "c: //example.avi", null);
The IGRAPHBUILDER :: Render method creates a Filter Graph that plays the specified file. In fact, some of the required Filter instances, if you have a Filter instance, and the work connecting these Filter, if it is a video file, This filter graph looks like this: [File Source] -> [If it is a contract form, this is a decoder] -> [Video render] To start playback, call iMediaControl :: RUN method:
HR = pControl-> Run ();
When Filter Graph runs, the data is finally played back to video or audio through each filter. Playback occurs in a separate thread. You can wait for the end of the playback by calling the iMediaEvent :: waitforcompletion method:
Long Evcode = 0; Pevent-> WaitForcompletion (Infinite, & Evcode);
This method is blocked during playback until playback is over or timeout. When the application ends, you need to release the interface pointer and turn off the COM library:
PCONTROL-> Release (); pevent-> release (); pgraph-> release (); coundialize ();
Here is the full code of this example:
#include
Void main (void)
{
Igraphbuilder * pgraph = null;
IMediaControl * pControl = null;
IMediaEvent * pevent = NULL;